这是一篇由一个 CSS 选择器引发的文章,讲真,从来没想过会写一篇关于 CSS 选择器的文章。
事先声明,这篇文章是对一些基础的回顾,没有什么新东西或者黑科技。
如果你早已将这些 CSS 基础烂熟于胸,大可直接 Ctrl + w。
如果你跟我一样对这些基础有些遗忘,那么可以尝试看下去。
事情的经过是这样的......
那是一个月黑风高的夜晚,我和同事一边愉快地加着班,一边悲愤地打着农药。趁着被敌方后羿shutdown的间隙,我花了 20 秒敲下了一行代码,等待页面热更新,查看效果,perfect!一切正常!
然鹅,正当我快要复活的时候,列表也滚到底了,卧槽!!最后一个 Item 样式出现了问题,但是时间已经来不及,快要复活了......以后可以写一篇博客叫《论敌方打野与我方打野》。
虽然我只花了一分钟就换了个方式来解决这个问题,但彻底把原来的问题搞明白却花了我差不多一个小时。
先给大家重现一下问题:
之前正常运行的代码
<div class="list">
<div class="item">我是第一个item</div>
<div class="item">我是第二个item</div>
<div class="item">我是第三个item</div>
<div class="item">我是第四个item</div>
<div class="item">我是第五个item</div>
</div>
.list {
padding: 15px;
background-color: #eee;
}
.item {
margin-bottom: 15px;
border-radius: 4px;
background-color: #fff;
}
.item:last-child {
margin-bottom: 50px;
}
有问题的代码
<div class="list">
<div class="item">我是第一个item</div>
<div class="item">我是第二个item</div>
<div class="item">我是第三个item</div>
<div class="item">我是第四个item</div>
<div class="item">我是第五个item</div>
<div class="dialog">......</div>
</div>
.list {
padding: 15px;
background-color: #eee;
}
.item {
margin-bottom: 15px;
border-radius: 4px;
background-color: #fff;
}
.item:last-child {
margin-bottom: 50px;
}
发现问题在哪了吗?
如果你一眼看出问题所在,并确切的知道原因,那么恭喜你,CSS 基础还是挺扎实的。
如果你发现了问题但不确定原因或者压根都没找到问题,那么也同样恭喜你,至少看见了这篇文章。
:last-child
通常用法:element:last-child
匹配 element 父元素及其父元素的子元素,中的最后一个 element 子元素。
注意:这里的 element 元素必须是其父元素下 所有元素 的最后一个子元素才有效。
例子:
<div class="list">
<div class="item">我是第一个item</div>
<div class="item">我是第二个item</div>
<div class="item">我是第三个item</div>
<div class="box">
<div class="item">穿插一个盒子item</div>
<div class="item">穿插两个盒子item</div>
<div class="item">穿插三个盒子item</div>
</div>
<div class="item">我是第四个item</div>
<div class="item">我是最后一个item,但不是最后一个子元素</div>
<div class="haha">我才是最后一个子元素</div>
</div>
.list {
padding: 15px;
background-color: #eee;
}
.item {
margin-bottom: 15px;
border-radius: 4px;
background-color: green;
}
.item:last-child {
background-color: red;
}
.box {
margin-left: 50px;
}
.haha {
background-color: yellow;
}
:first-child
选择器与它用法一样
:last-of-type
通常用法:element:last-of-type
匹配 element 父元素下及其父元素的子元素,中的最后一个 element 子元素。
注意:这里的 element 元素只要是其父元素下的 所有 element 元素 中的最后一个就可以。
所以看到这里,你是不是会以为下面这段代码:
<div class="list">
<div class="item">我是第一个item</div>
<div class="item">我是第二个item</div>
<div class="item">我是第三个item</div>
<div class="box">
<div class="item">穿插一个盒子item</div>
<div class="item">穿插两个盒子item</div>
<div class="item">穿插三个盒子item</div>
</div>
<div class="item">我是第四个item</div>
<div class="item">我是最后一个item,但不是最后一个子元素</div>
<div class="haha">我才是最后一个子元素</div>
</div>
.list {
padding: 15px;
background-color: #eee;
}
.item {
margin-bottom: 15px;
border-radius: 4px;
background-color: green;
}
.list .item:last-of-type {
background-color: red;
}
.box {
margin-left: 50px;
}
.haha {
background-color: yellow;
}
它的结果会是这样:
大错特错!
它的结果其实是这样:
让我们把上面 class="item"
的 div
标签换成 p
标签,那么结果就是
明明是同样的 HTML 结构和 CSS 样式,为什么就换了一个标签类型,结果就不一样了呢?
我在规范文档里发现了这样两句话:
Pseudo-classes are allowed in all sequences of simple selectors contained in a selector. Pseudo-classes
are allowed anywhere in sequences of simple selectors, after the leading type selector or universal
selector (possibly omitted).
:first-of-type pseudo-class
Same as :nth-of-type(1). The :first-of-type pseudo-class represents an element that is the first sibling of its type.
其大致意思是:
在一个选择器中,所有包含[简单选择器](https://drafts.csswg.org/selectors-3/#simple-selectors)的序列中都允许伪类。在简单选择器序列中,伪类可以放在任何地方,在主类型选择器后或者通配符选择器后(可能省略)。
:first-of-type 伪类
等同于 :nth-of-type(1)。 :first-of-type 伪类表示它这种类型的第一个兄弟元素。
不知道你是什么赶脚,反正我是
文字的表达和理解真的不是一件简单的事,所以我也只能大概的总结一下,意思就是:
:last-of-type 这样的伪类,是可以跟在一个任意简单选择器后的,但除了要匹配这个简单选择器,同时还要匹配这个简单选择器的元素类型,也就是元素标签。
talk is cheap,show you the code:
<div class="list">
<p class="item">我是第一个p标签 .item</p>
<p class="item">我是第二个p标签 .item</p>
<p class="item">我是第三个p标签 .item</p>
<div class="box">
<p class="item">穿插一个盒子p标签 .item</p>
<p class="item">穿插两个盒子p标签 .item</p>
<p class="item">穿插三个盒子p标签 .item</p>
</div>
<p class="item">我是第四个p标签 .item</p>
<p class="item">我是最后一个p标签 .item</p>
<div class="item">我是最后一个 .item,但不是最后一个div元素</div>
<div class="haha">我才是最后一个div元素</div>
</div>
.list {
padding: 15px;
background-color: #eee;
}
.item {
margin-bottom: 15px;
border-radius: 4px;
background-color: green;
}
.list .item:last-of-type {
background-color: red;
}
.box {
margin-left: 50px;
}
.haha {
background-color: yellow;
}
总结
这一篇写完,连我自己都有些晕,所以大家还是要仔细看看代码,挨个敲一敲,然后再好好体会。