CSS新用法 - 颜色格式、@layer、容器查询、aspect-ratio

关于颜色的书写格式

/* ✅ 逗号分隔,正常工作 */
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在移动端可能出现不正确的表现,如下图,这时可以使用新的单位

CSS新用法 - 颜色格式、@layer、容器查询、aspect-ratio

其实和这3个单位一起的还有很多

  1. The large viewport units(大视口单位):lvw``lvh, lvi, lvb, lvmin``lvmax ,前缀是 lv,意为 large viewport

  1. The small viewport units(小视口单位):svw, svh, svi, svb, svmin``svmax,前缀是 sv,意为 small viewport

  1. The dynamic viewport units(动态视口单位):dvw, dvh, dvi, dvb, dvmin``dvmax,前缀是 dv,意为 dynamic viewport

翻译成人话:

  1. 大视口(Large Viewport):视口大小假设任何动态扩展和缩回的 UA 界面都收回去了

  1. 小视口(Small Viewport):视口大小假设任何动态扩展和缩回的 UA 界面都展开了

图片或许能更好理解

CSS新用法 - 颜色格式、@layer、容器查询、aspect-ratio

理解了大视口与小视口之后,再理解动态视口就轻松了些。

简单而言,动态视口的意思是:

  1. 动态工具栏展开时,动态视口等于小视口的大小

  1. 当动态工具栏被缩回时,动态视口等于大视口的大小

因此,也就能得到下面这张图:

CSS新用法 - 颜色格式、@layer、容器查询、aspect-ratio

和之前的视口单位对标关系比较好理解

新的动态单位 以前的单位
dvh vh
dvw vw
dvmax vmax
dvmin vmin

剩下,dvidvb 。其实,在之前也有 vivb 两个单位,主要是和书写方向有关,如果没有书写方向上的需求,可以跳过:

  • 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、cqhcqmincqmax单位和vw、vhvminvmax单位语法和含义是一致的,只是一个是相对于容器尺寸,另外一个是相对于视区(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;
  }
}

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

CSS新用法 - color-scheme、accent-color、revert、revert-layer、独立的transform

2024-6-6 11:28:23

技术教程

CSS新用法 - font-variation-settings、!important、hwb()、lab()、lch()、oklab()、oklch()

2024-6-6 11:32:45

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