前置知识
CSS/CSS3 长度、时间、频率、角度单位大全
CSS 值类型文档大全
CSS 全局关键字属性值:
- inherit,继承属性值;
- initial,CSS 语法中规定的初始值,不是浏览器内置样式的初始值;
- unset,对于有继承性的属性,等同于 inherit;对于没有继承性的属性,等同于 initial,常常(all:unset)酱紫使用;
- revert,还原为浏览器内置样式。
all 指代除了自定义属性(还有 unicode-bidi 和 direction)之外的所有 CSS 属性:
- initial,无实际价值;
- inherit,无实际价值;
- unset,让元素的样式表现和 span 一样;
- revert,让元素恢复成浏览器内置样式。
@supports 是用来检测当前浏览器是否支持某个 CSS 新特性的最规范、最正统的处理方法(当然,没 IE 什么事):
- 浏览器提供了相应的 JS 接口 CSS.supports(propertyName, value);
- @supports 规则的花括号可以包含其他任意 @ 规则,甚至是包含 @supports 规则自身。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
|
/* 支持弹性布局 */
@supports (display: flex) {
/* 可以嵌套其他规则 */
@media screen and (max-width: 720px) {
div {
/* ... */
}
}
}
/* 不支持弹性布局 */
@supports not (display: flex) {
/* 可以嵌套 @supports 自身 */
@supports (animation: none) {
span {
/* ... */
}
}
}
/* 同时支持弹性布局和网格布局 */
@supports (display: flex) and (display: grid) {
/* 可以嵌套 @keyframes */
@keyframes hahaha {
from {
/* ... */
}
to {
/* ... */
}
}
}
/* 支持弹性布局或者支持网格布局 */
@supports (display: flex) or (display: grid) {
/* ... */
}
|
总之,Web 开发是没有必要让所有浏览器都显示得一模一样的;好的浏览器有更好的显示,糟糕的浏览器就只有普通的显示;这才是对用户更负责任的做法。
width:fit-content
fit-content 的样式表现就是 CSS2.1 规范中的 shrink-to-fit,称其为包裹性;尺寸收缩但不会超出包含块级元素的尺寸限制:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
|
<style>
p {
background: red;
color: white;
}
/* 字数少时居中显示,字数多时左对齐显示 */
p > .table-span {
display: table;
margin: auto;
background: blue;
}
p > .fit-content {
display: block;
margin: auto;
width: fit-content;
background: green;
}
</style>
<p>
<span class="table-span">Ribeye tail rump tenderloin chislic venison.</span>
<span class="fit-content">Ribeye tail rump tenderloin chislic venison.</span>
</p>
<p>
<span class="table-span">
Flank chuck biltong, beef tenderloin tri-tip andouille alcatra cow ball tip.
Ribeye short ribs tail short loin, capicola pork belly landjaeger ham
drumstick salami flank.
</span>
<span class="fit-content">
Flank chuck biltong, beef tenderloin tri-tip andouille alcatra cow ball tip.
Ribeye short ribs tail short loin, capicola pork belly landjaeger ham
drumstick salami flank.
</span>
</p>
|
fit-content 的优点:让元素有了确定的尺寸;从此,让元素上下左右都居中有了一种新的写法:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
|
<style>
.fit-content-to-center {
position: absolute;
top: 0;
right: 0;
bottom: 0;
left: 0;
margin: auto;
/* 不必再借用 transform 属性了,减小了过渡动画的计算量 */
width: fit-content;
height: fit-content;
}
</style>
<span class="fit-content-to-center">
Ribeye tail rump tenderloin chislic venison.
</span>
|
stretch、available 和 fill-available 的作用都是一致的,那就是让元素的尺寸自动填满可用空间,就如同 div 元素的默认尺寸表现:
- stretch,弹性拉伸,用于替换之前的 fill-available 和 available;
- available,可用空间,Firefox 使用的关键字,需要配合 -moz- 前缀使用;
- fill-available,填充可用空间,Webkit 使用的关键字,需要配合 -webkit- 前缀使用。
所以,使用时应该酱紫写 CSS:
1
2
3
4
5
6
|
/* 其实,在实际开发中,用处不大 */
.element {
width: -webkit-fill-available;
width: -moz-available;
width: stretch;
}
|
min-content 与 max-content
min-content 即首选最小宽度或者最小内容宽度。
元素由 content-box、padding-box、border-box 和 margin-box 组成,元素最终占据的尺寸由这 4 个盒子占据的尺寸决定。其中 padding-box、border-box 和 margin-box 的尺寸表现规则不会因为元素的不同而有所不同,但是 content-box 不一样,它随着内容的不同,首选最小宽度也会不同:
- 替换元素(按钮、视频和图片等元素)的首选最小宽度是当前元素内容自身的宽度;
- CJK 文字(中文、日文、韩文):
- 一段没有标点的中文文字的首选最小宽度是单个汉字的宽度;
- 一段中文文字包含避头标点(,。?、!)或避尾标点(前引号、前括号),同时 line-break 的属性值不是 anywhere,首选最小宽度需要包含标点字符的宽度。
- 非 CJK 文字(英文、数字和标点等)的首选最小宽度是由字符单元(所有连续的英文字母、数字和标点都是一个字符单元,直到遇到中断字符)的宽度决定的;
- 一个元素最终的首选最小宽度是所有内部子元素中最大的那个首选最小宽度值。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
|
<style>
button,
span {
display: inline-block;
width: min-content;
outline: 1px solid black;
}
</style>
<button>按钮</button>
<button>Button</button>
<span>大大大小小小</span>
<span>AaBbCcDdEe</span>
<span>1234567890</span>
<span>他于 1999 年在香港科技大学(下称港科大)任职期间创立了固高科技...</span>
<span>
Pork belly fatback picanha, capicola t-bone rump ham strip steak brisket.
</span>
<span>1-2-34567-8-9-00000000</span>
|
在实际开发中是不会使用 min-content 关键字的,但是会非常频繁地遇到 min-content 的表现场景。
max-content 表示最大内容宽度;作用是让元素尽可能大,保证图文内容在一行显示,哪怕最终的宽度溢出外部容器元素。
所有需要使用 max-content 的场景,都能使用 white-space:nowrap 实现一模一样的效果,并且兼容性更好;所以实际上 max-content 没有任何实用价值。
position:sticky
黏性定位效果底层的渲染规则和固定定位没有任何关系,而是相对定位的延伸:
- 元素发生偏移的时候,元素的原始位置是保留的;
- 创建了新的绝对定位包含块,如果有绝对定位的子元素,那这个子元素是相对于当前黏性定位元素的;
- 支持设置 z-index 来改变元素的层叠顺序;
- 黏性定位是相对于层级最近的可滚动元素(overflow 不是 visible 的元素);如果没有可滚动元素,则相对视口定位;
- 当多个粘性元素发生重叠时,会有 A 元素推开 B 元素的视觉表现,而不是相互堆叠。
黏性定位中有一个流盒的概念,指的是黏性定位元素最近的可滚动元素的尺寸盒子,如果没有可滚动元素,则表示视口盒子。
黏性定位中还有一个名为黏性约束矩形的概念,指的是黏性定位元素的包含块在文档流中呈现的矩形区域和流盒的 4 个边缘在应用黏性定位元素的 left、top、right 和 bottom 属性的偏移计算值后的新矩形的交集。
滚动的时候流盒不变,而黏性定位元素的包含块跟着滚动,因此黏性约束矩形随着滚动的进行是实时变化的。假设黏性定位元素只设置了 top,则黏性定位元素碰到黏性约束矩形的顶部时就开始向下移动,直到它完全被包含在黏性约束矩形中。
如果多个黏性定位元素在同一容器中,则这几个黏性定位元素会产生元素重叠的情况:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
|
<style>
* {
margin: 0;
padding: 0;
border: none;
}
body {
height: 300vh;
}
.line {
position: fixed;
top: 15vh;
width: 100vw;
border-top: 1px dashed palevioletred;
}
.container {
outline: 1px solid white;
margin: 30vh auto 0;
width: 60vw;
height: 50vh;
}
p {
position: sticky;
top: 15vh;
border: 1px solid aquamarine;
text-align: center;
color: aquamarine;
font-size: 18px;
}
p:first-of-type {
text-align: left;
}
p:last-of-type {
text-align: right;
}
</style>
<span class="line"></span>
<div class="container">
<p>1</p>
<p>2</p>
<p>3</p>
</div>
|
如果黏性定位元素分布在不同的容器中,同时这些容器在布局上是上下紧密相连的,则视觉上会表现为新的黏性定位元素挤开原来的黏性定位元素,形成依次占位的效果:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
|
<style>
* {
margin: 0;
padding: 0;
border: none;
}
body {
height: 300vh;
}
.line {
position: fixed;
top: 15vh;
width: 100vw;
border-top: 1px dashed palevioletred;
}
.container {
outline: 1px solid white;
margin: 30vh auto 0;
width: 60vw;
height: 50vh;
}
p {
position: sticky;
top: 15vh;
border: 1px solid aquamarine;
text-align: center;
color: aquamarine;
font-size: 18px;
}
section {
height: 100px;
}
section:first-of-type p {
text-align: left;
}
section:last-of-type p {
text-align: right;
}
</style>
<span class="line"></span>
<div class="container">
<section><p>1</p></section>
<section><p>2</p></section>
<section><p>3</p></section>
</div>
|
上一个黏性定位元素被滚走,下一个黏性定位元素正好开始有黏性效果。
font-family
全新的通用字体族:
- system-ui,系统 UI 字体:
- 使用系统字体不再需要 font:menu、font:status-bar,因为 menu、status-bar、small-caption 关键字是包含字号的;
- font-family:system-ui 就可以使得字体设置随着系统字体变动。
- emoji,用于 emoji 字符的字体家族:
- Apple Color Emoji,用在 iOS 和 macOS 中;
- Segoe UI Emoji,用在 Windows 中;
- Segoe UI Symbol,Windows 7 中添加的一种新字体,一种 Unicode 编码字体,显示的是单色图案,非彩色图形;
- Noto Color Emoji,用在 Android 和 Linux 中。
- math,用于数学表达式的字体家族:
- Cambria Math,Windows 中的数学字体;
- Latin Modern Math,macOS 中的数学字体。
- fangsong,中文字体中的仿宋字体家族,一般用于非常正式的公告。
GitHub 的字体设置:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
|
<pre>
body {
/*
这里的字体设置遗漏了 Roboto 字体
Roboto 是为 Android 设计的一款无衬线字体
可以在 Android 上以最佳的西文字体显示
*/
font-family:
/*
只在 macOS 中有效
system-ui 字体族还没出现之前的一种私有语法
可以让 Firefox 和 Safari 9.1~10.1 使用系统字体
*/
-apple-system,
/*
只在 macOS 中有效
Chrome 53~55 使用系统字体的一种非标准语法
可以删掉了
*/
BlinkMacSystemFont,
/*
不支持系统字体的浏览器兜底用的
Windows 从 Vista 开始默认的西文字体族
*/
'Segoe UI',
/*
不支持系统字体的浏览器兜底用的
macOS 和 iOS 中很常用的一款无衬线字体
*/
Helvetica,
/*
不支持系统字体的浏览器兜底用的
全平台都支持的一款无衬线字体
*/
Arial,
sans-serif,
/*
emoji 字体
此处同样遗漏了 Android 的 emoji 字体
*/
'Apple Color Emoji',
'Segoe UI Emoji';
}
</pre>
|
最佳 CSS 字体设置实践:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
|
/* @font-face 定义的字体只有在被使用的时候才会加载 */
@font-face {
font-family: Emoji;
src: local('Apple Color Emoji'), local('Segoe UI Emoji'), local(
'Segoe UI Symbol'
), local('Noto Color Emoji');
unicode-range: U+1F000-1F644, U+203C-3299;
}
/* 最佳无衬线字体 */
body {
font-family: system-ui, -apple-system, Segoe UI, Roboto, Emoji, Helvetica,
Arial, sans-serif;
}
/* 最佳衬线字体 */
.font-serif {
font-family: Georgia, Cambria, 'Times New Roman', Times, serif;
}
/* 最佳等宽字体 */
.font-mono {
font-family: Menlo, Monaco, Consolas, 'Liberation Mono', 'Courier New',
monospace;
}
/* math 通用字体 */
math {
font-family: Cambria Math, Latin Modern Math;
}
|
font-display
字体显示时间线开始于浏览器尝试下载字体的那一刻,整个时间线分为 3 个时段,每个时段有不同的字体渲染行为:
- 字体阻塞时段,如果未加载字体,任何试图使用它的元素都必须以不可见的方式渲染后备字体;如果在此期间字体成功加载,则正常使用它;
- 字体交换时段,如果未加载字体,任何试图使用它的元素都必须以可见的方式渲染后备字体;如果在此期间字体成功加载,则正常使用它;
- 字体失败时段,如果未加载字体,则浏览器将其视为加载失败,并使用正常字体进行回退渲染。
font-display 就是围绕字体显示时间线展开的;共有五个属性值:
- auto,字体显示策略由浏览器决定;
- block,字体阻塞时段较短,字体交换时段无限;适合图标字体场景;
- swap,字体阻塞时段极短(不超过 100ms),字体交换时段无限;适合用在小段文本同时文本内容对页面非常重要的场景;
- fallback,字体阻塞时段极短(不超过 100ms),字体交换时段较短;适合用于大段文本同时对字体效果比较看重的场景;
- optional,字体阻塞时段极短(不超过 100ms),没有字体交换时段;如果字体瞬间被加载(被缓存),则浏览器使用该字体,否则使用回退字
体;日常 Web 开发更推荐。
font-display 属性只能用在 @font-face 规则中;如果你的自定义字体是用于字体呈现,就使用 optional,否则使用默认值。
中断与换行
字符单元默认的中断与换行规则:
- Space(普通空格)、Enter(回车)和 Tab(制表符)无论怎样组合都会合并为单个普通空格;
- 文字可以在 CJK 文本、普通空格和短横线连字符处换行,连续英文单词和数字不换行。
word-break:keep-all 可以让 CJK 文本不换行排版,同时又不影响非 CJK 文本的排版行为。
hyphens 是专为英文场景设计的一个 CSS 属性,可以让英文单词断开换行的时候带上连字符。
<wbr/> 表示有机会就断开换行(如果宽度足够就不换行);而 <br/> 则是直接换行显示,无论宽度是否足够。
text-decoration
text-decoration 是一个缩写属性:
- text-decoration-line,装饰线类型:
- none;
- underline;
- overline;
- line-through。
- text-decoration-style,装饰线风格:
- solid;
- double;
- dotted;
- dashed;
- wavy。
- text-decoration-color,装饰线颜色;
- text-decoration-thickness,装饰线粗细。
text-decoration 最有意思的特性要数装饰线的累加特性了:
1
2
3
4
5
6
7
8
9
10
11
12
|
<style>
div {
text-decoration: overline wavy orangered 1px;
}
p {
text-decoration: underline dotted tomato 2px;
}
</style>
<div>
<p>Burgdoggen shank picanha beef ribs capicola pastrami.</p>
<p>Tongue ribs filet shoulder short loin pancetta salami.</p>
</div>
|
text-underline-position:(under|left|right|from-font) 可以用来设置下划线的位置。
text-underline-offset 也可以用来设置下划线的位置(只对下划线类型的装饰线有效),其偏移量支持数值和百分比值。
color
不是所有人都知道的一些知识:
- HTML 中 color 算法和 CSS 中的 color 算法是不一样的;无法识别的颜色在 HTML 中会渲染成另外一个颜色,而在 CSS 中会忽略这个颜色;
- 颜色关键字设置的颜色都是实色,不带透明度;
- 颜色关键字不区分大小写;
- 所有颜色关键字中,只有两个颜色是以“deep”开头的,分别是深天蓝色 deepskyblue 和深粉色 deeppink;
- 暗灰色 darkgray 要比灰色 gray 更浅,并不是有“dark”前缀的颜色就更深;
- transparent 其实是 rgba(0, 0, 0, 0) 的另外一种快捷书写方式;
- SVG 和 Canvas 中的透明渐变算法与 CSS 的渐变算法不一致。
HSL 颜色很适合用在颜色变化的场合:
- Hue,色调,可以是小数:
- 0 ~ 360deg 大致按照红、橙、黄、绿、青、蓝、紫、红的颜色顺序分布;
- red = 0deg、green = 120deg、blue = 240deg。
- Saturation,饱和度,0% ~ 100%;
- Lightness,亮度,0% ~ 100%。
background-clip
background-clip 支持下面几个属性值:
- border-box,默认值,背景图像或者背景颜色的显示区域是整个 border-box,边框的下方也会显示背景内容;
- padding-box,背景图像或者背景颜色的显示区域是整个 padding-box;
- content-box,背景图像或者背景颜色的显示区域是整个 content-box;
- text,可以让背景图像按照字符形状进行剪裁。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
|
<style>
div {
float: left;
display: flex;
justify-content: center;
align-items: center;
margin: 8px;
padding: 20px;
width: 150px;
height: 150px;
background-color: cornflowerblue;
border: 20px dashed darksalmon;
outline: 1px solid black;
}
div:nth-of-type(1) {
background-clip: border-box;
}
div:nth-of-type(2) {
background-clip: padding-box;
}
div:nth-of-type(3) {
background-clip: content-box;
}
div:nth-of-type(4) {
-webkit-background-clip: text;
background-clip: text;
color: transparent;
}
</style>
<div>background-clip: border-box;</div>
<div>background-clip: padding-box;</div>
<div>background-clip: content-box;</div>
<div>background-clip: text;</div>
|
box-shadow
多边框效果:
1
2
3
4
5
6
7
8
9
10
11
12
13
|
<style>
.multi-border {
margin: 40px auto;
width: 60%;
height: 80px;
border-radius: 10px;
background-color: dodgerblue;
box-shadow: 0 0 0 4px white, 0 0 0 8px #fc9918, 0 0 0 12px #f14a16, 0 0 0
16px #35589a, 0 0 0 20px #370665, 0 0 0 24px #121212, 0 0 0 28px #30475e,
0 0 0 32px #f05454;
}
</style>
<div class="multi-border"></div>
|
CSS 中的角度单位:
- deg,角度,一个完整的圆是 360deg;
- grad,百分度,一个完整的圆是 400grad;
- rad,弧度,一个完整的圆是 2πrad;
- turn,圈数,一个完整的圆是 1turn。
元素 transform 之后的变化:
- 创建层叠上下文;
- 子元素 position:fixed 失效;
- transform 不为 none 的元素也可以作为绝对定位元素的包含块。
卷角投影效果:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
|
<style>
html {
display: flex;
justify-content: center;
align-items: center;
height: 100vh;
background-color: #666;
transform: scale(1);
}
.page {
position: relative;
width: 300px;
height: 200px;
background-color: #f4f39e;
box-shadow: 0 2px 10px 1px rgba(0, 0, 0, 0.2);
border-bottom-right-radius: 50% 10px;
}
.page::before,
.page::after {
content: '';
position: absolute;
width: 90%;
height: 30%;
z-index: -1;
}
.page::before {
left: 15px;
bottom: 12px;
box-shadow: 0 8px 16px rgba(0, 0, 0, 0.3);
transform: skew(-15deg) rotate(-5deg);
}
.page::after {
right: 15px;
bottom: 25px;
box-shadow: 8px 8px 10px rgba(0, 0, 0, 0.4);
transform: skew(15deg) rotate(8deg);
}
</style>
<div class="page"></div>
|
zoom 的属性值:
- 百分比值,50%,表示缩小到原来的一半;
- 数值,0.5,表示缩小到原来的一半;
- normal,等同于 1,默认值;
- reset,表示按 Ctrl− 或 Ctrl+ 进行文档缩放的时候,元素不跟着缩小与放大。
zoom 和 transform:scale 的区别:
- zoom 是一个非标准属性;
- zoom 缩放的中心坐标是相对于元素的左上角,且不能修改;transform:scale 缩放默认的中心坐标是元素的中心点;
- zoom 缩放会实时改变元素占据的尺寸空间;
- zoom 不会创建层叠上下文,不会使子元素 position:fixed 失效,不会改变绝对定位元素的包含块。
min、max 和 clamp
min(expression [, expression]) 支持一个或多个表达式,每个表达式之间使用逗号分隔,然后将最小的表达式的值作为返回值;例如:
1
2
3
4
5
6
7
8
9
10
11
12
13
|
div {
width: min(10vw, 5em, 80px);
width: min(10px * 10, 10em);
width: min(calc(10px * 10), 10em);
width: min(10px * 10, var(--width));
}
.constr {
width: 1024px;
max-width: 100%;
}
.constr {
width: min(1024px, 100%);
}
|
clamp 的作用是返回一个区间范围的值,clamp(MIN-最小值,VAL-首选值,MAX-最大值):
- 如果 VAL 在 MIN ~ MAX 范围内,则使用 VAL 作为函数返回值;
- 如果 VAL 大于 MAX,则使用 MAX 作为返回值;
- 如果 VAL 小于 MIN,则使用 MIN 作为返回值。
渐变
CSS 渐变本质上是一个图像,无法使用 transition 实现过渡效果,也无法使用
animation
实现动画效果。
渐变角度和渐变方位关系:0deg 表示向上,顺时针旋转是正角度,所以 90deg 表示向右。
变换
3D 变换相关的三个属性:
DEMO,
旋转的骰子
。
动画
@keyframes 规则中的 CSS 优先级是最高的;因此,没有必要在 @keyframes 中使用 !important 关键字。
animation-direction 可以用来控制动画的方向,其本质上是通过控制 @keyframes 规则中定义的动画关键帧执行的方向来实现的:
- normal,每个动画循环结束,动画重置到起点重新开始;[0->100%, 0->100%, 0->100%, …];
- alternate,下一轮动画的执行方向和上一轮动画的执行方向相反;[0->100%, 100%->0, 0->100%, …];
- reverse,每一轮动画执行的方向相反;[100%->0, 100%->0, 100%->0, …];
- alternate-reverse,[100%->0, 0->100%, 100%->0,…]。
animation-fill-mode 动画填充模式,主要用来定义动画在执行时间之外应用的值:
- none,表示动画开始之前和动画结束之后不会对元素应用 @keyframes 规则中定义的任何样式,可能会有『突变』的糟糕体验;
- both,让元素的动画在延时等待时保持第一帧的样式,在动画结束后保持最后一帧的样式,适用于绝大多数的开发场景;
- forwards,表示动画结束后(由 animation-iterationcount 属性决定),元素将应用当前动画结束时的属性值;
- backwards,表示在动画开始之前,元素将应用当前动画第一轮播放的第一帧的属性值。
animation-timing-function 支持两种缓动函数,cubic-bezier 和 steps;steps 函数用法为 steps(number, position):
- number,指数值,且是整数值,表示把动画分成了多少段;
- position,可选参数,指关键字属性值,表示动画跳跃执行是在时间段的开始还是结束:
- start,在时间段的开头处跳跃(直接开始,也就是时间段才开始,就已经执行了一个距离段);
- end,默认值,在时间段的结束处跳跃(戛然而止,也就是时间段一结束,当前动画执行就停止);
- jump-both,动画开始时和结束时都不发生跳跃,然后中间部分等分跳跃;
- jump-none,动画开始时和结束时都发生跳跃;
- jump-start,同 start;
- jump-end,同 end。
分栏布局
分栏布局相关的 CSS 属性:
- columns,column-width 和 column-count 的缩写;最终分栏的数量要么由 column-count 决定,要么由 column-width 决定:
- columns:18em,这里指代 column-width;
- columns:2|auto,这里指代 column-count。
- column-width,表示每一栏/列的最佳宽度(不支持百分比),是一种期望尺寸,实际渲染宽度多半和指定的宽度是有出入的:
- 几乎不存在分栏布局的栏目宽度就是 column-width 设置的宽度这样的场景。
- column-count,表示理想的分栏数目,最终的分栏数目可能不受 column-count 的控制;
- column-gap,表示每一栏之间的空白间隙的大小,可以是长度值,也可以是百分比值;
- column-rule,设置各个分栏的分隔线样式,是 column-rule-color、column-rule-style 和 column-rule-width 的缩写:
- column-rule-color,分隔线颜色;
- column-rule-style,分隔线样式;
- column-rule-width,分隔线粗细。
- column-span,表示某一个内容是否跨多栏显示,作用在分栏布局的子元素上:
- none,表示不横跨多栏,默认值;
- all,表示横跨所有垂直列。
- column-fill,当内容分栏的时候平衡每一栏填充的内容。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
|
<style>
.container {
columns: 100px;
column-rule: 3px solid olivedrab;
outline: 1px solid black;
}
.content {
border: 3px solid orangered;
}
</style>
<section class="container">
<div class="content">
Boudin meatloaf pork belly biltong swine pig flank sirloin. Cow corned beef
biltong andouille prosciutto. Salami shoulder turducken filet mignon sausage
hamburger flank kielbasa kevin swine. Ham capicola short loin tongue
shankle. Pork chuck short ribs, chicken rump pork chop fatback tail bresaola
boudin.
</div>
</section>
|
弹性布局
display:flex 发生了什么?
- 弹性子项(包括匿名内联元素)都是块级元素;
- 弹性子项浮动失效;
- 弹性子项(即使 position:static)支持 z-index,如果 z-index 不为 auto,会创建新的层叠上下文;
- 弹性子项的 margin 不会合并;
- 弹性子项的尺寸是经过精确计算的,可以使用 margin:auto 对剩余空间进行分配;
- 弹性子项如果被设置为绝对定位,则会脱离弹性布局。
匿名内联元素会变为匿名块级元素。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
|
<style>
.container {
display: flex;
}
.content {
margin: 30px;
float: right;
}
</style>
<!--
这里的 2 就是『匿名内联元素』
在弹性容器中,2 变成了『匿名块级元素』
因此,vertical-align 在这里没有用
-->
<section class="container">
<div class="content">1</div>
2
<div class="content">3</div>
</section>
<script>
const contentEle = document.querySelector('.content');
// float 的计算属性值还是为 right,但没有 float 行为
console.log(window.getComputedStyle(contentEle).float);
</script>
|
margin:auto 可以达到和 justify-content:space-between 一样的效果。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
|
<style>
.container {
display: flex;
}
.space-between {
justify-content: space-between;
}
.content {
outline: 1px solid black;
}
</style>
<h3>margin: auto</h3>
<section class="container">
<div class="content">1</div>
<div class="content" style="margin: auto">2</div>
<div class="content">3</div>
</section>
<h3>justify-content: space-between</h3>
<section class="container space-between">
<div class="content">1</div>
<div class="content">2</div>
<div class="content">3</div>
</section>
|
绝对定位的子项会脱离弹性布局。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
|
<style>
.container {
display: flex;
}
.space-between {
justify-content: space-between;
}
.content {
width: 21px;
outline: 1px solid black;
}
.content:first-of-type {
position: absolute;
}
</style>
<section class="container space-between">
<div class="content">
1
<br />
1
</div>
<div class="content">2</div>
<div class="content">3</div>
</section>
|
align-items 与 align-self 的区别:
- align-items 设置在弹性容器上(负责所有子项),align-self 设置在弹性子项上(负责某一子项);
- align-items 初始值是 normal,而在弹性布局中,align-items 初始值是 stretch;
- align-self 初始值是 auto,表示子项的垂直对齐方式由弹性容器上的 align-items 控制。
flex 是 flex-grow、flex-shrink 和 flex-basis 的简写:
- flex-grow,弹性容器在主轴方向上剩余空间多余时分配规则;默认 0,表示不分配;
- flex-shrink,弹性容器在主轴方向上剩余空间不足时分配规则;默认 1,表示分配;
- flex-basis,空间分配的基础尺寸;作用在 content-box 上,默认 auto;
- flex:initial,等同于 flex:0 1 auto,不抢多余空间,可以在空间不足时收缩;
- flex:auto,等同于 flex:1 1 auto,子项自动拉伸/收缩来填满剩余空间,在容器尺寸不足时会优先最大化内容尺寸;
- flex:none,等同于 flex:0 0 auto,子项没有弹性,子项表现为最大内容宽度;
- flex:1,等同于 flex:1 1 0%,子项自动拉伸/收缩来填满剩余空间,在容器尺寸不足时会优先最小化内容尺寸;
- flex:0,等同于 flex:0 1 0%,子项没有弹性,子项表现为最小内容宽度。
flex:0 和 flex:none 的区别:
flex:1 和 flex:auto 的区别:
弹性容器中,子项的最终尺寸是基础尺寸、弹性拉伸/收缩、最大/小尺寸共同作用的结果:
- 最终尺寸的计算优先级是:最大/小尺寸>弹性拉伸/收缩>基础尺寸;
- 基础尺寸由 flex-basis 或 width,以及 box-sizing 共同决定;
- 当没有设置基础尺寸时,最大内容宽度会顶替基础尺寸的角色;
- 弹性增长指的是 flex-grow,弹性收缩指的是 flex-shrink;
- 最大尺寸主要受 max-width 限制;最小尺寸则受最小内容宽度、width 和 min-width 共同影响。
网格布局
网格布局的默认布局和块布局非常类似,就是简单地从上往下依次垂直排列。
显式网格:在规定容器内显示的网格。
隐式网格:多于设置的单元格数量的 grid 子项,或者是在设定的网格范围之外出现 grid 子项。
作用于 grid 容器上的 CSS 属性:
- grid-template-columns,用来指定网格的列的数量和尺寸,支持长度值、百分比值、min/max-content、auto、fr 值、函数值;
- grid-template-rows,用来指定网格的行的数量和尺寸,支持的数据类型同 grid-template-columns:
- min-content,一排/列格子中所有最小内容尺寸中最大的那个最小内容尺寸值;
- max-content,一排/列格子中所有最小内容尺寸中最大的那个最大内容尺寸值;
- auto,max-content 是固定的尺寸,auto 会受到 justify-content 和 align-content 的影响:
- 当多列的宽度同时设置为 auto 的时候,这些列的宽度并不相同,而是在 max-content 的基础上增加同样大小的尺寸。
- fr(fraction)值,表示自动分配列(有些列的宽度就由页面自动分配)的尺寸划分比例:
- auto 的尺寸划分是随着内容变化的,内容多则尺寸大,内容少则尺寸小;而 fr 就是纯粹按比例计算,与内容多少无关;
- 如果所有 fr 值之和大于 1,则按 fr 值的比例划分可自动分配的尺寸;
- 如果所有 fr 值之和小于 1,最终的尺寸是可自动分配的尺寸和 fr 值的乘积。
- repeat(),不直接参与尺寸设置,更像一种简化代码的语法形式;
- minmax(min, max) ,表示尺寸范围限制在 min ~ max 范围内;
- fit-content(limit),尺寸由内容决定,内容越多尺寸越大,但不超过设定的 limit 尺寸。
- grid-template-areas,用来指定网格区域的划分,网格区域一定要形成规整的矩形区域;无论是 L 形还是凹的或凸的形状都会认为是无效的属性值;
- grid-template,前面三种属性的缩写;
- grid-column-gap,推荐使用 column-gap 替代,垂直间隙;
- grid-row-gap,推荐使用 row-gap 替代,水平间隙;
- grid-gap,推荐使用 gap 替代,grid-column-gap 和 grid-row-gap 的缩写;
- justify-items,用来定义元素在网格中的水平对齐表现:
- stretch,元素水平尺寸拉伸,填满整个网格的水平空间;
- start,元素的水平尺寸收缩为内容大小,同时沿着网格线左侧对齐显示;
- end,元素的水平尺寸收缩为内容大小,同时沿着网格线右侧对齐显示;
- center,元素的水平尺寸收缩为内容大小,同时在当前网格区域内部水平居中对齐显示。
- align-items,用来定义元素在网格中的垂直对齐表现:
- 和 justify-items 类似,区别就在于方向不同。
- place-items:<align-items> <justify-items>?,以上两个属性的简写;
- justify-content,指定了网格元素整体水平方向上的分布对齐方式;
- align-content,指定了网格元素整体垂直方向上的分布对齐方式;
- place-content:<align-content> <justify-content>?,以上两个属性的简写;
- grid-auto-columns,用来控制隐式网格的尺寸;
- grid-auto-rows,用来控制隐式网格的尺寸;
- grid-auto-flow:[row 或者 column]||dense,用来定义子项目元素的自动流动状态,非常类似于弹性布局中的 flex-direction:
- row,默认值,表示没有指定位置的网格在水平(行)方向上自然排列,这也是为什么网格布局会优先水平排列;
- cow,表示没有指定位置的网格在垂直(列)方向上自然排列;
- dense,如果稍后出现的网格比较小,则尝试看看其前面有没有合适的地方放置该网格,使网格尽可能排列紧凑。
- grid,是多个 CSS 属性的缩写集合:
- grid:none,设置所以子属性为初始值;
- 如果没有隐式网格,且无须改变网格布局的自然流向,则当做 grid-template 来使用;
- 如果出现隐式网格,或者需要改变网格布局的自然流向,则使用下面两种形式:
- grid:<grid-template-rows>/[auto-flow && dense?]<grid-auto-columns>?;
- grid:[auto-flow && dense?]<grid-auto-rows>?/<grid-template-columns>。
grid-template-columns/rows 的用法和简写:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
|
<style>
.container {
display: grid;
/* grid-template-rows: 25% 100px auto 60px; */
/* grid-template-columns: 80px auto 100px; */
/* grid-template: 25% 100px auto 60px / 80px auto 100px; */
grid: 25% 100px auto 60px / 80px auto 100px;
}
.content {
display: flex;
justify-content: center;
align-items: center;
outline: 1px solid olivedrab;
}
</style>
<section class="container">
<div class="content">1</div>
<div class="content">2</div>
<div class="content">3</div>
<div class="content">4</div>
<div class="content">5</div>
<div class="content">6</div>
<div class="content">7</div>
<div class="content">8</div>
<div class="content">9</div>
<div class="content">10</div>
<div class="content">11</div>
<div class="content">12</div>
</section>
|
fr 值的计算方式:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
|
<style>
.container1 {
display: grid;
grid-template-columns: 1.1fr 1.1fr 1.1fr;
}
.container2 {
margin: 30px 0 0;
display: grid;
grid-template-columns: 0.3fr 0.2fr 0.1fr;
}
.content {
display: flex;
justify-content: center;
align-items: center;
height: 30px;
outline: 1px solid olivedrab;
}
</style>
<section class="container1">
<div class="content">1</div>
<div class="content">2</div>
<div class="content">3</div>
</section>
<section class="container2">
<div class="content">1</div>
<div class="content">2</div>
<div class="content">3</div>
</section>
|
grid-template-areas 的使用:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
|
<style>
.container {
display: grid;
grid-template-columns: repeat(3, 1fr);
grid-template-rows: repeat(4, 1fr);
grid-template-areas: '蛙 蛙 蛙' '虾 鱼 鱼' '虾 鱼 鱼' '蟹 蟹 蟹';
gap: 8px;
}
.content {
display: flex;
justify-content: center;
align-items: center;
height: 30px;
outline: 1px solid orchid;
}
</style>
<section class="container">
<div class="content">蛙</div>
<div class="content">蛙</div>
<div class="content">蛙</div>
<div class="content">虾</div>
<div class="content">鱼</div>
<div class="content">鱼</div>
<div class="content">虾</div>
<div class="content">鱼</div>
<div class="content">鱼</div>
<div class="content">蟹</div>
<div class="content">蟹</div>
<div class="content">蟹</div>
</section>
|
隐式网格:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
|
<style>
.container {
display: grid;
grid-template: 1fr 1fr / 1fr 1fr;
/* 隐式网格高度为 50px */
grid-auto-rows: 50px;
gap: 8px;
}
.content {
display: flex;
justify-content: center;
align-items: center;
outline: 1px solid orchid;
}
</style>
<section class="container">
<div class="content">1</div>
<div class="content">2</div>
<div class="content">3</div>
<div class="content">4</div>
<!-- 之后的都属于隐式网格 -->
<div class="content">5</div>
<div class="content">6</div>
<div class="content">7</div>
</section>
|
grid-auto-flow 类似 flex-direction,控制着网格的排列流向:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
|
<style>
.container {
display: grid;
grid-template: 1fr 1fr 1fr / 1fr 1fr 1fr;
gap: 8px;
}
.row {
grid-auto-flow: row;
}
.column {
grid-auto-flow: column;
}
.content {
display: flex;
justify-content: center;
align-items: center;
outline: 1px solid;
}
.row .content {
outline-color: orchid;
}
.column .content {
outline-color: olivedrab;
}
</style>
<h3>grid-auto-flow: row</h3>
<section class="container row">
<div class="content">1</div>
<div class="content">2</div>
<div class="content">3</div>
<div class="content">4</div>
<div class="content">5</div>
<div class="content">6</div>
<div class="content">7</div>
</section>
<h3>grid-auto-flow: column</h3>
<section class="container column">
<div class="content">1</div>
<div class="content">2</div>
<div class="content">3</div>
<div class="content">4</div>
<div class="content">5</div>
<div class="content">6</div>
<div class="content">7</div>
</section>
|
作用于 grid 子项上的 CSS 属性:
- grid-column-start/end,grid 子项所占据的行的起止范围;
- grid-row-start/end,grid 子项所占据的列的起止范围,参数可以为整数(不为 0)、也可以为网格线名称:
- 整数,表示起止于第几条网格线,可以是负整数(从右侧开始计数网格线);
- 当浏览器找不到网格线时,会自动补全 -start/-end 后缀,继续寻找网格线;
- span3,表示当前网格会自动跨越 3 个网格;
- span <name>,表示当前网格会自动扩展,直到选中指定的网格线名称;
- auto,默认值,默认跨度是 1 个格子。
- grid-column,grid-column-start/end 的缩写属性;
- grid-row,grid-row-start/end 的缩写属性;
- grid-area,grid-column/row-start/end 四个属性的缩写,有两种属性值:
- <area-name>,由 grid-template-area 创建的区域名称;
- <row-start>/<column-start>/<row-end>/<column-end>,占据网格区域的行列起止位置。
- justify-self,设置单个网格元素的水平对齐方式;
- align-self,设置个网格元素的垂直对齐方式;
- place-self,<align-self> <justify-self>?。
Shapes 布局
Shapes 需要 float 的配合,可以实现不规则的图文环绕效果;其相关的 CSS 属性有 3 个,shape-outside、shape-margin、shape-image-threshold。
shape-outside 支持的属性值:
- none,普通矩形环绕;
- content/padding/border/margin-box,指定文字环绕时,依照哪个盒子的边缘进行计算;
- 形状函数(circle 圆、ellipse 椭圆、inset 矩形、polygon 多边形);
- 图片类型(URL 链接、渐变、函数图像等)。
shape-margin 的作用是控制文字环绕图形时文字与元素边界的距离;因为在 Shapes 布局中,文字环绕有时候是无视 margin 属性的。其有效数值范围是 0 ~ 浮动元素边界,当属性值超过浮动元素边界的时候,布局效果如同普通浮动布局效果,没有不规则的图形环绕效果。
shape-image-threshold 指图像环绕时候的半透明阈值,默认是 0.0,也就是图像透明度为 0 的区域边界才能被文字环绕;如果属性值是 0.5,则表示透明度小于 0.5 的区域都可以被文字环绕。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
|
<style>
.shape {
float: left;
width: 60px;
height: 60px;
padding: 20px;
margin: 20px;
border: 20px solid peru;
background-color: cornflowerblue;
background-clip: content-box;
border-radius: 50%;
outline: 1px solid red;
}
</style>
<section>
<span class="shape" style="shape-outside: none"></span>
<div>
Buffalo boudin ham bresaola short ribs jowl leberkas ball tip jerky bacon
ribeye swine picanha landjaeger brisket. Kevin shankle spare ribs
tenderloin. Kevin tongue tail swine sausage, turkey t-bone picanha. Brisket
venison jerky tongue biltong. Drumstick cow pig picanha frankfurter ground
round, pork belly brisket rump jowl meatloaf. Andouille bresaola burgdoggen
spare ribs hamburger drumstick prosciutto ball tip tri-tip short loin
chicken meatloaf swine strip steak flank.
</div>
</section>
<section>
<span class="shape" style="shape-outside: content-box"></span>
<div>
Buffalo boudin ham bresaola short ribs jowl leberkas ball tip jerky bacon
ribeye swine picanha landjaeger brisket. Kevin shankle spare ribs
tenderloin. Kevin tongue tail swine sausage, turkey t-bone picanha. Brisket
venison jerky tongue biltong. Drumstick cow pig picanha frankfurter ground
round, pork belly brisket rump jowl meatloaf. Andouille bresaola burgdoggen
spare ribs hamburger drumstick prosciutto ball tip tri-tip short loin
chicken meatloaf swine strip steak flank.
</div>
</section>
<section>
<span class="shape" style="shape-outside: padding-box"></span>
<div>
Buffalo boudin ham bresaola short ribs jowl leberkas ball tip jerky bacon
ribeye swine picanha landjaeger brisket. Kevin shankle spare ribs
tenderloin. Kevin tongue tail swine sausage, turkey t-bone picanha. Brisket
venison jerky tongue biltong. Drumstick cow pig picanha frankfurter ground
round, pork belly brisket rump jowl meatloaf. Andouille bresaola burgdoggen
spare ribs hamburger drumstick prosciutto ball tip tri-tip short loin
chicken meatloaf swine strip steak flank.
</div>
</section>
<section>
<span class="shape" style="shape-outside: border-box"></span>
<div>
Buffalo boudin ham bresaola short ribs jowl leberkas ball tip jerky bacon
ribeye swine picanha landjaeger brisket. Kevin shankle spare ribs
tenderloin. Kevin tongue tail swine sausage, turkey t-bone picanha. Brisket
venison jerky tongue biltong. Drumstick cow pig picanha frankfurter ground
round, pork belly brisket rump jowl meatloaf. Andouille bresaola burgdoggen
spare ribs hamburger drumstick prosciutto ball tip tri-tip short loin
chicken meatloaf swine strip steak flank.
</div>
</section>
<section>
<span class="shape" style="shape-outside: margin-box"></span>
<div>
Buffalo boudin ham bresaola short ribs jowl leberkas ball tip jerky bacon
ribeye swine picanha landjaeger brisket. Kevin shankle spare ribs
tenderloin. Kevin tongue tail swine sausage, turkey t-bone picanha. Brisket
venison jerky tongue biltong. Drumstick cow pig picanha frankfurter ground
round, pork belly brisket rump jowl meatloaf. Andouille bresaola burgdoggen
spare ribs hamburger drumstick prosciutto ball tip tri-tip short loin
chicken meatloaf swine strip steak flank.
</div>
</section>
|
当 shape-outside 的属性值为图片类型(必须是同域名下)时,浏览器会解析图片的透明和非透明区域;默认情况下,文字会沿着非透明区域的边缘排列:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
|
<style>
.shape {
float: left;
width: 452px;
height: 222px;
background-color: currentColor;
color: red;
shape-outside: url(/css-last/whale.png);
-webkit-mask: url(/css-last/whale.png) no-repeat;
mask: url(/css-last/whale.png) no-repeat;
}
</style>
<span class="shape"></span>
<div>
Buffalo boudin ham bresaola short ribs jowl leberkas ball tip jerky bacon
ribeye swine picanha landjaeger brisket. Kevin shankle spare ribs tenderloin.
Kevin tongue tail swine sausage, turkey t-bone picanha. Brisket venison jerky
tongue biltong. Drumstick cow pig picanha frankfurter ground round, pork belly
brisket rump jowl meatloaf. Andouille bresaola burgdoggen spare ribs hamburger
drumstick prosciutto ball tip tri-tip short loin chicken meatloaf swine strip
steak flank.
</div>
|
媒体查询
@media 查询的规则由 4 部分组成:媒体查询修饰符、媒体类型、媒体条件、媒体特征。
媒体查询修饰符:
- only,本身没有任何效果,主要是为了兼容过时的浏览器;
- not,否定整个查询语句。
媒体类型:
- screen,屏幕输出设备上生效;
- print,打印(预览)时生效;
- all,匹配所有设备。
媒体条件:
- not,否定某个媒体特征;
- and,同时满足;
- or,满足之一。
媒体特征:
- aspect-ratio,输出设备可视区域的宽度和高度的比例(可能受软键盘的影响);
- width,设备的宽度的查询与匹配;
- height,设备的高度的查询与匹配;
- orientation,判断设备是横屏还是竖屏(可能受软键盘的影响):
- landscape,横屏状态;
- portrait,竖屏状态。
- display-mode,Web 应用的显示模式:
- fullscreen:全屏显示,没有任何浏览器部件;
- browser:在浏览器中打开,是浏览器的一个标签页;
- standalone:如同独立的应用程序,有独立的窗口,有自己的程序启动图标,没有导航元素,但是会有状态栏;
- minimal-ui:如同独立的应用程序,但有一个用来导航的最小 UI 元素集,具体有什么元素在不同浏览器中是不一样的。
- any-hover,是否有任意输入设备可以经过某个元素(可以用来检测『设备是否接入了鼠标』):
- none,没有输入装置可以实现悬停效果;
- hover,可以触发元素的悬停交互效果。
- hover,主输入设备是否可以经过某个元素,例如,是否连接了鼠标;
- any-pointer,是否有任意输入设备可以触控操作,以及如果可以触控操作,精度应为多少:
- none,没有可用的点击设备;
- coarse,至少有一个设备的点击不是很精确(例如,手指点击);
- fine,有点击很精准的设备(例如,鼠标)。
- pointer,主输入设备是否可以触控操作,以及如果可以触控操作,精度应为多少:
- none,主输入装置点击不可用;
- coarse,主输入装置点击不精确;
- fine,主输入装置点击很精准。
- prefers-color-scheme,用来检测用户是否使用了深色模式:
- no-preference,系统没有告知使用的颜色方案;
- light,系统当前使用了浅色模式;
- dark,系统当前使用了深色模式。
- prefers-reduced-motion,用来检测用户是否配置了没有必要的动画选项(类似于 iOS 中的『减弱动态效果』):
- no-preference,用户没有通知系统任何首选项;
- reduced,用户已通知系统,需要减弱动态效果。
网页快速适配深色模式:
1
2
3
4
5
6
7
8
9
10
|
/* 这种『偷懒的技巧』在 Safari 中可能有渲染问题 */
@media (prefers-color-scheme: dark) {
body {
filter: invert(1) hue-rotate(180deg);
}
img {
/* 对于图片元素,需要进行反向操作 */
filter: invert(1) hue-rotate(180deg);
}
}
|
当用户关闭系统动画时,页面可以同步减少动画效果:
1
2
3
4
5
6
|
@media (prefers-reduced-motion) {
* {
animation: none;
transition: none;
}
}
|
image-set
image-set 类似于 HTML 中的 srcset 属性,可以根据屏幕的像素密度来显示相应的背景图。
1
2
3
4
5
6
7
|
.example {
background-image: image-set(
url(origin.png) 1x,
url(origin-2x.png) 2x,
url(origin-print.png) 600dpi
);
}
|
变量与自定义属性
CSS 变量的声明由 CSS 自定义属性及其对应的值组成;CSS 变量的使用是通过变量函数 var() 调用 CSS 自定义属性实现。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
|
/*
不支持包含 $、[、]、^、(、)、%、" 等特殊字符的命名
要使用这些特殊字符,需要使用反斜杠转义
*/
:root {
--primary-color: blue;
--俄乌: 10px; /* CJK 文字 */
---: orange; /* 短横线 */
--1: red; /* 数字 */
--: green; /* 空格 */
}
section {
background-color: var(--1);
border: var(--俄乌) solid var(---);
color: var(--primary-color);
outline: var(--俄乌) solid var(--);
}
|
var() 的第二个参数可以用来设置缺省值,当且仅当第一个参数解析无效时才起作用:
1
2
3
4
5
6
7
8
9
10
11
12
|
body {
--color: 20px;
background-color: black;
/*
由于第一个参数 --color 是可以呗正常解析的
所以 red 这个缺省值会被忽略
显然背景色 20px 是不合法的
所以会被解析为初始值
transparent
*/
background-color: var(--color, red);
}
|
CSS 自定义属性是有作用域的,所以全局使用的自定义属性都定义在 :root 伪类中。
CSS 自定义属性不支持在媒体查询的查询条件中使用,也不支持 content 属性:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
|
:root {
--maxWidth: 666px;
--percent: 60%;
}
/* 不可以,没用 */
@media (max-width: var(--maxWidth)) {
body {
font-size: 21px;
}
}
/* 无效 */
body::after {
content: var(--percent);
}
|
在 HTML 中的使用:
1
2
3
|
<div style="--color: pink;">
<span style="outline: 1px solid var(--color);"></span>
</div>
|
在 JS 中使用(需要借助 style 的 setProperty/getPropertyValue 方法):
1
2
3
4
|
const divEle = document.querySelector('div');
divEle.style.setProperty('--color', 'blue'); // 赋值
divEle.style['--color'] = 'blue'; // 无效
window.getComputedStyle(divEle).getPropertyValue('--color'); // 取值
|
object-fit
替换元素的内在尺寸适用于外部指定的尺寸,这就导致两个问题:
- 外部指定的尺寸和内在尺寸有可能宽高比例不相符;
- 资源加载完毕之前,内在尺寸是 0;加载完毕之后,可能导致页面重绘。
object-fit 就是为了解决这些问题的(有点像 background-size),其属性值有 5 个:
- fill,默认值,替换内容会填满 content-box,不保持内在比例;
- contain,替换内容在 content-box 中完整显示,保持内在比例;
- cover,替换内容会覆盖 content-box,保持内在比例并可能会让替换内容部分区域不可见;
- none,替换内容显示为原始比例,无视外部尺寸限制;显示区域会大量留白(原始内容尺寸较小)或者被裁剪(原始内容尺寸较大);
- scale-down,替换内容尺寸为较大时,表现为 contain;尺寸较小时,表现为 none。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
|
<style>
section {
display: flex;
flex-wrap: wrap;
}
div {
width: 50vw;
height: 50vw;
box-sizing: border-box;
padding: 10px;
border: 10px solid palevioletred;
outline: 1px solid cadetblue;
}
img {
width: 100%;
height: 100%;
}
</style>
<section>
<div>
<img src="avatar.png" style="object-fit: fill" />
</div>
<div>
<img src="avatar.png" style="object-fit: contain" />
</div>
<div>
<img src="avatar.png" style="object-fit: cover" />
</div>
<div>
<img src="avatar.png" style="object-fit: none" />
</div>
<div>
<img src="avatar.png" style="object-fit: scale-down" />
</div>
<div>
<img src="avatar.png" style="object-fit: scale-down" />
</div>
</section>
|
object-position 是一个使用场景比较少的属性,用于控制替换内容在替换元素中的位置(有点像 background-position);初始值为 50% 50%,居中效果。
image-orientation 可以让浏览器识别图片 Exif 信息中的 Orientation 值来对图片方向进行修正:
- from-image,初始值,如果包含 Orientation,则对图片方向进行纠正;
- none,不对图片方向进行纠正。
filter
filter 支持 10 个滤镜函数:
- blur(5px),模糊,不支持百分比,其参数值可以理解为屏幕上互相融合的像素数量,会有边缘泛白的问题;
- brightness(2.4),亮度,支持百分比,参数范围是 0 到无穷大,默认参数为 1;
- contrast(200%),对比度,支持百分比,参数范围是 0 到无穷大,默认参数为 1;
- drop-shadow(x 偏移,y 偏移,模糊大小,色值),投影;
- grayscale(50%),灰度,可以实现去色效果(特殊节日灰掉网页),让彩色值变为灰度值,支持百分比,参数范围是 0 到无穷大,默认参数为 0;
- hue-rotate(90deg),色调旋转,保持饱和度和亮度不变;
- invert(75%),反相,亮度和色调同时反转,支持百分比,参数范围是 0 到无穷大;
- opacity(25%),透明度,效果和 opacity 类似,两种属性同时使用,效果会叠加;
- saturate(230%),饱和度,支持百分比,参数范围是 0 到无穷大;
- sepia(60%),褐色,支持百分比,参数范围是 0 到无穷大。
以上的滤镜效果是可以叠加的。
box-shadow 和 filter:drop-shadow() 的区别:
- filter:drop-shadow 没有内投影;
- filter:drop-shadow 没有扩散半径;
- filter:drop-shadow 不支持投影叠加;
- filter:drop-shadow 符合真实世界的表现。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
|
<style>
section {
display: flex;
flex-wrap: wrap;
justify-content: center;
}
div {
margin: 8px 0 16px;
width: 80vw;
height: 50vw;
padding: 10px;
background-color: transparent;
box-sizing: border-box;
border: 10px dashed palevioletred;
}
</style>
<section>
<div style="box-shadow: 5px 5px 8px"></div>
<div style="filter: drop-shadow(5px 5px 8px)"></div>
</section>
|
backdrop-filter 和 filter 语法相似,可以轻松实现毛玻璃效果;他们的区别是,backdrop-filter 是让当前元素所在区域后面的内容应用滤镜效果,需要当前元素是半/完全透明的;filter 是让当前元素自身应用滤镜效果。
混合模式
CSS 中有 3 个混合模式相关的属性:
- mix-blend-mode,元素与元素之间的混合;
- isolation,应用于祖先元素,限制 mix-blend-mode:
- auto,默认值,混合模式隔离与否根据具体情况而定;
-
isolate
,对混合模式进行隔离(通过创建新的层叠上下文)。
- background-blend-mode,混合元素背景图案、渐变和颜色。
background-blend-mode 和
mix-blend-mode
支持的混合模式是一致的:
- normal,正常;
-
multiply
,正片叠底,混合后颜色变暗;
-
screen
,滤色,效果和 multiply 正好相反,混合后颜色变亮;
-
overlay
,叠加,根据下层元素色值和 128 的大小,采用“multiply”或“screen”算法;
- darken,变暗,将两种颜色的 RGB 通道值依次进行比较,哪个色值小就使用哪个色值;
-
lighten
,变亮,将两种颜色的 RGB 通道值依次进行比较,哪个色值大就使用哪个色值;;
- color-dodge,颜色变淡,混合区域的对比度降低;
- color-burn,颜色加深,混合区域的对比度提升;
- hard-light,强光,亮的地方更亮,暗的地方更暗;
-
soft-light
,柔光,效果同“hard-light”,只是没那么极端;
-
difference
,差值,最终颜色的色值是用较浅颜色的色值减去较深颜色的色值的结果;
-
exclusion
,排除,对比度要比“difference”低一些;
- hue,色调混合,将颜色混合,使用底层元素的亮度和饱和度,以及上层元素的色调;
- saturation,饱和度混合,混合后的颜色保留底图的亮度和色调,并使用顶图的饱和度;
-
color
,颜色混合,混合后的颜色保留底图的亮度,并使用顶图的色调和饱和度;
- luminosity,亮度混合,混合后的颜色保留底图的色调和饱和度,并使用顶图的亮度。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
|
<style>
/* 模拟晚上的场景 */
.normal {
float: left;
width: 400px;
height: 300px;
background-color: rgba(0, 40, 140, 0.6);
background-image: url(normal.jpg);
background-size: cover;
}
.night {
background-blend-mode: darken;
filter: brightness(80%) grayscale(20%) contract(1.2);
}
</style>
<div class="normal"></div>
<div class="normal night"></div>
|
遮罩效果
mask-image,设置使用遮罩效果的图像:
- none,默认值,表示无遮罩图片;
- 图像数据类型,包括 CSS 渐变、url()、image-set()、cross-fade()、element() 等;
- 遮罩元素类型,主要指 SVG 遮罩元素。
mask-mode(Chrome 不支持),设置遮罩模式:
- match-source,默认值,根据资源类型自动采用合适的遮罩模式;
- luminance,基于亮度判断是否要进行遮罩;
- alpha,基于透明度判断是否要进行遮罩。
mask-composite,同时使用多张图片进行遮罩时的合成方式:
- add,默认值,遮罩累加,并集;
- substract,遮罩相减,多张遮罩图片的重合区域不显示遮罩,遮罩图片越多,遮罩区域越小;
- intersect,遮罩相交,多张遮罩图片的重合区域才显示遮罩,交集;
- exclude,遮罩排除,多张遮罩图片的重合区域被当作透明的。
1
2
3
4
5
6
7
8
9
10
11
12
13
|
<style>
.mask-image {
width: 400px;
height: 400px;
/* mask-* 属性和 background-* 属性很像 */
-webkit-mask-size: contain;
-webkit-mask-repeat: no-repeat;
-webkit-mask-position: center center;
/* 需要是透明背景的图片 */
-webkit-mask-image: url('./whale.png');
}
</style>
<img src="husky.jpg" class="mask-image" alt="二哈" />
|
滚动行为
scroll-behavior 属于交互渐进增强型的属性:
- auto,初始值,不常用;
- smooth,使滚动行为变得平滑。
overflow-behavior(-x/y) 用于设置元素“滚动到边缘(滚动条触顶/底)”时的行为:
- auto,默认值,内部元素滚动到边缘时触发外部元素滚动;
- contain,内部元素滚动到边缘时,触发“反弹”效果,滚动行为不会“冒泡”到外部;
- none,相比于 contain,少了“反弹”效果,差异主要体现在移动端。
overflow-anchor,滚动锚定;当内容突然出现时,浏览器自动改变滚动高度,使的可视区域的内容不被“冲走”,就像滚动被锚定了一样:
- auto,是否“锚定”由浏览器决定;
- none,禁止“锚定”。
滚动吸附
当元素滚动结束时,自动定位到“指定”位置(当超过一定阈值的时候),有点类似于“
吸附
”的效果。
其中作用在“滚动容器”上的属性有:
- scroll-snap-type,确定定位方式是“水平”还是“垂直”滚动定位:
- none,默认值,滚动时忽略“指定”位置;
- x,捕捉“水平”定位点;
- y,捕捉“垂直”定位点;
- block,捕捉和块状元素排列一个滚动方向的定位点,默认文档流下指的就是“捕捉垂直定位点”;
- inline,捕捉和内联元素排列一个滚动方向的定位点,默认文档流下指的就是“捕捉水平定位点”;
- both,“水平”和“垂直”均捕获;
- mandatory,强制定位,如果存在有效的定位点位置,则滚动容器必须在滚动结束时进行定位;
-
proximity
,浏览器自己判断要不要定位(当容器窗口尺寸小于子元素尺寸时,不定位;否则,定位)。
- scroll-snap-stop,是否允许滚动容器忽略捕获位置,兼容性较差:
- normal,可以忽略捕获位置;
- always,不能忽略,必须定位到第一个捕获元素的位置。
- scroll-snap-padding(-*),用来调整定位点的位置。
作用在“滚动定位子元素”上的属性有:
- scroll-snap-align,定义捕获点位置是“上边缘”、“下边缘”、“中间位置”:
- none,默认值,不定义捕获点位置;
- start,起始位置对齐,如垂直滚动、子元素和容器同上边缘对齐;
- end,结束位置对齐,如垂直滚动、子元素和容器同下边缘对齐;
- center,居中对齐,子元素中心和滚动容器中心一致。
- scroll-margin(-*),用来调整定位点的位置。
滚动条样式
scrollbar-width 用来设置滚动条的宽度,并不支持具体的长度值:
- auto,系统默认滚动条样式;
- none,不展示滚动条,但是页面可以进行正常滚动;
- thin,如果有“窄”的滚动条,就使用“窄”的滚动条;没有的话,就采用比默认滚动条“窄”一点(Windows 下为 8px)的滚动条。
scrollbar-color 用来设置滚动条的颜色:
- auto,使用系统默认的滚动条颜色(系统使用的主题决定);
- dark/light,深色/浅色滚动条(目前没有浏览器支持);
- c1 c2,c1 表示滑块的颜色(::webkit-scrollbar-thumb),c2 表示滚动轨道的颜色(::webkit-scrollbar-track)。
隐藏滚动条(可滚动):
1
2
3
4
5
6
7
|
.scroll-none {
scrollbar-width: none;
}
.scroll-none::-webkit-scrollbar {
width: 0;
height: 0;
}
|
点击行为
pointer-events: none 虽然可以禁用“鼠标”点击、悬停和拖拽行为,但其并不适合用来实现“禁用”效果:
- 不能阻止键盘行为,对应元素仍可以通过键盘被 focus 并 click;
- 影响“无障碍访问”,对应元素的 title 属性将不起作用。
touch-action 是移动端中与手势触摸密切相关的 CSS,属性值为:
- auto,默认值,表示手势操作完全由浏览器决定;
- none,表示不进行任何手势相关的行为,不能用手指滚动/缩放网页;
- manipulation,表示浏览器只允许进行滚动和持续缩放操作(双击缩放不被支持),可以用来解决点击后延时 300ms 的问题;
- pan-x,表示支持手指水平移来移去的操作;
- pan-y,表示支持手指垂直移来移去的操作;
- pan-left,表示支持手指往左移动,移动开始后往右可以恢复的操作;
- pan-right,表示支持手指往右移动,移动开始后往左可以恢复的操作;
- pan-up,表示支持手指往上移动,移动开始后往下可以恢复的操作;
- pan-down,表示支持手指往下移动,移动开始后往上可以恢复的操作;
- pinch-zoom,表示支持手指缩放页面的操作。
拉伸行为
resize 属性的作用条件:
- 不支持内联元素;
- 块级元素的 overflow 属性计算值不能为 visible。
resize 属性是通过改变元素的 width/height 属性值来实现的,所以可以通过 min/max-width/height 来限制元素的拉伸尺寸。
resize 的拖拽条样式可以通过 ::webkit-resizer 伪元素进行自定义。
输入行为
caret-color 可以改变输入框“插入光标”的颜色;其不仅对表单元素有效,对设置了 contenteditable 的普通元素同样有效。
1
2
3
4
5
6
7
8
9
10
11
|
<style>
input,
[contenteditable] {
padding: 0.8em;
border: 1px solid grey;
caret-color: red;
color: blue;
}
</style>
<input type="text" placeholder="text" />
<p contenteditable="true">contenteditable</p>
|
选择行为
user-select 属性多用于内嵌在 WebView 的页面中,保持和原生应用一致的内容选择体验:
- auto,初始值;
- text,元素及其子元素的内容可被选中;
- all,元素中的内容需要被整体选中,可以用来模仿原生选中的效果;
- contain,在元素内选择,选区被限制在元素之内,暂无浏览器支持;
- none,元素及其子元素的内容不可选中。
user-select 属性需要注意的点:
- 无论属性值是什么,::before 和 ::after 的内容都表现为 none;
- 没有继承性,那只是初始值 auto 的渲染表现而已。
::section 伪元素可以改变文字被选中后的颜色和背景色(选区)。
1
2
3
4
|
body::section {
background: red;
color: green;
}
|
打印行为
打印页面时隐藏不必要的信息:
1
2
3
4
5
6
7
|
@media print {
header,
footer,
[unnecessary-content] {
display: none;
}
}
|
打印页面时,默认情况下背景色是不打印的(节约墨水),color-adjust 可以用来控制是否打印背景色:
- economy,默认值,浏览器可以对元素进行样式上的调整(怎么调整浏览器自己定);
- exact,不要浏览器对样式进行调整。