根据前端技能树补缺CSS知识
CSS基础
CSS语法
一门基于规则的语言
语法结构:
- 一个选择器开头
- 一对大括号
- 多个属性-值对的声明
@规则
供了关于 CSS 应该执行什么或如何表现的指令。有些@规则很简单,只有一个关键词和一个值。例如,@import
将一个样式表导入另一个 CSS 样式表:
1 | @import 'styles2.css'; |
可能遇到的一个常见的@规则是 @media
,它被用来创建媒体查询。媒体查询使用条件逻辑来应用 CSS 样式。
在下面的例子中,样式表为 <body>
元素定义了一个默认的粉红色背景。然而,如果浏览器的视口宽于 30em,接下来的媒体查询则定义了蓝色背景。
1 | body { |
CSS的如何运行
下面是浏览器加载网页的基本步骤(不同浏览器略有不同,但基本步骤都会包含):
- 浏览器载入HTML文件
- 将HTML转化为一个DOM(Document Object Model),DOM 是文件在计算机内存中的表现形式
- 浏览器拉取HTML相关资源,例如:图片、视频、CSS样式,稍后会处理JS
- 浏览器解析CSS,根据选择器类型分到不同的桶,浏览器通过这些桶找到不同的选择器,将不同的规则(基于选择器的规则,如元素选择器、类选择器、id 选择器等)应用到DOM节点中并添加节点依赖的样式(这个中间步骤称为渲染树)。
- 上述的规则应用于渲染树之后,渲染树会依照应该出现的结构进行布局。
- 网页展示在屏幕上(这一步被称为着色
DOM
一个DOM有一个树形结构,标记语言中的每一个元素、属性、以及每一段文字都对应着结构树中的一个节点(Node/DOM 或 DOM node)
当你使用浏览器 F12 调试的时候你需要操作 DOM 以查看使用了哪些规则
以下列 HTML 代码为例:
1 | <p> |
在这个 DOM 中,<p>
元素对应了父节点,它的子节点是一个 text 节点和三个对应了<span>
元素的节点,SPAN
节点同时也是他们中的 Text 节点的父节点。
1 | P |
CSS选择器
选择器列表
使用,
连接的多个选择器:
1 | h1, |
但是在被组合起来以后,如果其中一个选择器有语法错误,那么整个规则都会失效,无论是h1
还是这个 class 都不会被样式化。
选择器类型
类型选择器
1 | h1 { } |
全局选择器
1 | * { |
利用全局选择器我们可以使CSS代码更衣读,例如,如果想选中<article>
元素的第一个子元素加粗:
1 | article :first-child { |
但这一操作尝尝会与article:first-child
混淆,后者选择了作为其他元素的第一子元素的<article>
元素。
为了避免这种混淆,我们可以向:first-child
选择器加入全局选择器,这样选择器所做的事情很容易就能看懂。选择器正选中<article>
元素的任何第一子元素:
1 | article *:first-child { |
类(class)选择器
1 | .box { } |
此外我们还可以指向特定元素的类
1 | span.highlight { |
id选择器
1 | #unique { } |
标签属性选择器
这组选择器根据一个元素上的某个标签的属性的存在以选择元素的不同方式:
1 | a[title] { } |
或者根据一个有特定值的标签属性是否存在来选择:
1 | a[href="https://example.com"] { } |
存否和值选择器
选择器 | 示例 | 描述 |
---|---|---|
[*attr*] |
a[title] |
匹配带有一个名为attr的属性的元素——方括号里的值。 |
[*attr*=*value*] |
a[href="https://example.com"] |
匹配带有一个名为attr的属性的元素,其值正为value——引号中的字符串。 |
[*attr*~=*value*] |
p[class~="special"] |
匹配带有一个名为attr的属性的元素,其值正为value,或者匹配带有一个attr属性的元素,其值有一个或者更多,至少有一个和value匹配。注意,在一列中的好几个值,是用空格隔开的。 |
`[attr | =value]` | `div[lang |
子字符串匹配选择器
选择器 | 示例 | 描述 |
---|---|---|
[attr^=value] |
li[class^="box-"] |
匹配带有一个名为attr的属性的元素,其值开头为value子字符串。 |
[attr$=value] |
li[class$="-box"] |
匹配带有一个名为attr的属性的元素,其值结尾为value子字符串 |
[attr*=value] |
li[class*="box"] |
匹配带有一个名为attr的属性的元素,其值的字符串中的任何地方,至少出现了一次value子字符串。 |
大小写敏感
如果想在大小写不敏感的情况下,匹配属性值的话,你可以在闭合括号之前,使用i
值。
1 | li[class^="a" i] { |
伪类与伪元素
伪类
伪类是选择器的一种,它用于选择处于特定状态的元素,比如当它们是这一类型的第一个元素时,或者是当鼠标指针悬浮在元素上面的时候。它们表现得会像是你向你的文档的某个部分应用了一个类一样,帮你在你的标记文本中减少多余的类,让你的代码更灵活、更易于维护。
伪类就是开头为冒号的关键字:
1 | :pseudo-class-name |
用户行为伪类
一些伪类只会在用户以某种方式和文档交互的时候应用。这些用户行为伪类,有时叫做动态伪类,表现得就像是一个类在用户和元素交互的时候加到了元素上一样。案例包括:
:hover
:forcus
伪元素
伪元素以类似方式表现,不过表现得是像你往标记文本中加入全新的 HTML 元素一样,而不是向现有的元素上应用类。伪元素开头为双冒号::
。
1 | article p::first-line { |
备注: 一些早期的伪元素曾使用单冒号的语法,所以你可能会在代码或者示例中看到。现代的浏览器为了保持后向兼容,支持早期的带有单双冒号语法的伪元素。
伪类用于样式化一个元素的特定状态
1 | a:hover { } |
伪元素即选择一个元素的某个部分而不是元素自己,例如::first-line
将选择一个元素中的第一行
1 | p::first-line { } |
伪类和伪元素的组合
1 | article p:first-child::first-line { |
生成内容:::before
和::after
有一组特别的伪元素,它们和content
属性一同使用,使用 CSS 将内容插入到你的文档中中。
你能用这些插入一个文本字符串,和在下面的实时示例里那样。试着改变content
属性的文本值,看看输出是怎么改变的。你也能改变::before
伪元素为::after
,看到这段文本插入到了元素的末尾而不是开头。
还可以用来插入一些图形:
1 | .box::before { |
注意事项
使用CSS插入文本是不推荐的,以为对于一些屏幕阅读器来说,这些文本是不可见的,而且对于未来别人的查找和编辑也是不方便的,更多的是用来插入图标
伪类参考表
选择器 | 描述 |
---|---|
:active |
在用户激活(例如点击)元素的时候匹配。 |
:any-link |
匹配一个链接的:link 和:visited 状态。 |
:blank |
匹配空输入值的``元素。 |
:checked |
匹配处于选中状态的单选或者复选框。 |
:current (en-US) |
xxxxxxxxxx3 1input::placeholder {2 color: red3}css |
:default |
匹配一组相似的元素中默认的一个或者更多的 UI 元素。 |
:dir |
基于其方向性(HTMLdir 属性或者 CSSdirection 属性的值)匹配一个元素。 |
:disabled |
匹配处于关闭状态的用户界面元素 |
:empty |
匹配除了可能存在的空格外,没有子元素的元素。 |
:enabled |
匹配处于开启状态的用户界面元素。 |
:first |
匹配分页媒体的第一页。 |
:first-child |
匹配兄弟元素中的第一个元素。 |
:first-of-type |
匹配兄弟元素中第一个某种类型的元素。 |
:focus |
当一个元素有焦点的时候匹配。 |
:focus-visible |
当元素有焦点,且焦点对用户可见的时候匹配。 |
:focus-within |
匹配有焦点的元素,以及子代元素有焦点的元素。 |
:future (en-US) |
匹配当前元素之后的元素。 |
:hover |
当用户悬浮到一个元素之上的时候匹配。 |
:indeterminate |
匹配未定态值的 UI 元素,通常为复选框。 |
:in-range |
用一个区间匹配元素,当值处于区间之内时匹配。 |
:invalid |
匹配诸如<input> 的位于不可用状态的元素。 |
:lang |
基于语言(HTMLlang属性的值)匹配元素。 |
:last-child |
匹配兄弟元素中最末的那个元素。 |
:last-of-type |
匹配兄弟元素中最后一个某种类型的元素。 |
:left |
在分页媒体 (en-US)中,匹配左手边的页。 |
:link |
匹配未曾访问的链接。 |
:local-link (en-US) |
匹配指向和当前文档同一网站页面的链接。 |
:is() |
匹配传入的选择器列表中的任何选择器。 |
:not |
匹配作为值传入自身的选择器未匹配的物件。 |
:nth-child |
匹配一列兄弟元素中的元素——兄弟元素按照an+b形式的式子进行匹配(比如 2n+1 匹配元素 1、3、5、7 等。即所有的奇数个)。 |
:nth-of-type |
匹配某种类型的一列兄弟元素(比如,<p> 元素)——兄弟元素按照an+b形式的式子进行匹配(比如 2n+1 匹配元素 1、3、5、7 等。即所有的奇数个)。 |
:nth-last-child |
匹配一列兄弟元素,从后往前倒数。兄弟元素按照an+b形式的式子进行匹配(比如 2n+1 匹配按照顺序来的最后一个元素,然后往前两个,再往前两个,诸如此类。从后往前数的所有奇数个)。 |
:nth-last-of-type |
匹配某种类型的一列兄弟元素(比如,<p> 元素),从后往前倒数。兄弟元素按照an+b形式的式子进行匹配(比如 2n+1 匹配按照顺序来的最后一个元素,然后往前两个,再往前两个,诸如此类。从后往前数的所有奇数个)。 |
:only-child |
匹配没有兄弟元素的元素。 |
:only-of-type |
匹配兄弟元素中某类型仅有的元素。 |
:optional |
匹配不是必填的 form 元素。 |
:out-of-range |
按区间匹配元素,当值不在区间内的的时候匹配。 |
:past (en-US) |
匹配当前元素之前的元素。 |
:placeholder-shown |
匹配显示占位文字的 input 元素。 |
:playing |
匹配代表音频、视频或者相似的能“播放”或者“暂停”的资源的,且正在“播放”的元素。 |
:paused |
匹配代表音频、视频或者相似的能“播放”或者“暂停”的资源的,且正在“暂停”的元素。 |
:read-only |
匹配用户不可更改的元素。 |
:read-write |
匹配用户可更改的元素。 |
:required |
匹配必填的 form 元素。 |
:right |
在分页媒体 (en-US)中,匹配右手边的页。 |
:root |
匹配文档的根元素。 |
:scope |
匹配任何为参考点元素的的元素。 |
:valid |
匹配诸如<input> 元素的处于可用状态的元素。 |
:target |
匹配当前 URL 目标的元素(例如如果它有一个匹配当前URL 分段的元素)。 |
:visited |
匹配已访问链接。 |
伪元素参考
选择器 | 描述 |
---|---|
::after |
匹配出现在原有元素的实际内容之后的一个可样式化元素。 |
::before |
匹配出现在原有元素的实际内容之前的一个可样式化元素。 |
::first-letter |
匹配元素的第一个字母。 |
::first-line |
匹配包含此伪元素的元素的第一行。 |
::grammar-error |
匹配文档中包含了浏览器标记的语法错误的那部分。 |
::selection |
匹配文档中被选择的那部分。 |
::spelling-error |
匹配文档中包含了浏览器标记的拼写错误的那部分。 |
关系选择器
最后一组选择器可以将其他选择器组合起来,更复杂的选择元素。下面的示例用运算符(>
)选择了<article>
元素的初代子元素:
1 | article > p { } |
后代选择器
使用空格隔开:
1 | .box p { |
子代关系选择器
1 | article > p { } |
邻接兄弟选择器
邻接兄弟选择器(+
)用来选中恰好处于另一个在继承关系上同级的元素旁边的物件。例如,选中所有紧随<p>
元素之后的<img>
元素:
1 | h1 + p { |
通用兄弟
如果你想选中一个元素的兄弟元素,即使它们不直接相邻,你还是可以使用通用兄弟关系选择器(~
)。要选中所有的<p>
元素后任何地方的<img>
元素,我们会这样做:
1 | h1 ~ p { |
层叠与继承
层叠
当应用两条同级别的规则到一个元素的时候,写在后面的是实际使用的规则
例如如下两条规则,将会生效后面的蓝色规则:
1 | h1 { |
优先级
浏览器是根据优先级来决定当多个规则有不同选择器对应相同的元素的时候需要使用哪个规则。它基本上是一个衡量选择器具体选择哪些区域的尺度:
- 一个元素选择器不是很具体,则会选择页面上该类型的所有元素,所以它的优先级就会低一些。
- 一个类选择器稍微具体点,则会选择该页面中有特定
class
属性值的元素,所以它的优先级就要高一点。
继承
某些父元素上的CSS属性可以被子元素继承例如color
和font-family
是会被子元素继承的
再如width
是不可继承的
关于一个属性能否被继承,可以再MDN CSS属性参考页面查看,以 color 属性的形式定义部分为例。
CSS为控制继承提供了五个特殊的通用属性值。每个CSS属性都接收这些值
inherit
- 使子元素继承父元素
intial
- 使应用于选定元素的属性值设置为该属性的初始值
revert
- 将应用于选定元素的属性值重置为浏览器的默认样式,而不是应用于该属性的默认值。在许多情况下,此值的作用类似于
unset
。
- 将应用于选定元素的属性值重置为浏览器的默认样式,而不是应用于该属性的默认值。在许多情况下,此值的作用类似于
revert-layer
- 将应用于选定元素的属性值重置为在上一个层叠层中建立的值。
unset
- 将属性重置为自然值,也就是如果属性是自然继承那么就是
inherit
,否则和initial
一样
- 将属性重置为自然值,也就是如果属性是自然继承那么就是
重设所有属性值
CSS 的简写属性 all
可以用于同时将这些继承值中的一个应用于(几乎)所有属性。它的值可以是其中任意一个(inherit
、initial
、unset
或 revert
)。这是一种撤销对样式所做更改的简便方法,以便回到之前已知的起点。
下面的示例中有两个块级引用元素。第一个用元素本身的样式,第二个设置 all
为 unset
1 | blockquote { |
1 | <blockquote> |
理解层叠
需要理解层叠样式就需要考虑如下三个重点:
- 资源顺序
- 优先级
- 重要程度
资源顺序
资源顺序体现在:
优先级相同的样式,后面的规则将被应用
优先级
浏览器对于优先级的计算是,对不同类型的选择器给与不同的分数值,把这些分数相加就得到特定选择器的权重,然后进行匹配。
一个选择器优先级可以由三个不同的值(或分量)相加,可以认为是百(ID)- 十(类)- 个(元素)——三位数:
- ID:类选择器中包含ID选择器则百位得一分
- 类:选择器中包含类选择器、属性选择器或者伪类则十位得一分
- 元素:选择器中包含元素、伪元素选择器则个位得一分
注意事项:
否定(:not()
)和任意匹配(:is()
)伪类本身对优先级没有影响,但它们的参数则会带来影响。参数中,对优先级算法有贡献的参数的优先级的最大值将作为该伪类选择器的优先级。
选择器 | ID | 类 | 元素 | 优先级 |
---|---|---|---|---|
h1 |
0 | 0 | 1 | 0-0-1 |
h1 + p::first-letter |
0 | 0 | 3 | 0-0-3 |
li > a[href*="en-US"] > .inline-warning |
0 | 2 | 2 | 0-2-2 |
#identifier |
1 | 0 | 0 | 1-0-0 |
button:not(#mainBtn, .cta) |
1 | 0 | 1 | 1-0-1 |
内联样式
即style
属性内的样式,可以理解为优先级分数为1-0-0-0
,即无论如果内敛样式的优先级最高
!important
一个特殊的CSS用来覆盖上述所有优先级计算,但是建议除了非常情况不要使用
1 | .better { |
注意事项
覆盖
!important
唯一的办法就是另一个!important
具有相同优先级而且顺序靠后,或者更高优先级。
覆盖声明的顺序
相互冲突的声明将按以下顺序应用,后一种声明将覆盖前一种声明:
- 用户代理样式表中的声明(例如,浏览器的默认样式,在没有设置其他样式时使用)。
- 用户样式表中的常规声明(由用户设置的自定义样式)。
- 作者样式表中的常规声明(这些是我们 web 开发人员设置的样式)。
- 作者样式表中的
!important
声明 - 用户样式表中的
!important
声明 - 用户代理样式表中的
!important
声明
级联层的顺序
尽管级联层属于高级的主题,你可能不会立刻使用此特性,但了解层是如何级联的非常重要。
在级联层中声明 CSS 是,优先级的顺序由声明层的顺序来决定。在任何层之外声明的 CSS 样式会被按声明的顺序组合在一起,形成一个未命名的层,它会被当作最后声明的层。对于存在冲突的常规(没有 !important
声明)样式,后面的层比先前定义的层的优先级高。但对于带有 !important
标记的样式,其顺序相反——先前的层中的 important 样式比后面的层以及为在层中声明的 important 样式优先级要高。但内联样式比所有作者定义的样式的优先级都要高,不受级联层规则的影响。
当你在不同的层中有多个样式块,且其中提供了对于某一元素的单一属性的相互冲突的值时,声明该冲突样式的层的顺序将决定其优先级。而不是高优先级的层直接覆盖低优先级的层中的所有样式。需要注意的是单独的一个层中的样式的优先级仍旧会起作用。
1 | @layer firstLayer, secondLayer; |
盒模型
CSS将HTML中的元素视为一个个盒子(box),CSS中广泛使用的两种盒子有:
- 块级盒子(block box)
- 内联盒子(inline box)
这两种盒子的表现会有所区别
块级盒子
块级盒子会表现如下特征:
- 盒子会在内联的方向上扩展,并占据父容器在该方向的所有空间
- 通常情况下盒子会与父容器一样宽
- 每个盒子独占一行
width
和height
会起作用padding
、margin
、border
会将其他元素推开
默认状态下为块级盒子的标签有<p>
、<h1>
内联盒子
内联盒子会表现如下特征:
- 盒子不会产生换行
width
和height
不起作用- 垂直方向的的内边距和外边距会被应用,但不会把其他处于
inline
状态的盒子推开 - 水平方向的内边距和外边距会被应用且会把其他处于
inline
状态的盒子推开
用做链接的 <a>
元素、 <span>
、 <em>
以及 <strong>
都是默认处于 inline
状态的。
可以通过属性display
切换inline
和block
的状态
内部和外部显示类型
盒子除了外部显示类型,还有内部显示类型。
内部显示类型决定了盒子内部元素是如何布局的,默认情况下按照正常文档流
布局,即与其它内联以及快元素一样
此外,还可以通过display: flex
将内部元素变为flex元素,此时外部显示类型为block
,内部显示类型为felx
除了flex
还有grid
inline-flex
会将内部类型设置为flex
的同时将外部类型设置为inline
块级和内联布局是 web 上默认的行为 —— 正如上面所述,它有时候被称为 正常文档流
什么是盒模型
完整的CSS和模型应用于块级盒子,内联盒子只使用和模型中定义的部分内容。
盒的各个部分
- Content box:用于显示内容的区域,大小可以通过
width
和height
来设置 - Padding box:包围在内容外部的空白区域,大小可以通过
padding
相关属性设置 - Border box:边框包裹内容和内边距。大小通过
border
来设置 - Margin box:最外层区域,与其他盒子之间的空白区域,大小通过
margin
设置
标准盒模型
我们尝试给一个盒模型设置width, border, padding, margin
:
1 | .box { |
那么这个盒子的实际宽高分别是:
- 宽度 = (350 + 25 * 2 + 5 * 2) = 410px
- 高度 = (150 + 25 * 2 + 5 * 2) = 210px
注意事项:
margin不计入实际大小,它会影响盒子在页面所占空间,但是影响的是盒子外部空间。盒子的范围到边框为止 —— 不会延伸到 margin。
替代(IE)盒模型
为了避免盒子大小不够直观(即计算实际宽度时还需要加上边框和内边距)CSS还提供了替代盒模型。该模型认为设置的宽度即为所有可见宽度
使用相同的配置:
1 | .box { |
得到的宽高为:
- 宽 = 350px
- 高 = 150px
这一选项通过设置box-sizing
属性得到:
1 | .box { |
如果希望所有模型都为替代盒模型,可以通过如下配置实现
1 | html { |
备注: 一个有趣的历史记录 ——Internet Explorer 默认使用替代盒模型,没有可用的机制来切换。(译者注:IE8+ 支持使用
box-sizing
进行切换)
margin,border,padding
margin,border,padding三者是属性的简写,允许我们一次性控制盒子的四个边
margin
margin用来推开盒子周围的元素,它总是在计算可见部分后额外添加的,包含以下四个单独控制的属性
margin可以接受负数,这样会使得其他元素与该盒子重叠
margin折叠
有时候当两个相邻盒子都设置了margin时,会发生与直觉不相符的情况。
原因时margin属性存在折叠的特性:
两个外边距相接的元素,两个外边距将会合并为一个外边距,即量大的单个外边距的大小
如果我们有下面的一段HTML
1 | <div class="container"> |
接下来我们为两个p
标签设置宽高
1 | .one { |
此时两个p标签之间的上下间隔为50px,而不是我们直觉的50+30=80px
下面给出边距折叠的定义
块的上外边距 (margin-top)和下外边距 (margin-bottom)有时合并 (折叠) 为单个边距,其大小为单个边距的最大值 (或如果它们相等,则仅为其中一个),这种行为称为边距折叠。
margin折叠的情况有如下几种:
同一层相邻元素之间
相邻的两个元素之间的外边距重叠,除非后一个元素加上clear-fix 清除浮动。
1 | <style> |
没有内容将父元素和后代元素分开
发生于父元素与其后代元素之间
- 如果没有边框
border
,内边距padding
,行内内容,也没有创建块级格式上下文或清除浮动来分开一个块级元素的上边界margin-top
与其内一个或多个后代块级元素的上边界margin-top
- 或没有边框,内边距,行内内容,高度
height
,最小高度min-height
或 最大高度max-height
来分开一个块级元素的下边界margin-bottom
与其内的一个或多个后代后代块元素的下边界margin-bottom
则就会出现父块元素和其内后代块元素外边界重叠,重叠部分最终会溢出到父级块元素外面。
如下面的例子
1 | <style type="text/css"> |
其中header的上边界87px高于selction的13px,于是超出了父元素section(阴影部分),并与父元素的上边界发生了重叠。使得sectiond到页面顶点的实际距离达到了87px
同时footer的下边界与父元素section的下边界也发生了堆叠,导致下边界到section底部的实际距离为0
空的块元素
当一个块元素上边界margin-top
直接贴到元素下边界margin-bottom
时也会发生边界折叠。
这种情况会发生在一个空的块元素完全没有设定边框border
、内边距padding
、高度height
、最小高度min-height
、最大高度max-height
、内容设定为 inline 或是加上clear-fix的时候。
1 | <style> |
注意事项:
- 上述情况的组合会产生更复杂的外边距折叠。
- 即使某一外边距为 0,这些规则仍然适用。因此就算父元素的外边距是 0,第一个或最后一个子元素的外边距仍然会“溢出”到父元素的外面。
- 如果参与折叠的外边距中包含负值,折叠后的外边距的值为最大的正边距与最小的负边距(即绝对值最大的负边距)的和,;也就是说如果有 -13px 8px 100px 叠在一起,边界范围的技术就是 100px -13px 的 87px。
- 如果所有参与折叠的外边距都为负,折叠后的外边距的值为最小的负边距的值。这一规则适用于相邻元素和嵌套元素。
border
在标准盒模型中,边框大小将会被添加到盒子的高宽计算中
在替代盒模型中,边框会使得盒子的内容区域变小
边框属性可以设置:
- 宽高
- 颜色
- 样式
padding
内边距无法设置为负数,应用于元素的任何背景都将显示在内边距后面
盒子模型与内联盒子
以上属性还可以应用在内联盒子,但:
- 宽度喝高度会被忽略
- 边框和内边距会生效,但是不会改变其他内容与内联盒子的关系
- 外边距将在水平距离生效
1 | <style> |
inline-block
display
属性有一个特殊的值inline-block
提供了一个处于块与内联之间的状态
一个inline-block
元素具有以下特性:
width
和height
可以生效padding,margin
,以及border
会推开其他元素
但并不会独占一行。
依然是上面的例子,可以看出inline-block
的区别
1 | <style> |
这种元素通常被用在导航栏中,为了让使用flexbox显示的一行a标签能够根据鼠标的停留更改背景颜色,我们需要让他有比内部文字更大的大小:
1 | <style> |
总结
元素模式 | 元素排列 | 设置样式 | 默认宽度 | 包含 |
---|---|---|---|---|
块级元素 | 一行只能放一个块级元素 | 可以设置宽度和高度 | 容器的100% | 可以包含任意元素,p无法包含div |
行内元素 | 一行可以放多个行内元素 | 不可直接设置宽高 | 本身内容的宽度 | 可包含文本,或其他行内元素 |
行内块元素 | 一行可以放多个行内元素 | 可以设置宽度和高度 | 本身内容的宽度 |
背景
颜色
background-color
图像
background-image
当使用比盒子大的图片作为背景时,默认会从图片的左上角开始渲染,且仅渲染盒子范围的图片范围。
当使用比盒子小的图片作为背景时,默认会让图片复制铺满整个盒子。
可以通过background-repeat
来控制图像的平铺行为
no-repeat
——阻止背景重复平铺。repeat-x
——仅水平方向上重复平铺。repeat-y
——仅垂直方向上重复平铺。repeat
——默认值,在水平和垂直两个方向重复平铺。
还可以通过background-size
来设置背景图片的大小,值可以是长度或百分比。
此外还可以使用两个关键字值:
cover
:浏览器将使图像足够大,使它完全覆盖了盒子区域,同时仍然保持其宽高比。在这种情况下,图像的部分区域可能会跳出盒子外。contain
:浏览器会将图像调整到适合框内的尺寸。在这种情况下,如果图像的长宽比与盒子的长宽比不同,会在图像的两边或顶部和底部出现空隙。
背景定位
background-position
属性允许你选择背景图片出现在它所应用的盒子上的位置。这使用了一个坐标系统,其中方框的左上角是 (0,0)
,方框沿水平(x
)和垂直(y
)轴定位。
该属性可以接受长度和百分比作为值
同时也接受关键字:
- top
- right
- center
- …
还支持使用四值语法来指示到盒子的某些边的距离
1 | .box { |
长度单位是相对于其前面的值的偏移量。
备注:
background-position
是background-position-x
和background-position-y
的简写,它们允许用户分别设置不同的坐标轴的值。
渐变背景
使用渐变的一个有趣的方法是使用网络上许多 CSS 渐变生成器中的一个,比如这个。
可以像图片一样进行设置,但需要使用linear-gradient()
函数来实现,例如:
1 | .a { |
多背景图片
也可以有多个背景图像——在单个属性值中指定多个 background-image
值,用逗号分隔每个值。
这样做会出现背景图片相互重叠的情况。背景将分层,最后列出的背景图片位于最下层,而之前的每张图片都堆在代码中紧随其后的那张图片之上。
其他 background-*
属性也可以像 background-image
一样使用逗号分隔的方式设置:
1 | background-image: url(image1.png), url(image2.png),url(image3.png),url(image4.png); |
不同属性的每个值,将与其他属性中相同位置的值匹配。
但当数量无法匹配时,较小数量的值会循环匹配
即如果有四张图片,但是位置只有两个值的话,前两个图片会引用这两个位置值的属性,然后image3会应用position1,image3会引用position2,以此循环
背景附加
background-attachment
属性控制滑动时背景的呈现方式,取值有:
scroll
:使元素的背景在页面滚动时滚动。如果滚动了元素内容,则背景不会移动。实际上,背景被固定在页面的相同位置,所以它会随着页面的滚动而滚动。fixed
:使元素的背景固定在视口上,这样当页面或元素内容滚动时,它就不会滚动。它将始终保持在屏幕上相同的位置。local
:将背景固定在它所设置的元素上,所以当你滚动该元素时,背景也随之滚动。
background简写属性
使用单个background
进行控制时需要注意以下规则:
background-color
只能在最后一个逗号之后指定。background-size
值只能立即包含在background-position
之后,用“/”字符分隔,例如:center/80%
。
1 | .box { |
边框
我们可以利用border来配合构建一些更有意思的边框:
1 | <style> |
文本
文本方向
可以使用writing-mode: vertical-rl
对文本的显示进行设置
该属性有三个取值:
horizontal-tb
:块流向从上至下。对应为横向文本vertical-rl
:块流向从右向左。对应文本为纵向vertical-lr
:块流向从左向右。对应的文为纵向
书写模式与块、内联布局
块级显示和内联显示与文本的书写模式密切相关
例如,如果使用书写模式的显示是横向的,如英文,那么块在页面上的显示就是从上到下的
1 | .horizontal { |
当我们修改书写模式时,也在改变块和内联文本的方向。
例如上述代码中:
horizontal-tb
块的方向是从上到下的横向。vertical-rl
块的方向是从右到左的纵向。
即:
块维度指的是块在页面书写模式下的显示方向
内联维度指的是文本方向
逻辑属性和逻辑值
对于上述的两个盒子,如果我们给这两个盒子设定宽度。
1 | .box { |
当盒子处于纵向书写模式下时,宽度也发生了变化,从而导致文本超出了盒子的范围。
因此CSS使用了一套尺寸映射的属性:
width
被称作内联尺寸inline-size
height
被称作内联尺寸block-size
上述代码使用inline-size
代替width
后box将会随内容宽度变化
逻辑外边距、边框和内边距属性
除了width
和height
外,margin,padding,border
等等也都有相应的映射,例如:
margin-top
映射到margin-block-start
,总是指向块级维度开始处的边距padding-left
映射到padding-inline-start
,应用到内联开始方向上的内边距border-bottom
映射到border-block-end
,引用到块级维度结尾处的边框
逻辑值
除了上述这些物理属性有逻辑属性的对应外
类似:
top
——block-start
right
——inline-end
bottom
——block-end
left
——inline-start
如何使用
逻辑属性是在物理属性之后出现的,因而最近才开始在浏览器中应用。你可以通过查看 MDN 的属性页面来了解浏览器对逻辑属性的支持情况。如果你并没有应用多种书写模式,那么现在你可能更倾向于使用物理属性,因为这些在你使用弹性布局和网格布局时非常有用。
溢出处理
由于CSS的万物皆盒的设计理念,遇到盒子无法装下其中的内容时,溢出就会发生,CSS对这些现象也有自己的处理
CSS尽力减少“数据损失”
即默认情况下,CSS对于溢出的内容采用直接显示的策略:
1 | <style> |
OverFlow属性
用于控制溢出内容的显示方式,默认取值为visible
即即使发生溢出了一样会将内容显示出来。
可用取值如下:
visible
直接显示hidden
隐藏溢出内容scroll
允许滑动以保证完全显示(无论何时都会显示滚动条)- 可以使用
overflow-x,overflow-y
两个属性控制滑动的方向
- 可以使用
auto
当内容发生溢出时才显示滚动条
溢出建立了块级排版上下文
CSS 中有所谓块级排版上下文(Block Formatting Context,BFC)的概念。
此处不过多介绍,在使用诸如scroll
或者auto
的时候,就建立了一个块级排版上下文。
结果就是,改变了overflow
的值的话,对应的盒子就变成了更加小巧的状态。在容器之外的东西没法混进容器内,也没有东西可以突出盒子,进入周围的版面。激活了滚动动作,你的盒子里面所有的内容会被收纳,而且不会遮到页面上其他的物件。
CSS值与单位
数字长度、百分比
数值类型
数值类型 | 描述 |
---|---|
<integer> |
<integer> 是一个整数,比如 1024 或 -55 。 |
<number> |
<number> 表示一个小数——它可能有小数点后面的部分,也可能没有,例如 0.255 、128 或 -1.2 。 |
<dimension> |
<dimension> 是一个 <number> 它有一个附加的单位,例如 45deg 、5s 或 10px 。<dimension> 是一个伞形类别,包括 <length> 、<angle> 、<time> 和 <resolution> 类型。 |
<percentage> |
<percentage> 表示一些其他值的一部分,例如 50% 。百分比值总是相对于另一个量。例如,一个元素的长度相对于其父元素的长度。 |
长度
最常见的数字类型是 <length>
例如 10px
(像素)或 30em
。CSS 中有两种类型的长度——相对长度和绝对长度。
绝对长度单位
绝对长度与任何东西都没有关系,通常认为总是相同的大小
单位 | 名称 | 等价换算 |
---|---|---|
cm |
厘米 | 1cm = 37.8px = 25.2/64in |
mm |
毫米 | 1mm = 1/10th of 1cm |
Q |
四分之一毫米 | 1Q = 1/40th of 1cm |
in |
英寸 | 1in = 2.54cm = 96px |
pc |
派卡 | 1pc = 1/6th of 1in |
pt |
点 | 1pt = 1/72th of 1in |
px |
像素 | 1px = 1/96th of 1in |
相对长度单位
单位 | 相对于 |
---|---|
em |
在 font-size 中使用是相对于父元素的字体大小,在其他属性中使用是相对于自身的字体大小,如 width 。 |
ex |
字符“x”的高度。 |
ch |
数字“0”的宽度。 |
rem |
根元素的字体大小。 |
lh |
元素的行高。 |
rlh |
根元素的行高。当用于根元素的 font-size 或 line-height 属性时,它指的是这些属性的初始值。 |
vw |
视口宽度的 1%。 |
vh |
视口高度的 1%。 |
vmin |
视口较小尺寸的 1%。 |
vmax |
视口大尺寸的 1%。 |
vb |
在根元素的块向上,初始包含块的尺寸的 1%。 |
vi |
在根元素的行向上,初始包含块的尺寸的 1%。 |
svw 、svh |
分别为视口较小尺寸的宽度和高度的 1%。 |
lvw 、lvh |
分别为视口大尺寸的宽度和高度的 1%。 |
dvw 、dvh |
分别为动态视口的宽度和高度的 1%。 |
其中em
和rem
的差别在于前者是依据父元素的字体大小,而后者是依据根节点的字体大小
因此,如果我们定义一组嵌套li
元素的字体为1.3em
时,字体会逐渐变大:
1 | <style> |
当我们使用百分比作为值的时候
如果将元素的字体大小设置为百分比,那么它将是元素父元素字体大小的百分比。如果使用百分比作为宽度值,那么它将是父值宽度的百分比。
颜色
颜色允许接受许多值,例如:
- 颜色关键字
- 十六进制RGB值
- RGB和RGBA值
- HSL和HSLA值
备注: 在颜色上设置 alpha 通道与使用
opacity
属性有一个关键区别: 当使用opacity
时,能让元素和它里面的所有东西都不透明,而使用 RGB 与 alpha 参数的颜色只让指定的颜色不透明。
HSL值的方式与RGB略有不同,它使用以下三个通道来定义颜色:
- 色调:0-360,表示色轮中不同角度的值color wheel (en-US)
- 饱和度:百分比,0 为无颜色(它将显示为灰色阴影),100% 为全色饱和度
- 亮度:百分比,其中 0 表示没有光(它将完全显示为黑色),100% 表示完全亮(它将完全显示为白色)
HSLA中的A仍然表示不透明度,与RGBA中的相同
图片
可以通过url()
指向实际文件,也可以接受一个渐变函数返回的值
位置
可以使用关键字(如 top
、left
、bottom
、right
以及 center
)将元素与 2D 框的特定边界对齐,以及表示框的顶部和左侧边缘偏移量的长度。
字符串和标识符
例如使用:after,:before
这些生成内容时,即可以使用CSS字符串来定义生成的内容
字符串使用“”
来与关键字进行区分
CSS中调整大小
这里特别指出使用百分比作为margin,padding
的值
1 | <style> |
给了里面的盒子 10% 的 margin
以及 10% 的 padding
。盒子底部和顶部的内外边距,和左右外边距有同样的大小。
或许,你期望元素的上下外边距是其高度的百分比,元素的左右外边距是其宽度的百分比。但情况并非如此!
使用百分比作为元素外边距(margin)或填充(padding)的单位时,值是以包含块的**内联尺寸inline-size
**进行计算的,也就是元素的水平宽度
min-,max-尺寸
除了运用这两个属性避免盒子过大或者过小无法显示左右内容
max-width
的常见用法为,在没有足够空间以原有宽度展示图像时,让图像缩小,同时确保它们不会比这一宽度大。
即让图像根据盒子大小进行缩放,但不会超过图片原有大小:
1 | <style> |
这个技术是用来让图片可响应的
视口单位
单位vh,vw
根据视口来定义需要显示的百分比,视口大小的变化也会让它们的大小变化
视口,被认为是浏览器显示网页窗口时的大小
组织CSS
如何组织自己的CSS,让它更易于维护也是一个很重要的事情,通常具有以下几个注意事项:
- 将CSS格式化为易读的形式
- 为CSS加注释
- 在CSS中加入逻辑段落
- 避免太特定的选择器
- 将大样式表分成几个小样式表
此外还有一些辅助便携的工具,例如面对对象CSS即OOCSS
核心思想是尽量将共同的属性设置抽离为一个新的类。
例如:
1 | .comment { |
其中.comment
和.list-item
基本相同除了.list-item
具有一个底边,那么我们可以将相同的属性抽离为一个新的类
1 | .media { |
BEM命名规则
BEM即指Block,Element,Modifier;块、元素、修饰符
B
功能独立的页面元素(或简单或复杂)被视作一个块,它的 CSS 类名具有唯一性,块的特点:
- 块的命名用来描述这个块的用途
- 块不应影响它自身所处的环境,意味着不应为块设置外置的几何(margin)或者位置属性
- 不要使用 CSS 标签选择器 和 ID 选择器
块的使用规则:
- 块之间可以相互嵌套
- 可以使用任意多的嵌套层级
E
元素则是块的组成部分,无法脱离块单独使用
元素的特点:
- 元素的命名用来描述这个元素的用途
- 元素的整个命名结构是
block-name__element-name
元素使用规则:
- 元素之间可以相互嵌套
可以使用任意多的嵌套层级
一个元素应始终是其块的组成部分,而不是其他元素的。这意味着元素命名不应被定义成类似层级如
block__elm1__elm2
M
修饰符用来定义元素和块的外观、状态或者行为
修饰符的特点如下:
- 修饰符的命名用来描述:
- 外观:
size_s
,theme_islands
- 状态:
disabled
,focused
- 行为:
directions-left-top
- 外观:
- 用单下划线 _ 来分割修饰符与块或元素的命名
- 当修饰符的存在与否起主要影响时使用 Boolean 类型
- 命名遵循如下形式:
blockName--modifierName
blockName__elementName--modifierName
即__
表示下级元素
--
表示修饰状态
具体例子如下:
1 | .overview {} /* 块 */ |
其他体系
此外还有一些体系例如:
- SMACSS:Scalable and Modular Architecture for CSS (SMACSS)
- ITCSS:ITCSS
- 原本Yahoo创造的ACSS:Atomic CSS (ACSS)
CSS的构建体系
而偶尔为了更程序化地编写CSS,较为流行的工具有Sass
可以很方便的提供一些预处理和后处理
此外还有一些可以对CSS进行后处理的工具,例如cssnano,可以将CSS文件中的额外的注释和空格去掉来优化CSS
Emmet语法
用于Html和css的代码快速生成:
html:
语法 | 效果 |
---|---|
div |
生成<div></div> |
div*3 |
生成3对标签 |
ul > li |
生成2对父子关系标签 |
div+p |
生成2对兄弟关系标签 |
div.demo 或div#two |
生成带有类名或id名的标签 |
div.demo$*5 |
生成5对类名为demo1、demo2、…、demo5的序号自动排序标签 |
div{我是内容} |
生成有内容的div |
css:
使用属性首字母缩写+内容即可生成css代码,例如:
ti2em
即可生成text-indent:2em
CSS书写顺序
建议遵循以下顺序书写:
- 布局定位属性
display/position/float/clear/visibility/overflow
(建议display第一个写,关系到盒子模式 - 自身属性
width/height/margin/padding/border/background
- 文字书写
color/font/text-decoration/text-align/vertical-align/white-space/break-word
- 其他属性(CSS3)
content/cursor/border-radius/box-shadow/text-shadow/background:linear-gradient...
页面布局准则
- 通过测量确定页面的版心(可视区域,内容区域宽度)
- 页面布局第一准则:分析行模块以及每个行模块中的列模块。即多个块级元素纵向排列使用标准流,多个跨级元素横向排列使用浮动流
- 页面布局第二准则:一行中的列模块经常浮动布局,先确定每个列的大小,之后确定列的位置
- 制作HTML结构。先结构后样式
样式化文本
基本文本和字体样式
用于样式文本的CSS属性通常可以分为两类:
- 字体样式:用于字体的属性,会直接应用到文本中,比如:
- 字体
- 字体大小
- 字体粗细
- 是否倾斜
- 文本布局风格:作用于文本的间距以及其他布局功能的属性,比如:
- 行于字之间的空间
- 内容框中文本如何对齐
注意事项:
无法将文本中一部分选中或添加样式,如果想要这么做,需要使用或等标签将其包裹,或者使用伪元,比如
::first-letter
,::first-line
或者::selection
(当前光标双击选中的内容)
字体
颜色可以直接使用color
属性设置,color
属性设置的内容是元素的前景内容的颜色(前景通常是文本,但也包含一些其他东西),或者使用text-decoration
属性放置在文本下方或上方的线 (underline overline)。
1 | p { |
字体种类
css允许使用font-family
属性设置字体,但浏览器只会将当前机器上可用的字体引用到元素上,如果指定字体不可用,则会使用默认字体替代。
1 | p { |
所以诞生了一些可以毫无顾忌的使用的,可以应用到所有系统的字体,被称为网页安全字体:
字体名称 | 泛型 | 注意 |
Arial | sans-serif | 通常认为最佳做法还是添加 Helvetica 作为 Arial 的首选替代品,尽管它们的字体面几乎相同,但 Helvetica 被认为具有更好的形状,即使 Arial 更广泛地可用。 |
Courier New | monospace | 某些操作系统有一个 Courier New 字体的替代(可能较旧的)版本叫 Courier。使用 Courier New 作为 Courier 的首选替代方案,被认为是最佳做法。 |
Georgia | serif | |
Times New Roman | serif | 某些操作系统有一个 Times New Roman 字体的替代(可能较旧的)版本叫 Times。使用 Times 作为 Times New Roman 的首选替代方案,被认为是最佳做法。 |
Trebuchet MS | sans-serif | 您应该小心使用这种字体——它在移动操作系统上并不广泛。 |
Verdana | sans-serif |
备注: 在各种资源中,cssfontstack.com 网站维护了一个可用在 Windows 和 Mac 操作系统上使用的网页安全字体的列表,这可以帮助决策网站的安全性。
默认字体
CSS 定义了 5 个常用的字体名称:
serif
sans-serif
monospace
cursive
fantasy
这些都是非常通用的,当使用这些通用名称时,使用的字体完全取决于每个浏览器,而且它们所运行的每个操作系统也会有所不同。
浏览器会尽力提供一个看上去合适的字体。 serif
, sans-serif
和 monospace
是比较好预测的,默认的情况应该比较合理,另一方面,cursive
和 fantasy
是不太好预测的,建议使用的时候注意。
名称 | 定义 | 示例 |
---|---|---|
serif |
衬线字体,即有衬线的字体(衬线是指字体笔画尾端的小装饰,存在于某些印刷体字体中)。 | |
sans-serif |
无衬线字体。 | |
monospace |
等宽字体,指包含的全部字符的宽度相同的字体,通常在编辑代码时使用。 | |
cursive |
手写字体,对于英文字符而言通常具有顺滑的连接笔画以模拟手写效果。 | |
fantasy |
装饰字体。 |
字体栈
由于无法保证你想在你的网页上使用的字体的可用性,可以提供一个字体栈 (font stack)
1 | p { |
字体大小
字体可以取大多数上文提到的单位值,甚至百分比值,然而调整大小最常用的单位是:
- px:绝对单位,在任何情况下计算出来的像素值都一样
- em:相对单位,
1em
等于当前元素的父元素上设置的字体大小,使用em会使得网站维护更简单 - rem:相对单位,
1rem
等于HTML中根元素的字体大小,不支持IE8以下不支持
文本样式
CSS提供了4种常用属性来定义文本样子:
font-style
: 用来打开和关闭文本 italic (斜体):normal
: 将文本设置为普通字体 (将存在的斜体关闭)italic
: 如果当前字体的斜体版本可用,那么文本设置为斜体版本;如果不可用,那么会利用 oblique 状态来模拟 italics。oblique
: 将文本设置为斜体字体的模拟版本,也就是将普通文本倾斜的样式应用到文本中。
font-weight
: 设置文字的粗体大小。这里有很多值可选 (比如-light,-normal,-bold,-extrabold,-black, 等等), 不过事实上除了normal
和bold
以外,很少会用到,可取值如下:normal
,bold
: 普通或者加粗的字体粗细lighter
,bolder
: 将当前元素的粗体设置为比其父元素粗体更细或更粗一点。100
–900
: 数值粗体值,如果需要,可提供比上述关键字更精细的粒度控制。
text-transform
: 允许你设置要转换的字体。值包括:none
: 防止任何转型。uppercase
: 将所有文本转为大写。lowercase
: 将所有文本转为小写。capitalize
: 转换所有单词让其首字母大写。full-width
: 将所有字形转换成全角,即固定宽度的正方形,类似于等宽字体,允许拉丁字符和亚洲语言字形(如中文,日文,韩文)对齐。
text-decoration
: 设置/取消字体上的文本装饰 (你将主要使用此方法在设置链接时取消设置链接上的默认下划线。) 可用值为:none
: 取消已经存在的任何文本装饰。underline
: 文本下划线。overline
: 文本上划线line-through
: 穿过文本的线。
注意到
text-decoration
可以一次接受多个值,如果想要同时添加多个装饰值,比如1
text-decoration: underline overline
同时注意
text-decoration
是一个缩写形式,它由text-decoration-line
,text-decoration-style
和text-decoration-color
构成。可以使用这些属性值的组合来创建有趣的效果,比如1
text-decoration: line-through red wavy
文字阴影
可以使用text-shadow
属性为文字添加阴影,最多需要4个值:
1 | text-shadow: 4px 4px 5px red; |
每个属性的代表的含义如下:
- 阴影与原始文本的水平偏移,可以使用大多数的 CSS 单位 length and size units, 但是 px 是比较合适的。这个值必须指定。
- 阴影与原始文本的垂直偏移;效果基本上就像水平偏移,除了它向上/向下移动阴影,而不是左/右。这个值必须指定。
- 模糊半径 - 更高的值意味着阴影分散得更广泛。如果不包含此值,则默认为 0,这意味着没有模糊。可以使用大多数的 CSS 单位 length and size units.
- 阴影的基础颜色,可以使用大多数的 CSS 颜色单位 CSS color unit. 如果没有指定,默认为
black
。
备注: 正偏移值可以向右移动阴影,但也可以使用负偏移值来左右移动阴影,例如
-1px -1px
.
多种阴影
多影音可以使用逗号分隔:
1 | text-shadow: -1px -1px 1px #aaa, |
文字布局
使用text-align
属性可以控制文本如何和它所在的盒子内对其:
left
:左对齐right
:右对齐center
:居中对齐justify
:使文本展开,改变单词之间的间距,使所有文本行的宽度相同。如果需要使用这个值,则通常需要考虑
行高
使用line-height
可以设置行高,可以接受大多数单位 length and size units
不过也可以设置一个无单位值作为乘数,使用无单位的值乘以fony-size
来获得line-height
。推荐的行高大约是1.5-2(双倍间距
行高种的数值表示 = 上间距 + 文本高度 + 下间距
- 当行高设置为和字体等高时,字体上下将不会存在空隙
- 行高 > 字体高度时,行高 - 字体高度 / 2即为上间距和下间距的值
字母和单词间距
letter-spacing
和 word-spacing
属性允许设置文本中的字母与字母之间的间距、或是单词与单词之间的间距。
1 | p::first-line { |
其他一些属性值
Font样式:
font-variant
: 在小型大写字母和普通文本选项之间切换。font-kerning
: 开启或关闭字体间距选项。font-feature-settings
: 开启或关闭不同的 OpenType 字体特性。font-variant-alternates
: 控制给定的自定义字体的替代字形的使用。font-variant-caps
: 控制大写字母替代字形的使用。font-variant-east-asian
(en-US): 控制东亚文字替代字形的使用,像日语和汉语。font-variant-ligatures
: 控制文本中使用的连写和上下文形式。font-variant-numeric
: 控制数字,分式和序标的替代字形的使用。font-variant-position
: 控制位于上标或下标处,字号更小的替代字形的使用。font-size-adjust
: 独立于字体的实际大小尺寸,调整其可视大小尺寸。font-stretch
: 在给定字体的可选拉伸版本中切换。text-underline-position
: 指定下划线的排版位置,通过使用text-decoration-line
属性的underline
值。text-rendering
: 尝试执行一些文本渲染优化。
文本布局样式
text-indent
: 指定文本内容的第一行前面应该留出多少的水平空间。text-overflow
: 定义如何向用户表示存在被隐藏的溢出内容。white-space
: 定义如何处理元素内部的空白和换行。word-break
: 指定是否能在单词内部换行。direction
: 定义文本的方向 (这取决于语言,并且通常最好让 HTML 来处理这部分,因为它是和文本内容相关联的。)hyphens
: 为支持的语言开启或关闭连字符。line-break
: 对东亚语言采用更强或更弱的换行规则。text-align-last
: 定义一个块或行的最后一行,恰好位于一个强制换行前时,如何对齐。text-orientation
: 定义行内文本的方向。word-wrap
: 指定浏览器是否可以在单词内换行以避免超出范围。writing-mode
: 定义文本行布局为水平还是垂直,以及后继文本流的方向。
Font简写
许多字体的属性可以通过font
的方式简写,但需要按照以下顺序来写:
font-style
, font-variant
, font-weight
, font-stretch
, font-size
, line-height
, and font-family
.
其中只有font-size
和font-family
是必要的
1 | font: italic normal bold normal 3em/1.5 Helvetica, Arial, sans-serif; |
Web字体
Web字体是一种CSS特性,可以允许指定在访问时随网站一起下载的字体文件,使用一个@font-face
块指定要下载的字体文件:
1 | @font-face { |
然后可以使用@font-face
种指定的字体种类名称将定制字体应用到页面上:
1 | html { |
总结
字体属性
属性 | 表示 | 注意 |
---|---|---|
font-size |
字号 | 单位通常为px |
font-family |
字体 | 按团队字体来 |
font-weight |
字体粗细 | 加粗是700/bold不加粗是400/normal,无单位 |
font-style |
字体样式 | 倾斜式italic不倾斜式normal |
font |
字体连写 | 1. 有顺序。2. 字体字号不能同时出现 |
文本属性
属性 | 表示 | 注意 |
---|---|---|
color |
文本颜色 | 常用十六进制 |
text-align |
文本对齐 | 可设置文字水平对齐方式 |
text-indent |
文本缩进 | 首行缩进,通常缩进2字符为text-indent:2em |
text-decoration |
文本修饰 | 添加下划线underline 取消下划线none |
line-height |
行高 | 控制行间距 |
列表
列表间距
1 | /* General styles */ |
- 首先设置网页根节点基准字体大小,以及字体样式
- 规则集2和3为标题设置相对字体大小,这样每个段落和列表都将拥有相同的字体大小和上下间距,有助于保持垂直间距一致
- 4号在段落在列表项目上设置相同的
line-height
,也有助于保持垂直间距一致 - 5-7用来描述列表,描述列表的术语和其描述上设置与段落和列表项相同的行高,以及
margin-bottom
为1.5rem
列表特定样式
下面三个属性可以在<ul>
和<ol>
元素上设置:
list-style-type
:设置用于列表的项目符号类型例如:- 方形
- 圆形
- 数字
- 字母
- 罗马数字
list-style-position
:设置在每个项目开始之前,项目符号是出现在列表内还是列表外list-style-image
:设置自定义图片作为项目开始符号
符号样式
例如大写罗马字:
1 | ol { |
项目符号位置
可以设为insiade让符号在列表以内
1 | ol { |
自定义图片
1 | ul { |
然而,这个属性在控制项目符号的位置,大小等方面是有限的。最好使用background
系列属性,可以在 Styling boxes 模块中了解更多信息。
1 | ul { |
- 将
ul
种的paddintg-left
从默认的40px修改为20px,然后在列表上设置相同的数值。目的是让背景图像不与列表文本重叠 - 将
list-style-type
设置为none,以便默认情况下不会显示项目符号 - 为每无须列表项插入项目符号,对应属性如下:
background-image
:充当项目符号的图片文件路径background-position
:图像位置0 0
表示左上角background-size
:图像大小background-repeat
:平铺方式,默认情况下是复制填充,因此需要禁用平铺
list-style
符号样式,符号图片以及符号位置可以用一个list-sytle
来缩写,方式如下:
1 | ul { |
属性值可以任意顺序排列,你可以设置一个,两个或者三个值(该属性的默认值为 disc, none, outside),如果指定了 type 和 image,如果由于某种原因导致图像无法加载,则 type 将用作回退。
管理列表计数
可以通过star
属性来控制开始数字:
1 | <ol start="4"> |
还可以通过reversed
属性将序号倒置
1 | <ol start="4" reversed> |
并且还可以通过value
属性设置自定义序号值
1 | <ol> |
CSS精灵图
为了有效地减小服务器接收和发送请求的次数,提高页面的加载速度,出现了CSS精灵技术CSS sprites
即将服务器中很多小的图片整合为一张大的图片
精灵图的使用
- 精灵图技术主要针对背景图片使用,即把多个小背景图片整合到一张大的图片中
- 前端实现精灵图的切割是使用
background-position
属性 - 移动的距离就是目标图片的x和y坐标
字体图标
可以方便的修改颜色、尺寸,且放大不失真
- 轻量级
- 灵活性
- 兼容性——几乎支持所有浏览器
vertical-align属性
该属性用实现于行内元素或者行内块元素的垂直居中效果
值 | 描述 |
---|---|
baseline | 默认,元素放在父元素的基线上(即字母中的a,b等没有小尾巴的字符的底部 |
top | 元素顶端与行中最高元素顶端对齐 |
middle | 把元素放置在父元素中部 |
bottom | 把元素的顶端与行中最低的元素的顶端对齐(即字母中的f,g等有小尾巴的字符的底部 |
文本溢出省略号
单行
1 | one-line-text { |
多行
多行文本显示有较大兼容性问题,目前只适用于WebKit浏览器或移动端
1 | mul-line-text { |
CSS初始化
为了消除浏览器自带的样式,网页的最开始应该进行CSS初始化:
1 | /* 清除盒子内外边距 */ |
CSS布局
在不对页面进行任何布局控制时,浏览器默认的HEML布局方式为正常布局流(normal flow)
下面这些属性的设置可能会覆盖默认的布局行为:
display
- 应用
float
值 position
属性- 表格布局
- 多列布局
默认状态下:
- 一个块级元素的内容宽度其父元素的100%
- 块级元素高度与其内容高度一致
- 行级元素的height width与内容一致
- 块级元素按照基于其父元素的书写顺序的块流动方向放置
CSS传统网页布局
- 标准流(文档流)
- 浮动流
- 定位流
标准流
标准流即:标签按照规定好默认方式排列
即
- 块级元素独占一行,从上到下依次排列
- 行内元素从左到右顺序排列,碰到父元素边缘自动换行
标准流是最基本的网页布局方式
浮动流
浮动可以让多个块级元素在一行显示,于是得到网页布局流第一准测:
网页布局流第一准则:多个块级元素纵向排列使用标准流,多个跨级元素横向排列使用浮动流
浮动流使用float
创建浮动框,将其移动到一边, 直到左侧边缘或右侧边缘触及包含块或另一浮动框的边缘
1 | <style> |
浮动元素特性:
- 浮动元素会脱离标准流
- 脱离标准流的控制,移动到指定位置,俗称脱标
- 浮动的盒子不再保留原先的位置
- 如果多个盒子设置了浮动,则会按照属性值一行内显示并且顶端对齐排列
- 浮动元素具有行内块元素特性:
- 行内元素设置浮动后可以设置宽高
- 块级元素设置浮动后可以同行显示,且宽度变为默认等于内容宽度
- 浮动盒子直接没有margin,与行内元素同理
注意事项:
- 浮动流和标准流的父盒子搭配时:先用标准流的父元素排列上下位置,后内部子元素浮动排列左右位置
- 一个元素浮动,理论上其余兄弟元素也要浮动:浮动盒子只会影响浮动盒子之后的标准流,不会影响其前面的标准流
清除浮动
为什么要清除浮动?
由于父级盒子在很多情况下,不方便给高度,但子盒子浮动又不占有位置,最后父级盒子高度为0时,就会影响下面的标准流盒子
清除浮动的本质是什么?
- 本质是清除浮动元素造成的影响
- 如果父盒子本身有高度,就不需要清除浮动
- 清除浮动后,父级就会根据浮动的子盒子自动检测高度。父级有了高度,就不会影响下面的标准流
清除浮动的语法:clear
属性值 | 描述 |
---|---|
clear:left |
不允许左侧有浮动元素 |
clear:right |
不允许右侧有浮动元素 |
clear:both |
同时清除左右两侧浮动的影响 |
实际应用中几乎只用clear:both
清除浮动策略:闭合浮动,即将浮动元素限制在父元素内
清除浮动的四种方法:
- 额外标签法(隔墙法),W3C推荐
- 父级添加
overflow
- 父级添加
after
伪元素 - 父级添加双伪元素
额外标签法(不常用
在最后一个浮动盒子的后面添加一个额外的标签,然后设置其clear:both
:
1 | <head> |
优点:简单,书写方便
缺点:添加许多无意义的标签,结构化较差
注意
添加的标签必须是块级标签
父亲添加overflow
为父节点添加overflow
属性,并将其值设为hidden
、auto
、scroll
1 | <head> |
优点:代码简洁
缺店:无法显示溢出的部分
父亲添加:after伪元
:after
是额外标签法的升级版,利用伪元代替额外添加的标签
1 | <head> |
优点:没有增加更多标签,解构更简单
缺点:需要对低版本浏览器做兼容
父亲添加双伪元素
同时给父元素添加:after
和:before
伪元素
1 | <head> |
优点:代码更简洁
缺点:需要兼容低版本浏览器
清除浮动总结
- 为什么要清除浮动
- 父亲没高度
- 子盒子浮动
- 影响了之后的布局,需要清除浮动造成的影响
- 清除浮动的方法:
方法 | 优点 | 缺点 |
---|---|---|
额外标签法 | 通俗易懂,书写方便 | 添加无意义标签,结构化较差 |
父亲添加overflow | 书写简单 | 导致父元素溢出隐藏 |
父亲添加:after伪元 | 不引入额外标签,结构语义化正确 | 需要做兼容 |
父亲添加双伪元 | 不引入额外标签,结构语义化正确 | 需要做兼容 |
定位流
定位流可以实现:
- 让盒子自由地在某个盒子内部移动,并压住某个盒子
- 固定在屏幕的某个位置,并压住某个盒子
定位 = 定位模式 + 边偏移
定位模式用与指定一个元素在文档中的定位方式
边便宜则决定了该元素的最终位置
定位模式
通过position
属性来设置
值 | 语义 |
---|---|
static |
静态定位 |
relative |
相对定位 |
absolute |
绝对定位 |
fixed |
固定定位 |
边偏移
用于定位盒子的最终位置,有四个属性
属性 | 示例 | 描述 |
---|---|---|
top |
top:80px |
顶端偏移量,定义元素相对于其父元素上边线的距离 |
bottom |
bottom:80px |
底端偏移量,定义元素相对于其父元素下边线的距离 |
left |
left:80px |
左侧偏移量,定义元素相对于其父元素左线的距离 |
right |
right:80px |
右侧偏移量,定义元素相对于其父元素右边线的距离 |
static静态定位(了解
即默认定位,无定位
- 静态定位按照标准流拜访位置,没有边偏移
- 很少使用
realative相对定位(重要
元素移动时,相对于它原来的位置而定
相对定位的特点:
- 相对于自己原来的位置移动
- 原来在标准流的位置继续占有,后面的盒子仍然以标准流的方式对待它(不脱标,继续保留原有位置)
因此相对定位通常用来限制绝对定位
absolute绝对定位
元素移动时,相对于它祖先元素移动
绝对定位的特点:
- 如果祖先元素没有定位或没有祖先元素,则按照浏览器进行定位(Document文档)
- 如果祖先元素有定位(相对,绝对,固定定位),则以最近的有定位的祖先元素作为参考点移动
- 绝对定位不再占有原有的位置(脱标)
子绝父相
即子盒子如果使用绝对定位,那么父盒子使用相对定位
- 子盒子使用绝对定位不会占用空间,可以放在父盒子的任意位置,且不会影响其他兄弟盒子
- 父盒子需要加定位才能限制子盒子的显示范围
- 父盒子在布局时,需要占有位置,因此只能使用相对定位
即:父级需要占有位置,因此是相对定位,子盒子不需要占有位置,则是绝对定位
fixed固定定位
可以在浏览器页面滚动时仍然保持不变
固定定位的特点:
- 以浏览器可视窗口为参照点移动元素
- 跟父元素没关系
- 随着页面滚动而滚动
- 固定定位不占有原先位置(脱标)
此外固定定位还能根据版心进行定位:
- 设置固定定位的盒子
left: 50%
,移动到浏览器可视区(版心)的一半位置 - 设置固定定位的盒子
margin-left: 版心宽度的一半
sticky粘性定位``
粘性定位可以被认为是relative相对定位和fixed固定定位的混合
该定位可以实现,当盒子在可是窗口以内时,以相对定位的方式固定在页面中,不随页面滚动而滚动
但当盒子即将被可视窗遮盖时,变为固定定位固定在可视窗的某个位置
固定定位的特点:
- 以浏览器的可视窗口为参照无来移动元素(固定定位特点
- 粘性定位占有原先的位置(相对定位特点
- 必须添加
top, bottom, left, right
其中的一个才能生效
通常和页面滚动搭配使用,但兼容性很差,IE不支持,通常该效果可以使用JS实现
定位叠放顺序z-index
z-index
用于控制盒子的前后顺序
数值可以为正数、负数、0,默认为auto,数值越大,盒子越靠上
如果值相同,则按照书写顺序,后来者居上
数字不能加单位``
只有定位流具有该属性
定位流总结
定位模式 | 是否脱标 | 移动位置 | 是否常用 |
---|---|---|---|
static | 否 | 不能使用边偏移 | 很少 |
realative | 否 | 相对于自身原位置偏移 | 常用 |
absolute | 是 | 相对于祖先元素偏移 | 常用 |
fixed | 是 | 相对于浏览器可视区偏移 | 常用 |
sticky | 否 | 相对于浏览器可视区偏移 | 当前很少 |
定位流的特殊性质
- 行内元素添加绝对或者固定定位,可以直接设置宽高
- 块级元素添加绝对或者固定定位,如果不设置宽度,默认为内容大小
- 脱标的盒子不会触发外边距塌陷(即外边距合并
- 绝对定位(固定定位)会完全压住盒子
- 需要注意的是与浮动流的区别:
- 浮动元素只会压住下面标准流的盒子,但不会压住下面标准流盒子里的文字(图片
- 原因是浮动最初的作用是为了实现文字环绕效果
- 但是绝对(固定)定位会压住下面标准流所有的内容
水平居中
- 标准流下,可以通过
margin: 0 auto
实现水平居中 - 定位流下,绝对定位使用
left: 50%; margin-left: -宽度的一半
Flex弹性盒子
通过修改display
属性来控制元素是否为弹性盒子
1 | section { |
当这只元素为flex盒子后,其子元素将变为flex项
flex模型
当元素表现为flex时,它沿着两个轴来布局:
- 主轴,沿着flex元素放置方向延伸的轴
- 交叉轴,垂直于flex元素放置方向的轴
- 设置了
display:flex
的父元素,被称为flex容器 - 在flex容器种的表选为弹性盒子的元素被称为flex项
换行
当子元素超出了其容器,可以通过限制宽高,后设置自动换行来解决:
在flex容器中设置
1 | flex-wrap: wrap |
在flex项中设置限宽:
1 | flex: 200px; |
来限制flex项的最小宽度为200px
flex-flow缩写
flex-flow
允许将flex-direction
和flex-wrap
缩写进去:
1 | flex-flow: row wrap; |
flex项的动态尺寸
对于每个flex项,可以设置flex
属性来定义显示比例
1 | div { |
这是一个无单位的比例值,表示每个 flex 项沿主轴的可用空间大小。
如果三个元素均设为1,那么三个元素将以1:1:1的形式呈现,如果是1:2则第一个元素占1/3,第二个元素占2/3
此外还可以同时设置比例值和单位值:
1 | article { |
这表示每个flex项将首先给出200px的可用空间,剩余的可用空间则按比例分配
flex缩写和全写
flex
是一个可以指定最多三个不同值的缩写属性:
- 第一个就是上面所讨论过的无单位比例。可以单独指定全写
flex-grow
属性的值。 - 第二个无单位比例——
flex-shrink
——一般用于溢出容器的 flex 项。这指定了从每个 flex 项中取出多少溢出量,以阻止它们溢出它们的容器。 - 第三个是上面讨论的最小值。可以单独指定全写
flex-basis
属性的值。
水平垂直对齐
如果想要flex容器中的元素垂直、水平方向吹则,可以使用下面的方式:
1 | div { |
其中:
align-items
控制flex项在交叉轴上的位置
- 默认值为
stretch
,即所有flex项沿着交叉轴方向拉伸以填充父元素,如果交叉轴方向没有固定宽度,则所有flex项将变得与最长的flex项一样长 - center会使得flex项保持原有高度,但会在交叉轴居中
flex-end
,flex-star
使flex项在交叉轴的开始或结束处对齐所有值。
对于需要单独控制的flex项,可以使用align-self
来覆盖父元素的align-items
1 | button:first-child { |
justify-countent
可以用来控制flex项在主轴上的位置
- 默认值为
flex-start
,让flex项位于主轴的开始处 flex-end
,让flex项位于主轴的结尾处center
,让flex项在主轴居中space-around
,会使所有flex项沿着主轴均匀地分布,在任意一端都会留出一点空间。space-between
和space-around
非常相似,只是它不会在两端留下空间
flex项排序
弹性盒子也有可以改变 flex 项的布局位置的功能,而不会影响到源顺序(即 dom 树里元素的顺序)。
1 | button:first-child { |
- 所有 flex 项默认的
order
值是 0。 - order 值大的 flex 项比 order 值小的在显示顺序中更靠后。
- 相同 order 值的 flex 项按源顺序显示。所以假如你有四个元素,其 order 值分别是 2,1,1 和 0,那么它们的显示顺序就分别是第四,第二,第三,和第一。
- 第三个元素显示在第二个后面是因为它们的 order 值一样,且第三个元素在源顺序中排在第二个后面。
也可以给 order 设置负值使它们比值为 0 的元素排得更前面。
Grid网格布局
网格是由一系列水平及垂直的线构成的一种布局模式。帮助我们设计一系列具有固定位置以及宽度的元素的页面,使我们的网站页面更加统一。
一个网格通常具有许多的列(column)与行(row),以及行与行、列与列之间的间隙,这个间隙一般被称为沟槽(gutter)
创建一个网格布局:
1 | .container { |
在定义网格后,网页并不会马上发生变化。因为 display: grid
的声明只创建了一个只有一列的网格,所以子项还是会像正常布局流那样,自上而下、一个接一个的排布。
接着我们需要给更定义的网格加一些列:
1 | .container { |
上述代码加入了三个宽度为200px的列,此处可以使用任何长度单位
fr单位
除了长度和百分比,我们也可以用 fr
这个单位来灵活地定义网格的行与列的大小。这个单位代表网格容器中可用空间的一份。
1 | .container { |
fr
单位按比例划分了可用空间,类似flex布局中的flex
备注:
fr
单位分配的是可用空间而非所有空间,所以如果某一格包含的内容变多了,那么整个可用空间就会减少,可用空间是不包括那些已经确定被占用的空间的。
网格间隙
可以使用grid-column-gap
和grid-row-gap
来定义行间隙;也可以使用grid-gap
来同时设定两者
1 | .container { |
间隙值可以使用百分比来设置,但不能使用fr
备注:
gap
可以不加grid
前缀使用,属于历史遗留问题,但为了代码健壮性,还是推荐加上
重复构建轨道组
当我们的列很多的时候,可以使用repeat
来构建具有某些宽度的某些列:
1 | .container { |
第一个值表示重复次数,第二个值表示重复构建的配置,配置可以具体多个长度例如repeat(2, 2fr,1fr)
这样就会创建4个列,宽度分别为2fr 1fr 2fr 1fr
显式网格和隐式网格
显式网格是用 grid-template-columns
或 grid-template-rows
属性创建的
隐式网格则是当有内容被放到网格外时才会生成
显式网格与隐式网格的关系与弹性盒子的 main 和 cross 轴的关系有些类似。
隐式网格中生成的行/列大小是参数默认是 auto
,大小会根据放入的内容自动调整。也可以使用grid-auto-rows
和grid-auto-columns
属性手动设定隐式网格轨道的大小
1 | .container { |
上面的例子将grid-auto-rows
设为了100px
,隐式网格中的行(因为这个例子里没有设定grid-template-rows
,因此,所有行都位于隐式网格内)现在都是 100 像素高了。
minmax函数
minmax
函数为一个行/列的尺寸设置了取值范围。比如设定为 minmax(100px, auto)
,那么尺寸就至少为 100 像素,并且如果内容尺寸大于 100 像素则会根据内容自动调整。
1 | .container { |
自动使用多列填充
某些情况下,我们需要让网格自动创建很多列来填满整个容器。通过设置grid-template-columns
属性,可以实现这个效果,但也可以用到 repeat
函数中的一个关键字auto-fill
来替代确定的重复次数。而函数的第二个参数,使用minmax
函数来设定一个行/列的最小值,以及最大值 1fr
。
1 | .container { |
基于线的元素放置
网格有许多分隔线,第一条线的起始点与文档书写模式相关。
在英文中,第一条列分隔线(即网格边缘线)在网格的最左边而第一条行分隔线在网格的最上面。
而对于阿拉伯语,第一条列分隔线在网格的最右边,因为阿拉伯文是从右往左书写的。
通过以下的属性来指定开始和结束位置
这些属性的值均为分隔线序号,也可以用以下缩写形式来同时指定开始与结束的线。
注意开始与结束的线的序号要使用
/
符号分开。
1 | header { |
使用grid-template-areas属性放置元素
还可以利用命名的方式,更直观的管理元素的排布:
1 | .container { |
grid-template-areas
属性的使用规则如下:
- 你需要填满网格的每个格子
- 对于某个横跨多个格子的元素,重复写上那个元素
grid-area
属性定义的区域名字 - 所有名字只能出现在一个连续的区域,不能在不同的位置出现
- 一个连续的区域必须是一个矩形
- 使用
.
符号,让一个格子留空
CSS3新特性
新增的选择器
- 属性选择器
input[attrname]
input[attrname="val"]
input[attrname^="val"]
开头包含input[attrname$="val"]
结尾包含input[attrname*="val"]
包含
- 解构伪类选择器
E:first-child
E:last-child
E:nth-child(n)
n可以是数字、关键字、公式- 关键字有:
- even偶数孩子
- odd奇数孩子
- 公式
- 公式中的变量n从0开始,每次加1
- 2n,选取偶数
- 2n+1,选取奇数
- 5n,选取5的倍数
- n+5,第5个到最后一个
- -n+5,前5个(包含第5个
- 该选择器在计算时会先计算后面的nth-child是第几个,然后看E是否和该元素匹配。计算时会将所有直系子标签全部计算顺序
- 关键字有:
E:first-of-type
第一个EE:last-of-type
最后一个EE:nth-of-type(n)
第n个E
- 伪元素选择器(CSS3中使用:,CSS2中使用:)
::before
::after
- 该方法用于创建一个元素,该元素属于行内元素
- 该元素在DOM中找不到
- 必须包含
content
属性 - 伪元素选择器和伪类选择器权重一样wei
Sass
嵌套规则
子选择器可以直接使用嵌套实现
1 | #main { |
父级选择器
sass增加了父级选择器&
,可以在某个css块中访问它的父级
1 | .block { |
变量
使用$
来定义变量
1 | $width: 5em; |
插值语句
通过#{}
来实现类似JS中的格式化字符串的效果
1 | $name: foo; |
将编译为
1 | p.foo { |
@at-root
在某个块中跳出父节点,直接在根节点上创建样式
1 | .parent { |
会被编译为
1 | .parent{...} |
.child
将不会被视为.parent
的子选择器
整合样式的写法
css中经常会出现border
这样的可以同时设置border-color border-width border-style
样式的整合样式,sass中优化了这一样式的写法,可以使用{}
将他们独立开:
1 | p { |
编译结果为:
1 | p { |
混入
我们可以使用任何@mixin
来定义一些非常常用的样式,然后当需要为其他样式添加这些样式时,使用@include
插入即可
1 | @mixin large-text { |
将会编译为
1 | .page-title { |
此外混入块还可以接收参数
1 | @mixin sexy-border($color, $width) { |
编译后结果为:
1 | p { |
@content
在引用mixin块时,我们希望在其中增加一些东西,那么就可以使用如下形式:
1 | p { |
此时需要和vue中的slot类似的,在mixin块中预留占位符,因此需要将上述的sexy-border修改为如下形式:
1 | @mixin sexy-border($color, $width) { |
此时p就会被编译为:
1 | p { |
使用Sass实现BEM
使用mixin
可以方便的实现BEM架构的命名法则
1 | $namespace: "ender" !default; |
将该sass文件在vite中配置为全局:
1 | import { defineConfig } from 'vite' |
即可在项目中的任何style中进行这样的的元素创建:
1 | <template> |
那么这些样式在编译之后将会形成如下css
1 | .ender-block { |