CSS 选择器及其优先级

CSS 选择器用于“选中” HTML 元素并应用样式。

1. 选择器类型与权重

选择器示例权重
!importantcolor: red !important;最高 (Override)
行内样式style="color: red"1000
ID 选择器#header0100
类选择器.btn0010
属性选择器[type="text"]0010
伪类选择器:hover, :first-child0010
元素选择器div, p, h10001
伪元素选择器::before, ::after0001
通配符/组合器*, +, >, ~0000

注意:not() 伪类本身不计算权重,但它里面的参数选择器会计算。

2. 层叠层级

当同一个元素被多个规则命中时,浏览器不是只看选择器权重,还会按“层叠顺序”决定最终样式。

从低到高可以理解为:

  1. 浏览器默认样式(User Agent)。
  2. 用户样式(User Styles,较少使用)。
  3. 开发者样式(Author Styles)。
  4. 选择器优先级(Specificity)。
  5. !important

补充规则:

  • 同一层级、同一权重下,后声明的规则覆盖先声明的规则(后来居上)。
  • *+>~ 这类通配符和组合器不增加权重。
  • !important 会提升声明优先级,但仍不建议滥用,否则可维护性会变差。

3. 伪类

表示元素的状态逻辑位置

常用状态伪类

  • :hover: 鼠标悬停。
  • :active: 鼠标按下。
  • :focus: 获得焦点。
  • :visited: 链接已访问。

结构伪类

  • :first-child: 父元素的第一个子元素。
  • :last-child: 父元素的最后一个子元素。
  • :nth-child(n): 父元素的第 n 个子元素。
  • :nth-of-type(n): 父元素的第 n 个同类型子元素。

:nth-child vs:nth-of-type

  • p:nth-child(2): 选中父元素的第 2 个子元素,该元素必须是 <p>。如果第 2 个子元素是 <div>,则无法选中。
  • p:nth-of-type(2): 选中父元素下的第 2 个 <p> 元素(忽略其他类型的兄弟元素)。

4. 伪元素

用于创建一些不在 DOM 树中的元素,或选中元素的特定部分。必须使用双冒号 :: (CSS3 规范),单冒号兼容旧版。

  • ::before: 在元素内容之前插入内容 (常用于图标、清除浮动)。
  • ::after: 在元素内容之后插入内容。
  • ::first-line: 选中第一行文本。
  • ::first-letter: 选中第一个字母。
  • ::selection: 选中被用户选取的文本。
/* 经典清除浮动 */
.clearfix::after {
  content: "";
  display: block;
  clear: both;
}

5. 常见面试题

1. CSS 优先级如何计算?

  • 可用四段模型理解:Inline > ID > Class/属性/伪类 > Tag/伪元素。
  • 常见简化记法:ID +100,Class +10,Tag +1,行内样式可视为 1000。
  • 真正落地还要结合层叠顺序(来源、声明先后、!important)。
  • 权重相同且同层级时,后定义覆盖先定义(后来居上)。

2.:nth-child:nth-of-type 的区别?

  • :nth-child(n) 强调的是“结构上的第 n 个子元素”,不区分类型。
  • :nth-of-type(n) 强调的是“同类型中的第 n 个”。

3. 可以继承的 CSS 属性有哪些?

  • 字体文本类font-size, font-family, color, text-align, line-height
  • 不可继承border, padding, margin, width, height, background