54

初探CSS 选择器Level 4

 5 years ago
source link: https://www.w3cplus.com/css/css-selectors-level-4.html?amp%3Butm_medium=referral
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client

在开始聊CSS选择器Level 4( Selectors Level 4 )之前,先要明确一个简单的概念。时至今日,在CSS的世界之中再不会有大版本的称谓,比如以前大家熟悉的CSS2.1、CSS3。现在的CSS都只会以CSS模块的版本来进行区分,比如我们今天要聊的CSS选择器,其最新版本就是: CSS Selectors Level 4 。在CSS Selectors Level 4中为选择器增添了不少的新特性,当然这些新特性有的已得到浏览器的支持,有的只得到部分主流浏览器的支持。所以接下来,花点时间学习一下,以备后用。

:not()

否定伪类 :not() 是一个 函数伪类 ,以选择器列表做为参数,它表示的元素不是由其参数表示的。 :not() 选择器 可以用来做为判断的一个选择器,好比JavaScript中的非。其主要作用就是将符合规则的元素剔除,将样式规则应用于其他元素上。事实上,在CSS Selector Level 3就有 :not() 的身影,只不过当初的功能比较弱,比如 :not(p) 用来选择不是 <p> 的元素。但在新版本的中,其功能变得更为强大,可以应用更为复杂的规则,但是同样地不允许嵌套使用,比如 :not(:not(...))

我们平时开发项目的时候,时常会碰到列表这样的效果,列表项之间有一个 margin-bottom ,而往往想在最后一项中不设置 margin-bottom 。比如像下图这样的效果:

YjUr2in.png!web

往往我们借助伪类选择器 :last-child 来帮我实现,比如:

li{
    margin-bottom: 20px;
}

li:last-child {
    margin-bottom: 0;
}

如果我们使用 :not() 选择器,会变得更容易:

li:not(:last-child) {
    margin-bottom: 20px
}

上面的代码表示的意思就是: 选中除最后一项 li 的所有 li ,并给其设置 margin-bottom: 20px;

另外, :not() 选择器还有一个提高CSS权重的小作用,比如 div:not(span)div 是同一个概念,但是明显的前者的优先级要更高。

浏览器的支持度:

:has()

关系伪类 :has() :not() 选择器类似,也是一个函数伪类,不同的是 :has() 使用相对选择器列表作为参数。它表示一个元素,任何一个相对选择器(当将元素绝对化并将其赋值为 :scope 元素)至少匹配一个元素。

:has() 伪类有点类似于jQuery中的 .has() 方法,简单来说就是用来 匹配含有某些规则的元素 。比如:

// 匹配含有`img`子元素的`a`元素
a:has(> img) { }

// 匹配拥有dt兄弟元素的dt元素
dt:has(+ dt) {}

// 匹配不含有h1、h2、h3、h4、h5和h6的section元素
section:not(:has(h1, h2, h3, h4, h5, h6)) {}

// 匹配含有的不是h1、h2、h3、h4、h5、h6子元素的元素
section:has(:not(h1, h2, h3, h4, h5, h6)) {}

最后两个示例是 :not():has() 组合在一起使用的,但两者组合在一起所达到的意思却完全不一样。其中 :not(:has(selector)) 匹配不含有 selector 选择元素的元素(有点绕,对应看上面示例描述),而 :has(:not(selector)) 匹配含有的不是 selector 子元素的元素。两都主要区别在于, :has(:not(selector)) 写法必须要含有一个子元素,而 :not(:has()) 可以不含有元素也会被匹配。

:matches()

:matches() 同样是一个函数伪类,以选择器列表作为参数。主要用于匹配所述规则的元素,并应用相应的样式规则,选择该列表中任意一个选择器可以选择的元素。它可以让我们节省书写大量的 CSS 样式匹配规则,让我们从大量重复的规则书写中解放出来。

来看两个示例:

.matches {
    color: black;
}

.matches :matches(span, div) :matches(span, div) {
    color: green;
}

上面的代码等同于:

.matches span div,
.matches span span,
.matches div span,
.matches div div {
    color: green;
}

注意,许多浏览器通过一个更旧的伪类选择器 :any() 来替代 :matches() ,并且要带上对应的浏览器私有前缀, :-webkit-any():-moz-any() ,其工作方式与 :matches() 完全相同,比如上面示例,我们可以改写成:

.matches :-webkit-any(span, div) :-webkit-any(span, div) {
    color: green;
}
.matches :-moz-any(span, div) :-moz-any(span, div) {
    color: green;
}

来看一个简单的示例:

示例中通过一行代码:

:matches(header, main, footer) p:hover {
    color: red;
    cursor: pointer;
}

就替代了:

header p:hover,
main p:hover,
footer p:hover {
    color: red;
    cursor: pointer;
}

如果你使用过CSS的处理器,就较好理解,它有点类似于CSS处理器中的嵌套规则。

有一点需要注意, :matches() 不能嵌套工作,也不能和 :not() 配合在一起工作,比如下面的几个选择器,都将无法正常工作:

:matches(:not(...)) {}
:not(:matches(...)) {}
:matches(:matches(...)) {}

除此之外,在 :matches() 传递的选择器列表中也不允许一些组合选择器,比如 ~>+ 等。

浏览器支持度:

:something()

:something() 被称为权重调整伪类,也是一个函数伪类,其语法和功能与 :matches() 类似。其不同之处是 :something() 伪类和它的任何参数都不影响选择器的权重, 它的权重总是为 0

对于在选择器中引入过滤器很有用,同时保持关联的样式声明易于重写。

下面是一个常见的例子:

a:not(:hover) {
    text-decoration: none;
}

nav a {
    /* 无效果 */
    text-decoraation: underline;
}

如果我们使用 :something() 伪类选择器就可以达到作者期望的效果:

a:something(:not(:hover)) {
    text-decoration: none;
}

nav a {
    /* Works now! */
    text-decoration: underline;
}

About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK