解释:一行代码设置宽度和最大宽度
/* 这个例子没什么意义,因为最小值永远都是200px */
div {
width: min(400px, 200px, 300px);
}
/* 如果100%比较小,那就是100%,如果800px比较小,则为800px */
/* 800px或者更小(比如100%代表700px,那就是700px),无最小宽度 */
div {
width: min(100%, 800px);
}
/* 大概就是下面这个意思 */
div {
width: 100%;
max-width: 800px;
}
max() - Chrome79+
解释:一行代码设置宽度和最小宽度
/* 表示如果50vw小于300px,则width匹配300px,如果50vw大于 300px,则匹配50vw */
/* 300px或者更大,无最大宽度 */
div {
width: max(300px, 50vw);
}
/* 大概就是下面这个意思 */
div {
min-width: 300px;
width: 50vw;
}
clamp() - Chrome79+
解释:一行代码设置宽度、最小宽度、最大宽度,三个参数:最小值、首选值和最大值
/* 宽度为90%,最小不会低于300px,最大不会高于700px */
div {
width: clamp(300px, 90%, 700px);
}
/* 大概就是下面这个意思 */
div {
width: 90%;
min-width: 300px;
max-width: 700px;
}
/* 当然你也可以写成这样让你的代码更加难以阅读 */
div {
width: max(300px, min(90%, 700px));
}
可以在min()、max()、clamp()中直接写数学表达式,不需要再嵌套calc()
div {
border: max(20px, calc(1vw + 10px)) solid;
}
/* 上面这样写,等价于下面这样 */
div {
border: max(20px, 1vw + 10px) solid;
}
/* 或者使用变量 */
.var {
--extra: 10px;
border-width: max(20px, 1vw + var(--extra));
}
/* 纯算也是可以的 */
div {
width: clamp(50px * 4 * 1.5, (100% / 2) * 2, 400px * 2);
}
:where()和:is() - Chrome88+
解释:a里面的b,a里面的c,a里面的d,都是同样是样式,即可使用。二者的区别后面会说
/* 之前 */
input[type="text"],
input[type="email"],
input[type="url"],
input[type="tel"],
input[type="password"],
input[type="search"] {
border: 2px solid;
}
/* 使用where */
input:where(
[type="text"],
[type="email"],
[type="url"],
[type="tel"],
[type="password"],
[type="search"]
) {
border: 2px solid;
}
/* 使用:is() */
a:is(:link, :visited) {
color: green;
}
a:is(:hover, :focus) {
text-decoration: none;
}
二者作用完全一样,区别在选择器的优先级上,where的括号中写的再多优先级也是0,但是is的是由括号内选择器的优先级决定的
/* 权重: 0 0 1 (0 id选择器, 0 类选择器, 1 标签选择器) */
button:where(.button1) {
background-color: rebeccapurple;
}
/* 权重: 0 1 1 (0 id选择器, 1 类选择器,也就是is括号里的, 1 标签选择器,也就是最前面的button) */
button:is(.button2) {
background-color: rebeccapurple;
}
has、where、is选择器更加的宽容,即使在部分语法错误的前提下,也能让语法正确的部分正常生效
/* 全部失效:因为并不存在touch,因为这个错误的touch,导致hover和focus即使写对了也无效 */
.button:hover,
.button:focus,
.button:touch {
background-color: #09f;
}
/* 会忽略掉错误的,hover和focus可以正常生效,touch会被忽略 */
button:where(:hover, :focus, :touch) {
background-color: #09f;
}
:has()和一些奇特的操作 - Chrome105+
解释:当a里面有b时,a的样子是……
<div class="box">
<p class="children">
<span>测试</span>
</p>
</div>
<div class="foo">
</div>
/* 无关紧要的默认样式 */
.box,
.foo {
width: 200px;
height: 200px;
}
.foo {
background-color: #000000;
}
/* 如果.box里面有.children的元素,则.box的颜色为#b5b7ff */
.box:has(.children) {
background-color: #b5b7ff;
}
/* 但是has()不能嵌套使用 */
/* 下面的写法是无效的 */
.box:has(p:has(span)) {
font-size: 14px;
}
/* 但是可以使用正常的选择器 */
/* 下面的写法是有效的 */
.box:has(p span) {
font-size: 14px;
}
/* 甚至有更多的用法 */
/* .box的下边距为16px */
.box {
margin-bottom: 16px;
}
/* 如果.box的兄弟是.foo,则下边距为200px,文字大小变为32px */
.box:has(+ .foo) {
margin-bottom: 200px;
font-size: 32px;
}
/* 无效:只适用于实际元素,不适用于伪元素 */
p:has(::before) {
background-color: #f00;
}
优先级与:is()相同,是由括号内选择器的优先级决定的,详见
比较奇特的操作01
我们可以利用has(),实现“当a里面有n个xxx的时候,a的样子是xxx”
/* 这样写,将会在ul里面大于等于3个元素的时候,ul出现一个红色边框 */
ul:has(>:nth-child(3)) {
border: 10px solid red;
}
/* 这样写,将会在ul里面只有3个元素的时候,ul出现一个红色边框 */
ul:has(>:nth-child(3):last-child) {
border: 10px solid red;
}
比较奇特的操作02
我们可以利用has(),实现类似“hover到a元素的时候,a的前一个元素的样子是xxx”
<button>第一个</button>
<button>第二个</button>
<button>第三个</button>
/* 当前hover的样式 */
button:is(:hover, :focus-visible) {
outline: 5px solid #649;
}
/* hover某一个时,后一个的样式 */
button:is(:hover, :focus-visible)+button {
outline: 5px dashed #f00;
}
/* hover某一个时,前一个的样式 */
button:has(+ button:is(:hover, :focus-visible)) {
outline: 5px dotted #ff69b4;
}
既然能选中前一个元素了,那就能实现一些更炫酷的效果