CSS3的nth-child选择器

原文链接:https://grack.com/blog/2015/01/09/abusing-css3-selectors/

如果你对这篇文章感兴趣,可以了解更多的有关 CSS4 的知识来提升自己。

CSS3的:nth-child:nth-last-child 选择器的神奇之处,不仅仅是可以替代 :first-child:last-child 选择器,它还可以匹配更为复杂的子元素,比如匹配某个元素(或除第一个元素外)的三个子孙元素,元素中四的倍数的子元素,又或者通过 a*n+b 这样的表达式来进行匹配子元素。

但你有没有想过这个选择器还有其他的妙用?比如,你可以使用它来获取仅有五个子元素的元素中的第三个元素子元素(接下来我们会介绍一个伪选择器 :nth-of-m-child 选择器)。你还可以获取仅有M个子元素的元素中的所有的子元素(另一个伪选择器,我们称之为 :family-of-m)。

我们什么时候需要用这两个选择器呢?比如我们有一个大小不固定,个数不固定的照片墙,但不想依赖于JS来实现这个效果,能否实现呢?点击 示例 预览实现的效果。

src="http://10.168.0.151/zhengxuejiao/cssselector/image-count.html" width="550" height="300">

:nth-of-M-child

选择含有M个子元素的第某个元素。

很感谢 xantys 向我提供了相关资料链接。资料1资料2

首先,第一个我要介绍的是:nth-of-m-child 伪类。假设元素的子元素位置固定,我们可以通过结合使用:nth-child:nth-last-child 来获取元素。

如果,我们想获取仅含有五个子元素的第三个子元素 。示例

span:nth-child(3):nth-last-child(3) { ... }

由此我们得出一个通用的公式(m,n为变量)
如果,我们想获取仅含有五个子元素的第三个子元素 。示例

:nth-child(n):nth-last-child(m+1-n).
src="http://10.168.0.151/zhengxuejiao/cssselector/nth-test.html" width="550" height="300">

:FAMILY-OF-M

现在我们可以获取一共含有M个元素的第N个元素,如果我们想扩展一下,直接获取某个含有M个元素的父节点下的所有子元素。这里的秘密是我们使用了CSS3的~兄弟选择器,它会暴力地匹配到所有的同级兄弟元素。如:

img ~ span { ... }

这种方法会获取到所有的同级的元素,而不管它一共有几个。那么,我们可以尝试结合加入我们的 :nth-of-m-child 选择器来实现。

span:nth-child(1):nth-last-child(5) ~ span { ... }

这种方法会获取到一共只含有5个子元素的第一个子元素(不包含它本身)的所有的兄弟节点,也就是说从第二个子元素到第五个子元素。最后,我们可以通过逗号,把第一个子元素的选择器加上,代码如下, 预览地址

span:nth-child(1):nth-last-child(5), span:nth-child(1):nth-last-child(5) ~ span { ... }
src="http://10.168.0.151/zhengxuejiao/cssselector/nth-family-test.html" width="550" height="300">

更进一步的探讨

我们准备好了图片,接下来来填写它的样式。

一行展示一张图片是很容易的,但当我们准备放置三张图片,希望其中第一张或者第二张图片稍大一些,我们就会需要用到选择器匹配。我们的这种匹配方式可以不用在意图片的个数。

下面是一个带注释的例子。需要我们注意的是,可能使用弹性伸缩盒子更为简单实现,我们这里只是为读者提供一种练习使用这种选择器的方式。

我们使用第五个,第八个,第十一个….来进行特殊匹配。我们可以使用:nth-child(1):nth-last-child(3n+5)来代替我们之前使用的:nth-child(1):nth-last-child(...) 这种方式,获取第 5,8,11,…等的子元素

/* First two are half-sized (99% / 2) */
img:first-child:nth-last-child(3n+5) ~ img, img:first-child:nth-last-child(3n+5) {
    max-width: 49.5%;
    margin-right: 1%;
}

/* Last n - 2 are (98% / 3) */
img:first-child:nth-last-child(3n+5) + img ~ img {
    max-width: 32.6%;
    margin-right: 1%;
}

/* But second, fifth, eighth, ... have no right margin */
img:first-child:nth-last-child(3n+5) ~ img:nth-child(3n+2) {
    margin-right: 0;
}

想匹配6,9,12那就更容易了。

/* Six, nine, twelve, ... are all (98% / 3) */
img:first-child:nth-last-child(3n+6) ~ img, img:first-child:nth-last-child(3n+6) {
    max-width: 32.6%;
    margin-right: 1%;
}

/* Every third one of these has no right margin. */
img:first-child:nth-last-child(3n+6) ~ img:nth-child(3n) {
    margin-right: 0;
}

7,10,13…类似于5/8/11

/* First four are half-sized (99% / 2) */
img:first-child:nth-last-child(3n+7) ~ img, img:first-child:nth-last-child(3n+7) {
    max-width: 49.5%;
    margin-right: 1%;
}

/* Last n - 4 are (98% / 3) */
img:first-child:nth-last-child(3n+7) + img + img + img ~ img {
    max-width: 32.6%;
    margin-right: 1%;
}

/* The second and fourth, seventh, tenth, ... have no right margin */
img:first-child:nth-last-child(3n+7) + img,
    img:first-child:nth-last-child(3n+7) ~ img:nth-child(3n+4) {
    margin-right: 0;
    outline: 1px solid red;
}

总结

我们可以通过使用:nth-child和其他的选择器来实现更多有趣的效果。这种匹配方式也同样适用于 :nth-of-type:nth-last-of-type

这种方式在手机端和PC端并没有明显差距,但如果你介意的话,可以自己做一下测试。
如果你打算结合弹性盒子中的 flex-wrap 来简化示例,那么你可能可以更优雅的使用更多不同的尺寸来展示我们的图片。
你也可以将表达式中的参数改为even 或者 odd,来匹配奇数偶数,或者其他限定符。
如果你对这篇文章有任何疑问或者更好的建议,可以通过JSFiddle展示给我。
欢迎关注我的Twitter账号@mmastrac ,与我联系。

2015.01.09

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值