不得不说CSS的世界真是一个神奇的世界,页面上那些五花八门效果大部分都有它的功劳,现在又有了css3、sass、less,更是让这个世界又新增了一些乐趣(不过也有烦恼啊!)。

言归正传,可能众多前端开发者都用过:focus但并未听说过:focus-within。那么:focus-within到底是什么?Po主也查阅了大量资料,翻看了各种介绍,这篇文章就来为你解答,(说实话要不是不想用js获取焦点事件真不知道有这个东西,我懒我知道..)

什么是 :focus-within ?

在css中:focus-within是一个伪类选择器(CSS Level 4 selector),它就像你知道的:focus或者:hover一样,不过不同的是:focus-within表示一个元素获得焦点或该元素的后代元素获得焦点。划重点,它或它的后代获得焦点

什么意思呢?这也就意味着,它或它的后代获得焦点,都可以触发 :focus-within。(举个栗子吧)

html
<div class="box">
    <label for="name">Your name:</label>
    <input type="name" name="text" id="name" placeholder="Enter your name" />
</div>
css
.box *:focus {
    background: yellow;
}
.box {
    padding: 10px;
    border-bottom: 3px solid transparent;
    transition: ease-in-out 0.3s;
}
.box:focus-within {
    border-color: #000;
}

See the Pen css:focus-within by 北海の猫 (@Ninemeow) on CodePen.0

如上述示例,父级.box获得焦点时,border颜色发生了改变。在div中的链接或input元素接收焦点,那么.box元素将会改变边框颜色。

有木有突然觉得很神奇,在以前要实现类似的效果,还需要借助JavaScript,通过.box后代元素的鼠标或键盘事件,然后给其父元素(或祖先元素,添加对应的样式)。怎么样?现在有了:focus-within 是不是就省事儿多了?

感应聚焦区域

它或它的后代获得焦点,这一点使得让感知获焦区域变得更大,所以,最常规的用法就是使用 :focus-within 感应用户操作聚焦区域,高亮提醒。

下面的效果没有添加任何 JS 代码:

See the Pen CSS focus-within INPUT by Chokcoco (@Chokcoco) on CodePen.0

无须去给获焦的元素设置:focus 伪类,而是可以给需要的父元素设置,这样当元素获焦时,我可以一并控制它的父元素的样式

核心思想用 CSS 代码表达出来大概是这样:

HTML
<div class="g-container">
    <div class="g-username">
      <input type="text" placeholder="user name" class="g_input" >
    </div>
    <div class="g-username">
      <input type="text" placeholder="code" class="g_input" >
    </div>
</div>
CSS
.g-container:focus-within {
    ...

    input {
        ....
    }
}

上述例子来自ChokCoco,这位Po主写的还有很多,有兴趣的可以去看看!

浏览器兼容性

当然了,:focus-within固然有趣,但大多前端开发者依旧还是担心它的兼容性问题。来看看Caniuse上怎么说对浏览器其支持度情况:

唠叨一下

如果你熟悉:focus并不觉得奇怪,但是如果也知道:focus-within的话,就说明你在不断的关注CSS相关的新特性,与时俱进啊(小弟佩服)!其实我感觉这个属性真的又刷新了CSS世界(少见多怪吧)。如果你也感兴趣的话,不仿自己写个Demo,总会能找到不一样的乐趣。


技术成就梦想,细节成就品质。