Skip to content

层叠、优先级和继承

本章概要

  • 组成层叠的六个标准
  • 层叠和继承的区别
  • 如何控制给元素施加样式
  • 简写声明的常见误区
  • 开始使用 CSS 的一些新功能

层叠

当声明冲突时,层叠会依据六种条件解决冲突:

  1. 样式表来源:作者样式 > 浏览器默认样式
  2. 行内样式:样式声明是通过 HTML 的 style 属性添加,还是通过 CSS 选择器添加
  3. 层级:
  4. 选择器优先级:id 选择器 > 类选择器 > 标签选择器
  5. 范围:
  6. 源码顺序:样式在样式表里的声明顺序,优先级相同的情况下,采用“后来居上”原则

层级和范围属于新增内容,将在第八章和第九章介绍。本章先介绍原有的四种标准。

一、样式表来源

There are three different origins of stylesheets:

  • author styles
  • user styles
  • user-agent styles

All taken together, the overall order of preference, in decreasing order, is as follows:

  • Important user-agent
  • Important user
  • Important author
  • Normal author
  • Normal user
  • Normal user-agent

用户样式,对网站作者来说属于不可控的部分,在此忽略。那么样式表的来源便可简化为两个:

  • author styles
  • user-agent styles

最常见的使用场景:使用作者自定义样式覆盖浏览器默认样式。

二、行内样式

如果用 HTML 的 style 属性写样式,这个声明只会作用于当前元素。实际上行内元素属于“带作用域的”声明,它会覆盖任何来自样式表或者 <style> 标签的样式。行内样式没有选择器,因为它们直接作用于所在的元素。

To override inline declarations in your stylesheet, you’ll need to add an !important to the declaration, shifting it into a higher-priority origin.

三、选择器优先级

优先级的准确规则如下:

  • 如果选择器的 id 数量更多,则它会胜出(即它更明确)
  • 如果 id 数量一致,那么拥有最多类的选择器胜出
  • 如果以上两次比较都一致,那么拥有最多标签名的选择器胜出

优先级标记:

选择器权重
!important无穷大
行内样式1,0,0,0
id 选择器0,1,0,0
类、伪类、属性选择器0,0,1,0
标签、伪元素选择器0,0,0,1
通用选择器 *、组合器(>~+)、否定伪类 :not0,0,0,0
继承的样式没有权值
  • 伪类选择器(如 :hover)和属性选择器(如 [type="input"])与一个类选择器的优先级相同
  • 通用选择器 *,组合器(>~+),否定伪类 :not 对优先级没有影响,不作计入
  • :not 伪类不像其它伪类,它不会增加选择器的优先级
  • :not(X) 伪类的优先级即为它参数选择器 X 的优先级

四、源码顺序

解析层叠值的最后一步是源码顺序,遵循“后来居上”的原则。

链接样式和源码顺序

这个顺序的记忆口诀是“LoVe/HAte”(“爱/恨”),即 link(链接)、visited(访问)、hover(悬停)、active(激活)。

How to organize CSS @ 9elements
The Definitive Guide to CSS Styling Order
High-level advice and guidelines for writing sane, manageable, scalable CSS

层叠值

浏览器遵循三个步骤,即来源、优先级、源码顺序,来解析网页上每个元素的每个属性。如果一个声明在层叠中“胜出”,它就被称作一个层叠值。元素的每个属性最多只有一个层叠值。

层叠值——作为层叠结果,应用到一个元素上的特定属性的值。

如果一个元素上始终没有指定一个属性,这个属性就没有层叠值。

框图总结

CSS 样式优先级

继承

如果一个元素的某个属性没有层叠值,则可能会从某个祖先元素继承一个。

It’s common to apply a font-family to the <body> element. All the descendant elements within will then inherit this font; you don’t have to apply it explicitly to each element on the page.

支持继承的属性

Several properties are inherited by default, and unless they are overridden, the styles applied to the parent element are passed down to the subsequent child elements.

  1. 字体系列属性
    font-family:字体系列
    font-weight:字体的粗细
    font-size:字体的大小
    font-style:字体的风格

  2. 文本系列属性
    text-indent:文本缩进
    text-align:文本水平对齐
    line-height:行高
    word-spacing:单词之间的间距
    letter-spacing:中文或者字母之间的间距
    text-transform:控制文本大小写(就是 uppercaselowercasecapitalize 这三个)
    color:文本颜色

  3. 元素可见性
    visibility:控制元素显示隐藏

  4. 列表布局属性
    list-style:列表风格,包括 list-style-typelist-style-image

  5. 光标属性
    cursor:光标显示为何种形态

无继承的属性

Certain CSS properties do not inherit from their parent elements. Instead, they keep their default values unless set explicitly on the child elements.

  1. display:规定元素应该生成的框的类型

  2. 文本属性:
    vertical-align:垂直文本对齐
    text-decoration:规定添加到文本的装饰
    text-shadow:文本阴影效果
    white-space:空白符的处理
    unicode-bidi:设置文本的方向

  3. 盒子模型的属性:widthheightmarginborderpadding

  4. 背景属性:backgroundbackground-colorbackground-imagebackground-repeatbackground-positionbackground-attachment

  5. 定位属性:floatclearpositiontoprightbottomleftmin-widthmin-heightmax-widthmax-heightoverflowclipz-index

  6. 生成内容属性:contentcounter-resetcounter-increment

  7. 轮廓样式属性:outline-styleoutline-widthoutline-coloroutline

  8. 页面样式属性:sizepage-break-beforepage-break-after

  9. 声音样式属性:pause-beforepause-afterpausecue-beforecue-aftercueplay-during

特殊值

  • inherit
  • initial
  • unset
  • revert

The inherit keyword

The inherit CSS keyword causes the element to take the computed value of the property from its parent element.

To know more about inheritance, you have to shift from styling individual elements and adjusting them to considering how styles can cascade through the document’s hierarchy.

Working of CSS Inheritance

一个例子:

通常我们会给网页的所有链接加上一个字体颜色(在下面的例子中,没有添加链接的样式,就会以用户代理样式为准),这个颜色同样会作用于页脚的“Terms of use”链接。

示例 HTML 代码:

HTML
<footer class="footer">
  &copy; 2016 Wombat Coffee Roasters &mdash;
  <a href="/terms-of-use">Terms of use</a>
</footer>

示例 CSS 代码:

CSS
.footer {
  color: #666;
  background-color: #ccc;
  padding: 15px 0;
  text-align: center;
  font-size: 14px;
}

通过 F12 查看 .footer 内部的 a 元素,可以看到,用户代理样式的伪类 a:-webkit-any-link,覆盖了作者样式的类选择器 .footer

color 属性不是会继承吗,为什么 footer 里的 a 标签没有继承 footer 的灰色,仍然是蓝色的呢? 这是因为,虽然子元素有默认继承父元素样式的特点,但是默认继承的样式其优先级最低,通常会被用户代理样式覆盖。如果需要覆盖用户代理样式,可以通过关键字 inherit 显式指定继承父元素的样式。

继续向样式表中添加如下代码:

CSS
.footer {
  color: #666;
  background-color: #ccc;
  padding: 15px 0;
  text-align: center;
  font-size: 14px;
}

.footer a {
  color: inherit;
}

加入这段代码之后,显示使用 inherit 指定继承的样式就可以覆盖用户代理样式,此时“Terms of use”链接会变成灰色。

结论:显式使用 inherit 继承的样式(灰色) > 用户代理样式(蓝色) > 默认继承的样式(灰色)

You can also use the inherit keyword to force inheritance of a property not normally inherited, such as border or padding, though you will likely not find many practical uses for this.

层叠与继承

The initial keyword

Initial values are the default values that CSS properties revert to if no other overriding styles are specified. The initial value ensures the browser has a predefined way to display an element, even without explicit styles.

The unset keyword

Unlike initial, which always resets a property to its default value, unset acts differently based on whether a property is naturally inherited.

  • When applied to inherited properties, such as color or font-size, the unset keyword causes the element to inherit these property values from its parent, similar to the CSS inherit keyword.
  • When an unset property is applied to non-inherited properties like margin or padding, it resets the property to its initial value, the default value defined by the browser’s CSS specifications.

The unset property is useful in scenarios where you want to set a bunch of properties all at once to initial or inherit. You can use it with the all property, which is one of the CSS global keyword values.

css
element {
  all: unset;
}

With the above line of code, all properties of the element will be reset. Properties usually inherited will default to inherit, and all others will revert to their initial values.

The revert keyword

The revert property is similar to the initial keyword. However, the difference is that instead of setting properties to their initial values as defined in CSS specifications, it reverts them to the browser’s default style.

简写属性

Shorthand properties are properties that let you set the values of several other properties at one time.

  • font is a shorthand for font-style, font-weight, font-size, line-height, and font-family
  • border is a shorthand for border-width, border-style, and border-color
  • border-width is shorthand for the top, right, bottom, and left border width.

前进式改善

  • Using the cascade for progressive enhancement
  • Progressively enhancing selectors
  • Feature queries using @supports()

总结

  • The browser follows the rules of the cascade to determine which styles are applied to which elements.
  • A selector’s specificity is determined by the number of IDs, classes, and tag names in the selector. Declarations with higher specificity selectors will override those with lower specificity.
  • When no cascaded value is present for certain properties, elements inherit a value from their parent element. These properties include those for text, lists, and table borders.
  • Providing a value of unset undoes other styles otherwise provided for that property, including user-agent styles. Using revert undoes your author styles but leaves user-agent styles intact.
  • Shorthand properties provide a concise way to set values for multiple related properties at once.
  • For shorthand properties such margin and padding, specify the values in clock-wise order, beginning with the top.
  • Progressive enhancement allows us to use cutting-edge CSS without breaking the page in older browsers.
最近更新