前言
由于有很多知识非常符合直觉或者和其他语言有通用性,因此个人觉得不需要全部记下来,本篇只记录一些个人觉得需要注意或单独记忆的知识点。
本篇主要涉及层叠、优先级、继承、函数、@规则、CSS工作流程和选择器。
层叠、优先级与继承
1. 冲突规则
(1)层叠
当应用两条同级别的规则到一个元素的时候,写在后面的就是实际使用的规则
如下面最终回显示蓝色
h1 {
color: red;
}
h1 {
color: blue;
}
<h1>This is my heading.</h1>
(2)优先级
浏览器是根据优先级来决定当多个规则有不同选择器对应相同的元素的时候需要使用哪个规则。它基本上是一个衡量选择器具体选择哪些区域的尺度:
- 一个元素选择器不是很具体,则会选择页面上该类型的所有元素,所以它的优先级就会低一些
- 一个类选择器稍微具体点,则会选择该页面中有特定 class 属性值的元素,所以它的优先级就要高一点
比如下面的最终会显示红色
.main-heading {
color: red;
}
h1 {
color: blue;
}
<h1 class="main-heading">This is my heading.</h1>
(3)继承
一些设置在父元素上的 CSS 属性是可以被子元素继承的,有些则不能
举一个例子,如果你设置一个元素的 color
和 font-family
,每个在里面的元素也都会有相同的属性,除非你直接在元素上设置属性
在下面例子中的span
被单独设置了属性,其他的p
都会直接继承body
属性
body {
color: blue;
}
span {
color: black;
}
<p>As the body has been set to have a color of blue this is inherited through the descendants.</p>
<p>We can change the color by targeting the element with a selector, such as this <span>span</span>.</p>
效果如下
一些属性是不能继承的——举个例子如果你在一个元素上设置 width
为 50% ,所有的后代不会是父元素的宽度的 50% 。如果这个也可以继承的话,CSS 就会很难使用了
2. 理解继承
(1)控制继承
CSS 为控制继承提供了五个特殊的通用属性值。每个 CSS 属性都接收这些值
inherit
:设置该属性会使子元素属性和父元素相同initial
:将属性的初始(或默认)值应用于元素。不应将初始值与浏览器样式表指定的值混淆unset
:如果这个属性本来有从父级继承的值(这个属性默认可以继承,且父级有定义),则将该属性重新设置为继承的值;如果没有继承父级样式,则将该属性重新设置为初始值。换句话说,在第一种情况下(继承属性)它的行为类似于inherit
,在第二种情况下(非继承属性)类似于initial
revert
:将应用于选定元素的属性值重置为浏览器的默认样式,而不是应用于该属性的默认值。在许多情况下,此值的作用类似于unset
revert-layer
:将应用于选定元素的属性值重置为在上一个层叠层中建立的值
比如下面例子
body {
color: green;
}
.my-class-1 a {
color: inherit;
}
.my-class-2 a {
color: initial;
}
.my-class-3 a {
color: unset;
}
<ul>
<li>Default <a href="#">link</a> color</li>
<li class="my-class-1">Inherit the <a href="#">link</a> color</li>
<li class="my-class-2">Reset the <a href="#">link</a> color</li>
<li class="my-class-3">Unset the <a href="#">link</a> color</li>
</ul>
效果如下
p.s: 第三个链接设置了 initial,这意味着它使用了属性的初始值(在本例中为黑色),而不是链接的浏览器默认样式的蓝色
(2)重设所有属性值
CSS 的简写属性 all
可以用于同时将这些继承值中的一个应用于(几乎)所有属性。它的值可以是其中任意一个(inherit
、initial
、unset
或 revert
)。这是一种撤销对样式所做更改的简便方法,以便回到之前已知的起点
比如
blockquote {
background-color: orange;
border: 2px solid blue;
}
.fix-this {
all: unset;
}
<blockquote>
<p>This blockquote is styled</p>
</blockquote>
<blockquote class="fix-this">
<p>This blockquote is not styled</p>
</blockquote>
效果如下
2. 理解层叠
有三个因素需要考虑,根据重要性排序如下,后面的更重要:
- 资源顺序
- 优先级
- 重要程度
(1)资源顺序
当有超过一条规则,而且权重相同时,那最后面的规则会应用
(2)优先级
更具体范围更小,则优先级更高
比如: ID > 类 > 元素
(3)内联样式
内联样式,即 style
属性内的样式声明,优先于所有普通的样式,无论其优先级如何。这样的声明没有选择器,但它总是比其他任何优先级的权重都要高。
(4)!important
有一个特殊的 CSS !important
可以用来覆盖所有上面所有优先级计算,需要很小心的使用。用于修改特定属性的值,能够覆盖普通规则的层叠。
了解
!important
是为了在阅读别人代码的时候知道有什么作用。但是,强烈建议除了非常情况不要使用它
备注: 覆盖
!important
唯一的办法就是另一个!important
具有相同优先级而且顺序靠后,或者更高优先级。
3. CSS位置的影响
CSS 声明的优先级取决于定义它的样式表和级联层
相互冲突的声明将按以下顺序应用,后一种声明将覆盖前一种声明:
- 用户代理样式表中的声明(例如,浏览器的默认样式,在没有设置其他样式时使用)
- 用户样式表中的常规声明(由用户设置的自定义样式)
- 作者样式表中的常规声明(这些是我们 web 开发人员设置的样式)
- 作者样式表中的
!important
声明 - 用户样式表中的
!important
声明 - 用户代理样式表中的
!important
声明
备注: 标记为
!important
的样式的优先级顺序是颠倒的。web 开发人员的样式表覆盖用户的样式表是有意义的,因此设计可以按预期进行,但是有时用户有充足的理由覆盖 web 开发人员的样式,正如上面提到的——这可以通过在他们的规则中使用!important
来实现。
4. 级联层的顺序
(1)一行中声明时越靠后优先级越高
@layer bootstrap,base,application;
bootstrap < base < application
在上面的代码中,我们先是用@layer bootstrap,base,application声明了三个layer,这三个layer的优先级从低到高依次为:bootstrap 、 base 、 application。
bootstrap组件的样式优先级最低,方便我们修改部分组件样式,application层的优先又高于base,能对内容区块进行更细粒度的样式控制,这样就在样式设计之初,进行了一个管理规划。
layer间的优先级,比选择器优先级具有更高的权重
(2)非@layer层与@layer层的优先级
非 @layer层 > @layer层
非 @layer 包裹的样式,就算写在其他layer之前,也拥有比 @layer 包裹样式更高的优先级
比如
body {
background-color: bisque;
}
@layer A {
body {
background-color: red;
color: black;
}
}
@layer B {
body {
color: blue;
background-color: green;
}
}
会显示为第一个的 bisque
(3)匿名层
匿名层指的是不声明layer名的级联层,它在级联层中的优先级,取决于layer声明次序
@layer A {
body {
background-color: green;
}
}
@layer {
body {
background-color: red;
}
}
@layer B {
body {
background-color: bisque;
}
}
优先级从高到低为: B > 匿名 > A,所以最后生效的body背景色为 bisque
(4)嵌套层
外层 > 内层
div {
padding: 20px;
width: 300px;
height: 50px;
}
@layer A {
div {
background: blue;
}
@layer B {
div {
background: red;
}
}
}
@layer C {
div {
background: bisque;
}
@layer D {
div {
background: green;
}
}
}
优先级从高到低:@layer C > @layer C.D > @layer A > @layerA.B
函数
虽然大多数数值是相对简单的关键字或数值,但也有一些值是以函数的形式出现的
1. calc() 函数
允许在cs中进行简单的计算。
函数由函数名和括号组成,括号内是函数的值。计算的结果并不是可以事先计算并作为静态值输入的东西。
.box {
padding: 10px;
width: calc(90% - 30px);
background-color: rebeccapurple;
color: white;
}
2. transform 属性的相关函数
使用 transform 属性可以对元素进行旋转、缩放、平移、倾斜
translate(x,y)
:平移scale(x, y)
:缩放rotate(deg)
:旋转skew(deg, deg)
:倾斜
可以通过transform-origin
属性来改变基点
的位置,可以使用一个、两个或三个值来指定,其中每个值都表示一个偏移量。 没有明确定义的偏移将重置为其对应的初始值。
如果定义了两个或更多值并且没有值的关键字,或者唯一使用的关键字是center,则第一个值表示水平偏移量,第二个值表示垂直偏移量。
CSS3还有一些其他的函数
@规则
CSS 的 @rules
(读作“at-rules”)是一些特殊的规则,提供了关于 CSS 应该执行什么或如何表现的指令
例如@import
将一个样式表导入到另一个样式表
@import 'styles2.css'
还有比较常见的@media
,被用来创建媒体查询。媒体查询使用条件逻辑来应用 CSS 样式
在下面的例子中,样式表为 <body>
元素定义了一个默认的粉红色背景。然而,如果浏览器的视口宽于 30em,接下来的媒体查询则定义了蓝色背景。
body {
background-color: pink;
}
@media (min-width: 30em) {
body {
background-color: blue;
}
}
CSS工作流程
此处先忽略了 JavaScript
选择器
选择器列表
可以把多个使用相同样式的选择器组合起来称为选择器列表,如果每个选择器都另起一行会更好读一些
h1, .special {
color: blue;
}
需要注意,使用选择器列表时,任何一个选择器无效,那么整条规则都会被忽略
比如下面的类选择器语法错误,那么无论是 h1 还是这个 class 都不会被样式化
h1,
..special {
color: blue;
}
选择器的种类
1. 类型、类和 ID 选择器
h1 {}
.box {}
#unique {}
如果一个元素有多个类,想要仅仅在选择器中存在所有这些类的时候选择这一元素时。
比如下面的例子,有一个包含了一条笔记的<div>
。灰色的边框在盒子带有notebox
类的时候应用。如果它还有一个warning
或是danger
类,我们改变border-color。
为了告诉浏览器我们只想匹配带有所有这些类的元素,我们可以将这些类不加空格地连成一串。
.notebox {
border: 4px solid #666;
padding: .5em;
}
.notebox.warning {
border-color: orange;
font-weight: bold;
}
.notebox.danger {
border-color: red;
font-weight: bold;
}
<div class="notebox">
This is an informational note.
</div>
<div class="notebox warning">
This note shows a warning.
</div>
<div class="notebox danger">
This note shows danger!
</div>
<div class="danger">
This won't get styled — it also needs to have the notebox class
</div>
效果如下
2. 属性选择器
根据一个元素上某个标签的属性是否存在以选择元素的不同方式
a[title] {}
或者根据一个有特定值的标签属性是否存在来选择
a[href="https://example.com"] {}
(1)存否和值选择器
这些选择器允许基于一个元素自身是否存在(例如href
)或者基于各式不同的按属性值的匹配,来选取元素
(2)子字符串匹配选择器
这些选择器让更高级的属性的值的子字符串的匹配变得可行。
例如,如果你有box-warning
和box-error
类,想把开头为“box-”
字符串的每个物件都匹配上的话,你可以用[class^="box-"]
来把它们两个都选中。
(3)大小写敏感
默认是大小写敏感的,如果想要不敏感,可以在闭合括号之前使用i
e.g
li[class^="a" i] {
color: red;
}
3. 伪类与伪元素
(1)伪类
伪类是选择器的一种,它用于选择处于特定状态的元素,比如当它们是这一类型的第一个元素时,或者是当鼠标指针悬浮在元素上面的时候。
伪类就是开头为冒号:
的关键字。
例如:hover
伪类会在鼠标指针悬浮到一个元素上的时候选择这个元素
a:hover {}
(2)伪元素
伪元素以类似方式表现,不过表现得是像你往标记文本中加入全新的 HTML 元素一样,而不是向现有的元素上应用类。选择一个元素的某个部分而不是元素自己。
伪元素开头为双冒号::
例如::first-line
会选择一个元素(下面例子中是<p>
)中的第一行,类似<span>
包在了第一个被格式化的行外面,然后选择这个<span>
p::first-line { }
(3)把伪类和伪元素组合起来
比如想让第一段的第一行加粗,需要把:first-child
和::first-line
选择器放到一起
article p:first-child::first-line {
font-size: 120%;
font-weight: bold;
}
(4)生成带有::before 和::after 的内容
一组特别的伪元素,它们和content
属性一同使用,通过 CSS 将内容插入到文档中。分别把内容插入到前面和后面。
.box::before {
content: "This should show before the other content !!! ";
}
<p class="box">Content in the box in my HTML page.</p>
效果如下图
一般很少插入文本字符串;
可以插入一个图标, 比如小箭头;
或者插入空字符串再把它设为display: block
,这样就可以用width
和height
等进行样式化。
.box::before {
content: "";
display: block;
width: 100px;
height: 100px;
background-color: rebeccapurple;
border: 1px solid black;
}
<p class="box">Content in the box in my HTML page.</p>
效果如下
点击查看更多伪类和伪元素,请翻到页面最下方
4. 关系选择器
被命名为关系选择器(Combinator),这是因为它们在其他选择器之间和其他选择器与文档内容的位置之间建立了一种有用的关系的缘故。
(1)后代选择器
用单个空格" "
字符组合两个选择器。比如,第二个选择器匹配的元素被选择,如果他们有一个祖先(父亲,父亲的父亲,父亲的父亲的父亲,等等)元素匹配第一个选择器。选择器利用后代组合符被称作后代选择器。
body article p
在下面示例中,只会匹配处于带有.box
类的元素里面<p>
元素
.box p {
color: red;
}
<div class="box"><p>Text in .box</p></div>
<p>Text not in .box</p>
(2)子代关系选择器
子代关系选择器是个大于号>
,只会在选择器选中直接子元素的时候匹配。继承关系上更远的后代则不会匹配
例如,只选中作为<article>
的直接子元素的<p>
元素:
article > p {}
下个示例中,我们弄了个有序列表,内嵌于另一个无序列表里面。我用子代关系选择器,只选中为<ul>
的直接子元素的<li>
元素,给了它们一个顶端边框。
如果移去指定子代选择器的>
的话,最后得到的是后代选择器,所有的<li>
都会有个红色的边框。
ul > li {
border-top: 5px solid red;
}
<ul>
<li>Unordered item</li>
<li>Unordered item
<ol>
<li>Item 1</li>
<li>Item 2</li>
</ol>
</li>
</ul>
效果如下
(3)邻接兄弟
邻接兄弟选择器+
用来选中恰好处于另一个在继承关系上同级的元素旁边的物件。例如,选中所有紧随<p>
元素之后的<img>
元素
p + img
常见的使用场景是,改变紧跟着一个标题的段的某些表现方面,就像是下面的示例那样。这里我们寻找一个紧挨<h1>
的段,然后样式化它。
如果往<h1>
和<p>
之间插入其他的某个元素,例如<h2>
,将会发现段落不再与选择器匹配,因而不会应用元素邻接时的前景和背景色。
h1 + p {
font-weight: bold;
background-color: #333;
color: #fff;
padding: .5em;
}
<article>
<h1>A heading</h1>
<p>Veggies es bonus vobis, proinde vos postulo essum magis kohlrabi welsh onion daikon amaranth tatsoi tomatillo
melon azuki bean garlic.</p>
<p>Gumbo beet greens corn soko endive gumbo gourd. Parsley shallot courgette tatsoi pea sprouts fava bean collard
greens dandelion okra wakame tomato. Dandelion cucumber earthnut pea peanut soko zucchini.</p>
</article>
效果如下
(4)通用兄弟
如果想选中一个元素的兄弟元素,即使它们不直接相邻,还是可以使用通用兄弟关系选择器~
。要选中所有的<p>
元素后任何地方的<img>
元素,我们会这样做:
p ~ img
在下面的示例中,我们选中了所有的 <h1>
之后的<p>
元素,虽然文档中还有个 <div>
,其后的<p>
还是被选中了
h1 ~ p {
font-weight: bold;
background-color: #333;
color: #fff;
padding: .5em;
}
<article>
<h1>A heading</h1>
<p>I am a paragraph.</p>
<div>I am a div</div>
<p>I am another paragraph.</p>
</article>
效果如下
5. 全局选择器
由*
代指
* {
margin: 0;
}
如果想选中任何<article>
元素的第一子元素,不论它是什么元素都给它加粗
article *:first-child {}
使用选择器
多种选择器可以组合使用
比如如果我们想选中为<ul>
的直接子元素的带有“a”类的列表项的话,我可以用下面的代码。
ul > li[class="a"] { }
总结
只记录了 CSS 的部分内容