Chrome浏览器下点击表单outline轮廓处理方法
我们之前对 HTML5 的<details>,<summary>的小三角样式进行了自定义,但是还有一个不容忽视的体验问题,就是在 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 键索引时候,可以看到下图所示的轮廓效果:
轮廓区域比原生的<summary>要小,但这无伤大雅,而且实际项目开发的时候,我们会去掉小箭头,此时只要设置<a>标签 display:block,则轮廓就可以和<summary>保持一致了。
接下来,我们按下 Space 空格键,就会发现<details>元素内的内容信息不断的展开与收起:
然后上面实现并不完美,相比原生的<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 效果就有了。
码云笔记 » Chrome浏览器下点击表单outline轮廓处理方法