Chrome浏览器下点击表单outline轮廓处理方法

我们之前对 HTML5 的<details>,<summary>的小三角样式进行了自定义,但是还有一个不容忽视的体验问题,就是在 Chrome 浏览器下点击时候会出现 outline 轮廓,如下图所示:

Chrome 浏览器下点击表单 outline 轮廓处理方法

在实际项目开发的时候,产品和设计一定会让你把这个效果去掉的。以及,当我们<summary>元素点击较快的时候,文本会被选中,也不是我们想看到的。

阻止文本选中解决办法:

summary{
  -webkit-user-select:none;
  -moz-user-select:none;
  -ms-user-select:none;
  user-select:none;
}

对于 outline 轮廓,常用的处理方法:

summary{
  outline:0;
}

这样处理对无障碍访问而是非常不友好的,那有没有什么办法兼顾视觉体验和无障碍访问体验呢?答案当然是有的,具体由 2 种做法来实现:

一、利用<a>标签的 outline 交互体验

浏览器对<a>标签元素的 outline 轮廓进行了专门的体验优化处理,鼠标点击的时候不显示轮廓,键盘访问时候显示轮廓。于是我们可采用李代桃僵策略,让<summary>元素的 outline 交给<a>元素,方法就是在<summary>中再内嵌一个<a>,同时通过 tabindex 属性 remove 掉<summary>原本的可访问性。HTML 代码示意如下:

<details open>
    <summary tabindex="-1"><a href="javascript:">这是示例</a></summary>
    <content>点击无外框,键盘 focus 有。</content>
</details>

CSS 如下:

summary{
  user-select:none;
  outline:0;
}

summary a{
  color:inherit;
}

此时,在 Chrome 浏览器下,我们点击摘要信息,没有任何 outline 轮廓出现;但是当我们使用 Tab 键索引时候,可以看到下图所示的轮廓效果:

Chrome 浏览器下点击表单 outline 轮廓处理方法

轮廓区域比原生的<summary>要小,但这无伤大雅,而且实际项目开发的时候,我们会去掉小箭头,此时只要设置<a>标签 display:block,则轮廓就可以和<summary>保持一致了。

接下来,我们按下 Space 空格键,就会发现<details>元素内的内容信息不断的展开与收起:

Chrome 浏览器下点击表单 outline 轮廓处理方法

然后上面实现并不完美,相比原生的<summary>元素,Enter 回车键展开收起效果丢失了。这是因为 HTML 元素中如果多个 focusable 同时带 click 浏览器行为元素嵌套的时候,点击里面的元素,外部元素的浏览器行为是不会触发的。类似的有<label>内嵌<a>标签。

对于<a>标签,其浏览器行为只能通过回车键触发,空格键是无效的;但是对于<summary>,回车键和空格键都能触发展开收起行为,这就是为什么上面代码空格键有效,回车键无效的原因。

如果想要同时支持回车键展开与收起,可以对 HTML 如下处理:

<details open>
    <summary tabindex="-1"><a href="javascript:" onClick="this.parentNode.click();">这是示例</a></summary>
    <content>点击无外框,键盘 focus 有。</content>
</details>

需要注意的是上面处理在<summary>自己额外绑定 click 事件时候可能会有 double 触发的问题,此时,阻止<a>元素的冒泡即可。

二、JS 捕获键盘行为手动设置 outline

这个方法不需要对 HTML 进行任何的改动,是通过 CSS 和 JS 配合对全局的<summary>元素进行 outline 优化。

CSS 如下:

summary {
    user-select: none;
    outline: 0;
}
summary[focus] {
    outline: 1px dotted;
    outline: 5px auto -webkit-focus-ring-color;
}

JS 如下:

window.addEventListener('keydown', function () {    
    window.isKeyEvent = true;
    setTimeout(function () {
        window.isKeyEvent = false;
    }, 100);    
});

document.addEventListener('focusin', function (event) {
    var target = event.target;
    if (target && target.tagName.toLowerCase() == 'summary' && window.isKeyEvent == true) {
        target.setAttribute('focus', '');
    }
});
document.addEventListener('focusout', function (event) {
    var eleFocusAll = document.querySelectorAll('summary[focus]');
    [].slice.call(eleFocusAll).forEach(function (summary) {
        summary.removeAttribute('focus');
    });
});

只要把上面的 CSS 和 JS 复制到页面中,视觉体验和交互体验完美支持的<summary>元素 outline 效果就有了。

表现为,点击<summary>没有任何 outline,键盘 focus 时候出现,且和浏览器原生 outline 效果一模一样,Space 键和 Enter 键展开与收起访问完全保留。

原理:

关键是全局监听 keydown 事件,如果有发生,则认为此 100 毫秒内的页面 focus 行为均是键盘产生,从而有效区分是点击触发的 focus 行为还是键盘触发的 focus 行为,如果是键盘触发,给<summary>元素手动增加 outline 效果。

结束语:

以上就是对 Chrome 浏览器下点击表单 outline 轮廓的处理方法,通过上述应用到 HTML5<details>标签上,视觉体验和交互体验完美支持的<summary>元素 outline 效果就有了。

「点点赞赏,手留余香」

2

给作者打赏,鼓励TA抓紧创作!

微信微信 支付宝支付宝

还没有人赞赏,快来当第一个赞赏的人吧!

声明:本站所有文章,如无特殊说明或标注,均为本站原创发布。任何个人或组织,在未征得本站同意时,禁止复制、盗用、采集、发布本站内容到任何网站、书籍等各类媒体平台。如若本站内容侵犯了原著者的合法权益,可联系我们进行处理。
码云笔记 » Chrome浏览器下点击表单outline轮廓处理方法

发表回复