CSS新用法 - min()、max()、clamp()、:where()、:is()、:has()

CSS新用法 - min()、max()、clamp()、:where()、:is()、:has()

min() - Chrome79+

解释:一行代码设置宽度和最大宽度

/* 这个例子没什么意义,因为最小值永远都是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;
}

既然能选中前一个元素了,那就能实现一些更炫酷的效果

 

​​

既然能选中前一个元素了,那就能实现一些更炫酷的效果

给TA打赏
共{{data.count}}人
人已打赏
技术教程

CSS新用法 - :modal、::backdrop、:picture-in-picture、:placeholder-shown、inset、scrollbar-gutte、backdrop-filter

2024-6-6 11:35:14

技术教程

CSS 专业技巧

2024-6-6 11:46:08

0 条回复 A文章作者 M管理员
    暂无讨论,说说你的看法吧
个人中心
购物车
优惠劵
今日签到
有新私信 私信列表
搜索