当前位置: 首页 > Web前端 > HTML

浅谈 -focus 伪类选择器和聚焦后 outline 边框的设置问题

时间:2023-03-28 17:47:24 HTML

讨论:focus伪类选择器和聚焦后外框边框的设置}这种样式设置,当元素被聚焦时,会显示外边框,让用户知道当前浏览器的焦点位置,但是样式外边框往往冗余且丑陋,所以开发者往往会选择去掉外边框,即设置:focus{outline:0;}。但是,不建议去掉焦点外边框,因为这会导致用户在使用键盘上的Tab键定位焦点时,不知道自己焦点在哪里。在这种情况下,用户的体验会很差。关于这一点,可以参考《绝不要删除样式的外边框》和《为你的网站设置有用和可用的焦点指示器样式》两篇文章(注:两篇文章均为英文)。我们面临的问题,其实简单来说,我们不希望点击聚焦时出现外边框,因为样式很难看,但是我们又想在使用键盘聚焦时显示外边框,因为不这样做会影响用户体验,前端领域一直在探索如何解决这个问题。以前只能用JS来判断焦点,现在可以用CSS4中新增的:focus-visible伪类选择器来处理了。接下来,许继将简要介绍这两种方案的特点和局限性。:focus-visible选择器:focus-visible是CSS4新增的伪类选择器,与:focus伪类选择器非常相似,都是在标签节点获得焦点时生效,唯一的区别是:focus伪类selector类选择器不区分引起焦点的操作,只要被焦点就会生效,而:focus-visible伪类选择器只有在键盘引起焦点时才会生效,但是可编辑元素比如除外,这种类型的元素无论什么操作引起焦点都会生效,下面是一个简单的例子:

普通标签通过点击获得焦点,边框为红色,
通过键盘的Tab键获得焦点,边框为绿色。
锚点按钮span[tabIndex="0"]

Inputable将始终匹配:focus-visible选择器,
无论什么动作引起焦点,边框都将是绿色。
span[contentEditable="true"]


↓View&Code↑看起来不错?不过XJ是这样认为的:焦点可见的伪类选择器并没有想象中那么好用。首先,它对可输入的元素进行了特殊处理,可能并不总是满足我们的需求,其次,兼容性问题。需要Firefox85+和Chrome86+支持。不要指望它用于IE和Safari。更详细的兼容性信息请参考MDN或canIuse。如果我们想让所有的浏览器都支持,就得用JS绑定事件来处理了。这是下一章要讨论的内容。这是另一条信息。早在Firefox4.0时代,Firefox就有了一个类似概念的伪类选择器:-moz-focusring,不过这个选择器最终并没有成为标准,其功能与现在的一样:focus-visible伪类选择器有相当大的区别。有些人可能会用这个选择器来做低版本Firefox的兼容,其实用处不大。此选择器现已弃用。你可以不用管它,所以XJ在上面的demo中并没有使用它。使用JS来解决这个问题使用JS来解决这个问题来实现兼容。最简单的方法就是绑定鼠标事件和键盘事件,在触发键盘事件时在中添加一个类名,比如isKbd。让.isKbd:focus{}样式规则生效,在触发鼠标事件时去掉上的isKbd类名,使.isKbd:focus{}样式规则不生效,下面是一个简单的例子,当焦点是点击引起的时候,就没有外边框了。当按下键盘引起焦点时,会有红色外框:

点击触发焦点时无外边框,
触发焦点时显示红色轮廓键盘。

按钮
锚点

span[contentEditable="true"]

↓View&Code↑那么问题解决了吗?答案是不!事实上,不仅仅是点击和键盘操作会触发焦点,JS操作和浏览器的一些默认行为也可能导致焦点被触发。我们需要一步区分判断,外边框的设置有一些特殊情况。除了可能需要特殊处理的可编辑标签外,还有一些标签比如中的是不能设置外边框的,而且设置也不一定会生效。最后,

当点击动作触发焦点时没有外边框,
focus由键盘触发时显示红色外边框。
按钮
锚点

Typeable标记焦点始终显示外边框,
无论焦点是由单击还是键盘引起的。

span[contentEditable="true"]

↓查看&代码↑这个问题解决了吗?答案是不!这样只解决了焦点行为的判断,然后就是设置样式的问题,首先是轮廓样式的限制,这个样式不能实现圆角(只有Firefox和最新版的Chrome可以),除非你的项目从头到尾都没有使用圆角,否则用圆角标签显示时轮廓总是很难看,后面是中的中的不能设置outer轮廓的边框,设置可能无效。我们可以使用box-shadow属性让外边框实现圆角,但是Safari的表单控件是不支持这个属性的,除非添加外观样式:none,但是这样会导致表单控件的默认样式为destroyed,还有一些标签不能设置外边框,那是因为这些标签可能有不规则的轮廓,outline和box-shadw无法处理这些不规则的轮廓,所以设置可能会失效,这么多问题太烦人了,有没有更现成的计划?是的,继续阅读。使用xj.focus插件处理焦点XJ写了一个xj.focus插件,也可以看成是对:focus-visible伪类选择器的polyfill,但是和WICG的焦点可见方案相比,xj.focus插件提供了更多的API参数让你自己选择焦点模式,同时它还自带一个焦点相关的CSS样式文件来解决样式问题,如果你想对焦点有更细致的控制或者是太懒得写样式,那么xj.focus也是一个不错的选择,下面是一个简单的例子:

点击操作触发焦点时没有外边框,
显示键盘触发焦点时的蓝色外边框。
按钮
锚点

可输入标签焦点始终显示外边框,
但这可以在全局配置中修改。

span[contentEditable="true"]

↓View&Code↑xj.focus插件默认提供了outline和box-shaodw两种外边框样式。Safari的form控件不支持box-shaodw,所以会自动使用outline,不过也可以通过插件的全局配置自由选择,二是插件忽略了的焦点中的,即不给它们设置外边框,让它们继续使用浏览器提供的默认值。外边框,同样也可以通过全局配置来改变。当然,xj.focus插件并不完美。由于W3C的一些标准问题,其对,在IE10/11/18中默认是可聚焦的,但在其他浏览器中不是。,在IE10/11中默认是可聚焦的,但在其他浏览器中不是。,在IE18中默认是可聚焦的,但在其他浏览器中不是。