最近在练习网易严选首页的布局时,发现它的顶部导航栏需求很特殊,第一项和最后两项是没有下拉选择框的。那么问题来了,在写css的时候该怎么使用选择器去达到这样的需求呢!?
首先先贴一下我最后的解决方案:
.nav-first>li:nth-child(n+2):not(:nth-last-child(-n+2)):hover .nav-second {
display: block;
}
其中核心是:
:nth-child(n+2):not(:nth-last-child(-n+2))
:nth-child(n+2)
是从第二子元素开始选择,就剔除了第一个子元素;
:not(:nth-last-child(-n+2))
是把倒数第二个及之后的所有子元素都剔除。
结构伪类选择器深度解析
以以下代码为例:
<ul class="nav">
<li>1</li>
<li>2</li>
<li>3</li>
<li>4</li>
<li>5</li>
<li>6</li>
<li>7</li>
<li>8</li>
</ul>
1) :first-child
匹配父元素
nav
的第一个子元素
1
,
nav
的第一个子元素必须是
li
标签,否则选择器会失效。
.nav li:first-child {
color: #fff;
background-color: red;
}
2) :last-child
匹配父元素
nav
的最后一个子元素
8
,
nav
的最后一个子元素必须是
li
标签,否则选择器会失效。
.nav li:last-child {
color: #fff;
background-color: red;
}
3) :only-child
匹配父元素
nav
的唯一一个子元素
1
,
nav
只能有一个子元素,而且必须是
li
标签,选择器才会生效,实用性不大。
.nav li:only-child {
color: #fff;
background-color: red;
}
4) :nth-child()
这个选择符括号内可以写+/- an + b (a,b均为整数)或者关键字:
① nth-child(a)
当括号里只写一个数字,比如
.nav li:nth-child(2)
,作用为选中父元素
nav
的第二个子元素
li
标签,如果
nav
的第二个子元素不是
li
标签,则选择符失效。
.nav li:nth-child(2) {
color: #fff;
background-color: red;
}
② nth-child(2n) / nth-child(2n+1)
程序猿对2n,2n+1一定很敏感——常见的奇偶数写法。
所以括号内写
2n
就是选中
nav
父元素的所有偶数项子元素
li
;
2n+1
就是选中所有奇数项子元素。以
2n+1
为例:
.nav li:nth-child(2n+1) {
color: #fff;
background-color: red;
}
③ nth-child(even) / nth-child(odd)
括号内也允许使用关键字:
odd
代表奇数,
even
代表偶数。
.nav li:nth-child(even) {
color: #fff;
background-color: red;
}
④ nth-child( +/- n+b)
n
的作用其实是连续向后选中,
b
的作用是从第几个子元素开始。
以
.nav li:nth-child(n+3)
为例,将会选中第三个元素以及之后的所有子元素。
.nav li:nth-child(n+3) {
color: #fff;
background-color: red;
}
– n
会把连续选中的方向改为向前,以
.nav li:nth-child(-n+4)
为例,将会选中第四个元素以及之前的所有子元素。
.nav li:nth-child(-n+4) {
color: #fff;
background-color: red;
}
5) :nth-last-child( +/- n+b)
这个选择符的作用类似于第四个
:nth-child
,只不过是从正数变成了倒数,连续选择的默认方向改成了向前。
可以看以下两者等价对比图:
:nth-child | :nth-last-child | 作用域 |
---|---|---|
:nth-child(2) | :nth-last-child(7) | 选中第二个 |
:nth-child(2n+1) | :nth-last-child(2n) | 选中所有奇数项 |
:nth-child(even) | :nth-last-child(odd) | 选中所有偶数项 |
:nth-child(n+3) | :nth-last-child(-n+6) | 选中第三个及之后的所有项 |
:nth-child(-n+4) | :nth-last-child(n+5) | 选中第四个及之前的所有项 |
6) :not()
:not()
选择符需要配合前边所讲的选择符使用,它的作用是
剔除
括号内选中的子元素。以开头的网易严选案例来说,不选中最后两个子元素,可以先写
:nth-last-child(-n+2)
,作用为选中倒数第二个及之后的所有子元素,然后把它放进
:not()
的括号内就达成了这个需求。
.nav li:not(:nth-last-child(-n+2)) {
color: #fff;
background-color: red;
}
中间小结
前五个选择符都是以
-chlid
结尾的,它的工作原理是先确定子元素位置,然后再看当前位置子元素标签是否符合设定的标签类型,符合就选中,不符合就不选中,所以会出现选择符无效的情况;
接下来要讲的一组选择符都是以
-of-type
结尾,它是先筛选出来所有符合标签类型的子元素,重新排列顺序,然后按照设定确定最终选中的子元素位置。
所以我们稍微改一下示例代码:(把数字1,3,5的标签改成了div)
<ul class="nav">
<div>1</div>
<li>2</li>
<div>3</div>
<li>4</li>
<div>5</div>
<li>6</li>
<li>7</li>
<li>8</li>
</ul>
7) :first-of-type
类似于
:frist-chlid
,这个选择符是选择同类型中的第一个同级兄弟元素。比如选择
li
标签:
.nav li:first-of-type {
color: #fff;
background-color: red;
}
所以nav下的所有div标签就不参与本次样式设定,示例代码相当于:
<ul class="nav">
<li>2</li>
<li>4</li>
<li>6</li>
<li>7</li>
<li>8</li>
</ul>
在这里
.nav li:first-of-type
等同于
.nav li:nth-chlid(2)
。
同理若选择div标签,则示例代码相当于:
<ul class="nav">
<div>1</div>
<div>3</div>
<div>5</div>
</ul>
css样式就该这么写:
.nav div:first-of-type {
color: #fff;
background-color: red;
}
8) :last-of-type
选择同类型中的最后一个同级兄弟元素。以
li
标签为例:
.nav li:last-of-type {
color: #fff;
background-color: red;
}
9) :only-of-type
选择同类型中的唯一的一个同级兄弟元素。以
li
标签为例:
.nav li:only-of-type {
color: #fff;
background-color: red;
}
由于
li
标签不唯一,所以选择符失效:
10) :nth-of-type
和上述
:nth-chlid
语法相同,在这只举一例:
.nav li:nth-of-type(n+2) {
color: #fff;
background-color: red;
}
11) :nth-last-of-type
和上述
:nth-last-chlid
语法相同,在这也只举一例:
.nav div:nth-last-of-type(-n+2) {
color: #fff;
background-color: red;
}
结构伪类选择器也可以组合使用,来满足PM大大的各种 “ 合理 ” 需求~
(现在开篇的案例是不是就很好理解啦~)
到这里,今天的结构伪类选择器的深度解析就讲完啦~ ❀撒花❀❀撒花❀❀❀❀❀
感谢你萌的耐心观看,这次是写的篇幅最长的一次了,呼~
码字不易,希望能对你萌的学习有所帮助!爱你们呦💗
其实哈,我自己在总结的时候,突然有一个想法,今天所讲的选择器都是以标签为基础进行选择的,那么能不能给标签加上统一的类名,选择器会对类名起作用吗!?!
比如这样
.item:nth-child(n+3)
再或者这样的
.item:nth-of-type(3)
以
-of-type
结尾的选择器原理就是先筛选标签,那么遇上类名会发生什么?!?
陷入沉思ing ~ – ~
明天再更新这些问题吧!我也很期待会发生什么奇奇怪怪的事情🐞🐛🐞~