关于颜色的书写格式
/* ✅ 逗号分隔,正常工作 */
div {
background-color: rgb(255, 210, 210);
color: hsl(150, 76%, 20%);
}
/* ✅ 空格分隔,正常工作 */
div {
background-color: rgb(255 210 210);
color: hsl(150 76% 20%);
}
/* ✅ hwb和lab必须要用空格分隔 */
div {
background-color: hwb(0deg 82% 0%);
color: lab(33% -31 16);
}
/* ❌ 使用逗号分隔是错误的写法,不会正常工作 */
div {
background-color: hwb(0deg, 82%, 0%);
color: lab(33%, -31, 16);
}
lab()
, hwb()
, lch()
, oklch()
都只支持空格分隔
@layer - Chrome99+
@layer CSS 命令用于声明级联层,并且可以用于定义多个级联层的优先顺序。这样就可以很好的区分组件库的样式权重和自己写的样式权重,不需要再去到处加!important了
/* 首先权重会按照声明的顺序来,后面的权重更高 */
@layer base {
p {
border: 10px solid red;
}
}
@layer framework {
p {
border-color: blue;
}
}
@layer components {
p {
border-color: rebeccapurple;
}
}
@layer theme {
p {
border-color: green;
}
}
/* 当然你可以自定义权重排序,越往后权重越高 */
@layer base, components, theme, framework;
@layer base {
p {
border: 10px solid red;
}
}
@layer framework {
p {
border-color: blue;
}
}
@layer components {
p {
border-color: rebeccapurple;
}
}
@layer theme {
p {
border-color: green;
}
}
/* 但是如果此时出现了一个在这layer之外的样式,则这个外面的样式权重高于在layer之内的 */
p {
/* 生效的是这个 */
border-color: pink;
}
@layer base, components, theme, framework;
@layer base {
p {
border: 10px solid red;
}
}
@layer framework {
p {
border-color: blue;
}
}
@layer components {
p {
border-color: rebeccapurple;
}
}
@layer theme {
p {
border-color: green;
}
}
可以用这个功能来加载组件库的样式
/* 使用@import将整个样式表加载到layer中 */
/* 可以用这种方式去加载组件库的样式 */
@import "theme.css" layer(utilities);
但是写的位置非常的重要,在中有讲到
任何 @import 规则必须位于样式表中所有其他有效的 @规则 和 样式规则之前(忽略 @charset 和空的 @layer 定义),并且在其和前一个 @import 规则之间不能有其他有效的 @规则或样式规则,否则该 @import 规则是无效的。
/* ❌这样写就是无效的 */
@layer third-party, base, components, utility;
@layer base {
body {
/* my custom styles */
}
}
@import url("https://cdn.jsdelivr.net/npm/bootstrap@5.2.3/dist/css/bootstrap.min.css") layer(third-party);
css也想到了肯定有人乱写,比如这样
@layer base, components, theme;
@layer framework, base, components;
base, components都声明了2次,这种情况下以第一次为准,后面的会被忽略,也就成了
@layer base, components, theme;
@layer framework, base, components;
所以framework在更后面出现,framework的权重更高
嵌套写法
要定义嵌套中的layer优先级,就在在嵌套中写
@layer reset, defaults, theme; /* ❌无效 */
/* 一定要写在外面其实也可以,就是要xxx.xxx ✅生效 */
@layer base.reset, base.defaults, base.theme;
@layer base {
@layer reset, defaults, theme; /* ✅生效 */
@layer reset {
p {
background-color: #fff;
}
}
@layer theme {
p {
background-color: aqua;
}
}
@layer defaults {
p {
background-color: red;
}
}
}
优先级可以总结为
单层layer,后面的优先级 > 前面的
嵌套layer,外层的优先级 > 内层的
layer外面的普通css优先级 > layer内的
svh、lvh 和 dvh单位 - Chrome108+
解释:100vh在移动端可能出现不正确的表现,如下图,这时可以使用新的单位
其实和这3个单位一起的还有很多
-
The large viewport units(大视口单位):
lvw``lvh
,lvi
,lvb
,lvmin``lvmax
,前缀是lv
,意为 large viewport
-
The small viewport units(小视口单位):
svw
,svh
,svi
,svb
,svmin``svmax
,前缀是sv
,意为 small viewport
-
The dynamic viewport units(动态视口单位):
dvw
,dvh
,dvi
,dvb
,dvmin``dvmax
,前缀是dv
,意为 dynamic viewport
翻译成人话:
-
大视口(Large Viewport):视口大小假设任何动态扩展和缩回的 UA 界面都收回去了
-
小视口(Small Viewport):视口大小假设任何动态扩展和缩回的 UA 界面都展开了
图片或许能更好理解
理解了大视口与小视口之后,再理解动态视口就轻松了些。
简单而言,动态视口的意思是:
-
动态工具栏展开时,动态视口等于小视口的大小
-
当动态工具栏被缩回时,动态视口等于大视口的大小
因此,也就能得到下面这张图:
和之前的视口单位对标关系比较好理解
新的动态单位 | 以前的单位 |
---|---|
dvh |
vh |
dvw |
vw |
dvmax |
vmax |
dvmin |
vmin |
剩下,dvi
和 dvb
。其实,在之前也有 vi
和 vb
两个单位,主要是和书写方向有关,如果没有书写方向上的需求,可以跳过:
-
vi
:vi 代表 Viewport Inline,代表文档的内联方向。在水平书写方向上,这对应于视口的宽度,而在垂直书写方向上,这表示视口的高度。记住 inline 方向的简单方法是记住它与文本的方向相同。
-
vb
:vb 代表 Viewport block,代表文档的块方向。这与 vi 水平书写方向相反,这将对应于视口高度,而在垂直文档中,这将表示视口的宽度。
总结一下,估计未来dvh将会非常广泛的使用, 如果你希望尝鲜, 可以选择使用polyfill
使用库https://github.com/joppuyo/large-small-dynamic-viewport-units-polyfill
或者如果用的不多, 手写CSS代码
.my-small-hero-element {
width: 100%;
height: 100vh; /* For browsers that don't support CSS variables */
height: calc(var(--1svh, 1vh) * 100); /* This is the "polyfill" */
height: 100svh; /* This is for future browsers that support svh, dvh and lvh viewport units */
}
.my-dynamic-hero-element {
width: 100%;
height: 100vh; /* For browsers that don't support CSS variables */
height: calc(var(--1dvh, 1vh) * 100); /* This is the "polyfill" */
height: 100dvh; /* This is for future browsers that support svh, dvh and lvh viewport units */
}
.my-large-hero-element {
width: 100%;
height: 100vh; /* For browsers that don't support CSS variables */
height: calc(var(--1lvh, 1vh) * 100); /* This is the "polyfill" */
height: 100lvh; /* This is for future browsers that support svh, dvh and lvh viewport units */
}
aspect-ratio - Chrome88+
解释:设置宽高比
/* 将会获得一个最大宽度400px,高度自动与宽度成比例的div */
div {
aspect-ratio: 16 / 9; /* aspect-ratio: 宽/高 */
max-width: 400px;
}
/* 也可以不约分 */
div {
aspect-ratio: 1920 / 1080;
max-width: 400px;
}
/* 如果想写一个正方形,可以写 1 / 1 或者 123 / 123 */
div {
aspect-ratio: 1 / 1;
max-width: 400px;
}
/* 如果只写一个值,则第二个值默认为1 */
div {
/* 等价于aspect-ratio: 5 / 1 */
aspect-ratio: 5;
max-width: 400px;
}
/* 他的优先级并不是很高,如果这样写,将会获得一个250*250的div,比例被忽略 */
div {
aspect-ratio: 16 / 9;
width: 250px;
height: 250px;
}
/* 如果内容比较多,div的高度被内容撑开,比例的设置一样会失效 */
div {
aspect-ratio: 4;
max-width: 400px;
/* 可以利用overflow让div内部出现滚动条,防止比例失效 */
overflow: auto;
}
容器查询 - Chrome106+
解释:实时匹配容器的尺寸
首先,我们都知道媒体查询,他是根据屏幕尺寸
来的
/* 常规写法 */
@media (min-width: 100px) and (max-width: 1900px)
/* Chrome104之后可以写的方便点 */
@media (100px <= width <= 1900px)
容器查询分为两部分
一、 container-type
配合下面这些单位使用
container-type有三个值,用于给一个元素建立容器查询
container-type: normal; /* 默认值,标识不建立容器元素 */
container-type: size; /* 表示水平和垂直方向都建立 */
container-type: inline-size; /* 只在水平方向建立 */
单位名称 | 释义 |
---|---|
cqw | 表示容器查询宽度(Container Query Width)占比。1cqw等于容器宽度的1%。假设容器宽度是1000px,则此时1cqw对应的计算值就是10px |
cqh | 表示容器查询高度(Container Query Height)占比。1cqh等于容器高度的1%。 |
cqi | 表示容器查询内联方向尺寸(Container Query Inline-Size)占比。默认情况下,Inline-Size指的就是水平方向,对应的是宽度,因此,1cqi通常可以看成是容器宽度的1% |
cqb | 表示容器查询块级方向尺寸(Container Query Block-Size)占比。默认情况下,Block-Size指的就是垂直方向,对应的是高度,因此,1cqb通常可以看成是容器高度的1% |
cqmin | 表示容器查询较小尺寸的(Container Query Min)占比,例如容器尺寸是300px*400px,则100cqmin对应的是尺寸较小的宽度300px,而非高度 |
cqmax | 表示容器查询较大尺寸的(Container Query Min)占比 |
从某种程度上讲,cqw、cqh
、cqmin
、cqmax
单位和vw、vh
、vmin
、vmax
单位语法和含义是一致的,只是一个是相对于容器尺寸,另外一个是相对于视区(ViewPort)尺寸。
比如我们有这样一个HTML结构
<div class="container">
<p>内容</p>
</div>
和这样一段css
.container {
container-type: inline-size;
}
.container p {
font-size: 5cqw;
}
此时,p标签中的文字尺寸,将始终占container
宽度的5%,而这个container
的宽度可以是动态的,这样就实现了动态的文字大小。
container-type
可以将一个元素声明为容器元素,有点像定位的时候,要先在外层加上position:relative
的感觉差不多,如果要使用这些容器查询的单位,则需要在外层元素上加上container-type
的声明,这时这些容器查询的单位才知道自己在相对于哪一个元素进行匹配
二、 @container
解释:当元素在某种尺寸时,需要改动很多样式的时候,就可以使用这个规则
/* 他会寻找最近的容器元素进行匹配,也就是最近的声明了container-type的元素 */
/* 如果一直往父级找都没有找到,则匹配视口 */
@container (width < 500px) {
.container p {
background-color: #000;
border-style: dotted;
font-weight: bold;
}
}
和他搭配的还有一个container-name
属性
.container-a {
container-type: inline-size;
container-name: aside;
}
.container-b {
/* 简写 */
container: banner / inline-size;
}
/* 只有container-name为banner的容器元素内的p标签才会字体加粗 */
@container banner (width < 480px) {
p {
font-weight: bold;
}
}