CSS 之原来你是这样子的: first-child

1,652 阅读4分钟

前言

写这篇文章的目的,一方面是纠正自己一直以来对这个伪类的误解(请看下面的代码)和更好的理解浏览器对:first-child解析和渲染机制,另一方面是希望通过这篇文章,能够让更多的新人深刻理解这个知识点。
注:first-child是CSS2的一个伪类(对于想知道伪元素和伪类的具体定义,请自行Google 或 W3C)。

代码示例

这个特定伪类很容易遭到误解,所以有必要举例来说明,废话少说,直接上代码:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <style type="text/css">
        p:first-child { color: red; }
        li:first-child { color: blue; }
    </style>
</head>
<body>
<div>
    <ul>
        <li>Vue 2</li>
        <li>Angular <strong>2</strong></li>
        <li>React</li>
    </ul>
    <p>Hello Everyone</p>
    <p><em>我</em> 是来搞事的.</p>
</div>
<p><b>注释:</b>必须声明 DOCTYPE,这样 :first-child 才能在 IE 中生效。</p>
</body>
</html>

主要看两个部分,一是样式部分,二是HTML主体内容,现在只需要在自己的脑海里想象出浏览器渲染出来的效果,对于这个效果,我将一一脑补出来给大家.
A:我YY出来了,呐

a

B:可能是这样
B

C:应该是这样吧
C

D:你们都错了
d


提示:最常见的错误是认为 p:first-child 之类的选择器会选择 p 元素的第一个子元素。

知识点整理

结果是什么不重要,先来看看W3C CSS2.1对伪类:first-child的说明和注意事项:

The :first-child pseudo-class matches an element that is the first child element of some other element.

翻译过来大致是(英文渣渣):":first-child这个伪类会匹配其它元素中第一个子元素",也就是说,是相对于其父元素的第一个子元素。

Note that since anonymous boxes are not part of the document tree, they are not counted when calculating the first child.

大致意思是:"匿名元素(比如<p>Hello <b>World</b></p>中的Hello)将不会包含在dom tree里面,使用:first-child伪类时是不会把匿名元素当成一个元素计算进去";也就是说,除了匿名元素,其它的任何元素都可以作为父元素,包括<body>、<ul>、<li>等等。

参考CSS2.1标准对于伪类:first-child的说明

我相信细心的人差不多都已经get到点了,第一个知识要点是 相对于父元素的第一个子元素 第二个是 不会计算匿名元素 (虽然我不知道称为匿名元素准不准确,如果说错的请轻拍并告诉正确的中文翻译)

代码分析

搞清楚上面提到的知识点之后,我们才能够有信心的做出专业判断,现在分析一下之前那段代码。
CSS:

p:first-child { color: red; }
li:first-child { color: blue; }

HTML:

<body>
    <div>
        <ul>
            <li>Vue 2</li>
            <li>Angular <strong>2</strong></li>
            <li>React</li>
        </ul>
        <p>Hello Everyone</p>
        <p><em>我</em> 是来搞事的.</p>
    </div>
    <p><b>注释:</b>必须声明 DOCTYPE,这样 :first-child 才能在 IE 中生效。</p>
</body>

CSS分析:
p:first-child { color: red; }是作为某元素(不包含匿名元素)的第一子元素的所有p元素的字体颜色都设置为红色;
li:first-child { color: blue; }同理;
HTML分析:
<div><body>的第一个子元素,最下面的<p>元素是<body>的:last-child;
<ul>作为<div>第一个子元素,下面两个<p>很明显不作为<ul>第一子元素;
<li>Vue2</li>是ul元素的第一个子元素;
以此类推,<em>作为<p>的第一子元素,<b>作为<p>的第一子元素,最终呈现在浏览器的效果为...

总结

:first-child和:last-child伪类在WEB开发中使用得非常频繁,比如使用:last-child清除浮动,使用CSS对:first-child选择的第一个子元素进行特殊处理;两者知一晓二,所以对于深刻理解它们是非常有必要。


本文对你有帮助?欢迎扫码加入前端学习小组微信群: