层叠、优先级和继承
本章概要
- 组成层叠的六个标准
- 层叠和继承的区别
- 如何控制给元素施加样式
- 简写声明的常见误区
- 开始使用 CSS 的一些新功能
层叠
当声明冲突时,层叠会依据六种条件解决冲突:
- 样式表来源:作者样式 > 浏览器默认样式
- 行内样式:样式声明是通过 HTML 的
style
属性添加,还是通过 CSS 选择器添加 - 层级:
- 选择器优先级:id 选择器 > 类选择器 > 标签选择器
- 范围:
- 源码顺序:样式在样式表里的声明顺序,优先级相同的情况下,采用“后来居上”原则
层级和范围属于新增内容,将在第八章和第九章介绍。本章先介绍原有的四种标准。
一、样式表来源
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 |
通用选择器 * 、组合器(> 、~ 、+ )、否定伪类 :not | 0,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
层叠值
浏览器遵循三个步骤,即来源、优先级、源码顺序,来解析网页上每个元素的每个属性。如果一个声明在层叠中“胜出”,它就被称作一个层叠值。元素的每个属性最多只有一个层叠值。
层叠值——作为层叠结果,应用到一个元素上的特定属性的值。
如果一个元素上始终没有指定一个属性,这个属性就没有层叠值。
框图总结
继承
如果一个元素的某个属性没有层叠值,则可能会从某个祖先元素继承一个。
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.
字体系列属性
font-family
:字体系列font-weight
:字体的粗细font-size
:字体的大小font-style
:字体的风格文本系列属性
text-indent
:文本缩进text-align
:文本水平对齐line-height
:行高word-spacing
:单词之间的间距letter-spacing
:中文或者字母之间的间距text-transform
:控制文本大小写(就是uppercase
、lowercase
、capitalize
这三个)color
:文本颜色元素可见性
visibility
:控制元素显示隐藏列表布局属性
list-style
:列表风格,包括list-style-type
、list-style-image
等光标属性
cursor
:光标显示为何种形态
无继承的属性
Certain CSS properties do not inherit from their parent elements. Instead, they keep their default values unless set explicitly on the child elements.
display
:规定元素应该生成的框的类型文本属性:
vertical-align
:垂直文本对齐text-decoration
:规定添加到文本的装饰text-shadow
:文本阴影效果white-space
:空白符的处理unicode-bidi
:设置文本的方向盒子模型的属性:
width
、height
、margin
、border
、padding
背景属性:
background
、background-color
、background-image
、background-repeat
、background-position
、background-attachment
定位属性:
float
、clear
、position
、top
、right
、bottom
、left
、min-width
、min-height
、max-width
、max-height
、overflow
、clip
、z-index
生成内容属性:
content
、counter-reset
、counter-increment
轮廓样式属性:
outline-style
、outline-width
、outline-color
、outline
页面样式属性:
size
、page-break-before
、page-break-after
声音样式属性:
pause-before
、pause-after
、pause
、cue-before
、cue-after
、cue
、play-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.
一个例子:
通常我们会给网页的所有链接加上一个字体颜色(在下面的例子中,没有添加链接的样式,就会以用户代理样式为准),这个颜色同样会作用于页脚的“Terms of use”链接。
示例 HTML 代码:
<footer class="footer">
© 2016 Wombat Coffee Roasters —
<a href="/terms-of-use">Terms of use</a>
</footer>
示例 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
显式指定继承父元素的样式。
继续向样式表中添加如下代码:
.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
orfont-size,
theunset
keyword causes the element to inherit these property values from its parent, similar to the CSSinherit
keyword. - When an
unset
property is applied to non-inherited properties likemargin
orpadding,
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.
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 forfont-style,
font-weight,
font-size,
line-height,
andfont-family
border
is a shorthand forborder-width,
border-style,
andborder-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. Usingrevert
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.