CSS里关于元素匹配里面有两个非常类似却又不尽相同的选择器,伪类 :first-child 和 :first-of-type
两者在匹配方式上有很大差异,其实在一开始自己也没去注意这个细节,直到上次一个同事遇到同级元素匹配失败的问题后才发现原来以前的理解都不正确。
先来看看可爱的同事遇到的问题:
HTML代码
1 <div id="add_road"> 2 <span class="input-title">路段 I D</span> 3 <input id="road_id" placeholder="road-id" value="S12"/> 4 <span class="required">*</span> 5 <span class="input-title">路段名称</span> 6 <input id="road_name" placeholder="rode-name" value="苏州桥"/> 7 <span class="required">*</span> 8 </div>
CSS代码
1 .add_input input:first-child{ 2 color:#3c0; 3 } 4 .add_input input:last-child{ 5 color:#c30; 6 }
在此为了测试方便对代码做了一些调整。效果如图:
可是发现我们对字体颜色进行设置的CSS代码没有效果,这跟我之前理解的:first-child和:last-child就有些出入。
那么接下来我们把最后一个<span>去掉
即:
删减后的HTML代码
1 <div id="add_road"> 2 <span class="input-title">路段 I D</span> 3 <input id="road_id" placeholder="road-id" value="S12"/> 4 <span class="required">*</span> 5 <span class="input-title">路段名称</span> 6 <input id="road_name" placeholder="rode-name" value="苏州桥"/> 7 </div>
效果如图:
我们发现:咦~ :last-child生效了,可我们想要的效果是一个为绿色,一个为红色,这显然还有差距。
然后我们再把第一个span删掉:
删减后的HTML代码
1 <div id="add_road"> 2 <input id="road_id" placeholder="road-id" value="S12"/> 3 <span class="required">*</span> 4 <span class="input-title">路段名称</span> 5 <input id="road_name" placeholder="rode-name" value="苏州桥"/> 6 </div>
效果如图:
结果不错,虽然没有标题很丑,但是至少两个伪类都有效果了。
那现在我们需要分析一下为什么会出现这种结果。
首先对:first-child和:first-of-type用一句话做出总结:
A B:first-child —— A元素的第一个子元素,且这个子元素为B,如果不是则CSS失效
A B:first-of-type —— A元素的第一个为B的子元素
也就是说在使用:first-child 时需要注意元素之前不能有其他同级元素,不然会使得样式失效,而在不确定的情况下可使用first-of-type属性
在CSS参考手册上有个关于:nth-child 的例子挺不错,可以帮助我们更有效地理解这个伪类
示例代码
1 <div> 2 <p>第1个p</p> 3 <p>第2个p</p> 4 <span>第1个span</span> 5 <p>第3个p</p> 6 <span>第2个span</span> 7 <p>第4个p</p> 8 <p>第5个p</p> 9 </div>
当我们使用 p:nth-child(3){color:#f00;} 时发现并没有任何效果,而再尝试 p:nth-child(4){color:#f00;} 可以看到 <p>第3个p</p> 这一元素变为了红色而不是 <p>第4个p</p>
在此对于 :nth-child(n) 的解释为: E:nth-child(n) 会选择父元素的第n个子元素E,如果第n个子元素不是E,则是无效选择符,但n会递增
大家可以据此理解两个伪类之间的区别于联系。
祝生活愉快~