At-rules是 CSS 规则的重要组成部分,根据我的经验,平时在工作中用到的不算多,但未来,随着 CSS 规模化的发展,这些规则的使用将越来越重要,接下来让我们看一下这些规则吧!
什么是At-rules?
At-rules是一个 CSS 语句,用来指示 CSS 如何运行。以 @ 符号开头,'@' 后跟一个标识符,并包括直到下一个分号的所有内容,或下一个 CSS 块,以先到者为准。
有哪些@规则?
@charset、@color-profile、@container、@counter-style、@font-face、@font-feature-values、@font-palette-values、@import、@keyframes、@layer、@media、@namespace、@page、@property、@supports
如果按实用的程度来划分,它们可以被划分成三个梯队
- 第一梯队:@counter-style、@font-face、@import、@keyframes、@layer、@media、@property、@supports
- 第二梯队:@charset、@color-profile
- 第三梯队:@container、@font-feature-values、@font-palette-values、@namespace、@page
但本文并不会以实用程度的顺序来介绍这些规则,因为有些规则虽然不实用,但它们却很重要!
下面我们分别来看看这些规则吧!
@charset
指定样式表中使用的字符编码。
理解这句话的核心在于,我们要知道,字符编码方式是由多种方法(多个地方)来指定的,浏览器会按照以下顺序指定样式表的字符编码:
- 文件的开头的 Unicode byte-order 字符值
- 由 Content-Type:HTTP header 中的 charset 属性给出的值或用于提供样式表的协议中的等效值
- CSS @charset规则
- 默认值(UTF-8)
其中有两个重要概念:
- Unicode byte-order 字符值:是通过在文件开头插入一个特殊的标记来指定的,通常情况下,它是一个不可见的字符,只有在某些文本编辑器中才能看到它。
- Content-Type:是HTTP协议中的一个请求头或响应头,用于指示实体主体的媒体类型,它的句法中包含了media-type、charset和boundary 。
CSS @charset规则只是指定样式表的字符编码方式的其中之一。
@color-profile
定义并命名颜色配置文件(icc文件,也叫色彩空间),该配置文件稍后可在color()函数中使用以指定颜色。
对于色彩空间,可以理解为,RGB是由红、绿、蓝三种颜色来组合的,同样的 RGB 分量,在不同的色彩空间中所代表的颜色是不一样的,所以,我们在描述一个 RGB 颜色的时候,不仅需要描述它的 RGB 三个分量,还要说明是在哪个空间,这就是 ICC 文件的作用。
常见的色彩空间有 sRGB 和 Adobe RGB,网络环境中图片的色彩空间通常是 sRGB,很多浏览器不能正确地解析图片自带的色彩空间说明,默认按照 sRGB 来进行解析(用默认值就足够了,所以此规则一般也用不到)。
对于色彩空间标准的原理及定义,少侠请看:
@container
实时匹配容器尺寸,根据不同尺寸范围,对容器内样式实现不同布局。
该规则与@media类似,只不过@media匹配的是浏览器窗体,而@container匹配的是某个元素。
目前该规则几乎没有应用场景,且在vscode中根本无法识别此规则语法 ,最主要的原因是:该规则仍未在所有浏览器中完全支持。
vscode的警告:
stack overflow上关于为什么报警告的解答:
@counter-style
用于自定义计数器的样式。 以前的计数器样式有两种指定方式:
- html中的type属性(少侠请看:developer.mozilla.org/zh-CN/docs/...
- css中的list-style-type属性(少侠请看:developer.mozilla.org/zh-CN/docs/...)
但随着发展,这一系列计数器样式已经不能满足全球化的排版了,所以出来第三种方式,即通过@counter-style 规则自定义计数器样式。
使用举例:
html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<style>
@counter-style my-couter {
system:cyclic;/* 循环规则 */
symbols:😊; /* 自定义符号 */
}
ol{
list-style-type: my-couter;
}
</style>
<body>
<ol>
<li>第一行</li>
<li>第二行</li>
<li>第三行</li>
<li>第四行</li>
</ol>
</body>
</html>
效果如下:
关于CSS @counter-style规则详细介绍,少侠请看:www.zhangxinxu.com/wordpress/2...
@font-face
用于自定义字体,首先你得获取一份字体文件。
字体文件有哪些?
- TrueType字体文件(TTF):这是一种常见的字体文件格式,被广泛用于Windows和Mac操作系统中
- OpenType字体文件(OTF):这是一种新型的字体文件格式,由Adobe和Microsoft共同开发,支持更多的字形和特性
- PostScript字体文件(PS):这种字体文件格式由Adobe开发,通常用于印刷和排版领域
- Web字体文件(WOFF、WOFF2、EOT):这些字体文件格式是为了在网页上使用而开发的,能够提供更好的排版效果和可访问性
- Bitmap字体文件(FON、BMP):这种字体文件格式使用像素点来表示字形,通常用于早期的计算机系统中
- 软件自带字体文件(例如Windows自带的宋体、黑体等):这些字体文件是操作系统或软件自带的,可以直接在系统或软件中使用
字体文件可以在阿里巴巴矢量图标库中下载。
使用举例:
html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style>
/* 自定义字体规则 */
@font-face {
font-family: iconfont; /* 自定义字体名称 */
src: url("iconfont.ttf"); /* 引入字体文件 */
}
/* 给元素使用自定义字体 */
.iconfont {
font-family: "iconfont" !important;
font-size: 30px;
color: blue;
}
</style>
</head>
<body>
<div>
<!-- 定义字体内容 -->
<span class="iconfont"></span>
</div>
</body>
</html>
效果如下:
@font-feature-values
用于对字体功能的拓展,为自定义字体设置特定的字体功能值,这些功能值可以控制字体的外观和行为,如字母之间的间距、连字、大小写变化等,更精细化地控制了字体的外观和行为,从而实现更好的排版效果。
此规则使用场景很少,基本用不到它,就不介绍了。
@font-palette-values
允许定义一组字体颜色值,并将其分配给一个变量名,这个变量名可以在整个CSS文件中使用,从而简化了CSS编写和维护的工作。
此规则使用场景很少,且在vscode中根本无法识别此规则语法,和@container规则一样,最主要的原因也是:该规则仍未在所有浏览器中完全支持。
@import
用于导入一个或多个CSS文件。
使用举例截图:
@keyframes
定义一个动画序列,包含一系列关键帧 (即动画的不同状态),然后通过动画属性将这些关键帧连接起来,形成一个流畅的动画效果。
使用此规则的关键点:
- 可以按任意顺序列出关键帧百分比,它们将按照其应该发生的顺序来处理。
- 关键帧中出现的 !important 将会被忽略。
- 如果一个关键帧规则没有指定动画的开始或结束状态(也就是,0%/from 和100%/to),浏览器将使用元素的现有样式作为起始/结束状态,这可以用来从初始状态开始元素动画,最终返回初始状态。
- 如果在关键帧的样式中使用了不能用作动画的属性,那么这些属性会被忽略掉,支持动画的属性仍然是有效的,不受波及。
- 如果多个规则使用同一个名称,以最后一次定义的为准。
- 如果一个 @keyframes 内的关键帧的百分比存在重复的情况,则 @keyframes 规则中该百分比的所有关键帧都将用于该帧。
- 如果某一个关键帧出现了重复的定义,且重复的关键帧中的 CSS 属性值不同,则以最后一次定义的属性(重复的)为准。
用动画实现的一个文字循环轮播例子:
html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>无限循环文字轮播</title>
<style>
@keyframes myAnimate1 {
from{
transform: translateX(0);
}
33.33%{
transform: translateX(-100%);
}
50%{
transform: scale(0) translateX(-100%);
}
66.66%{
transform: translateX(100%);
}
to{
transform: translateX(0);
}
}
@keyframes myAnimate2 {
from{
transform: translateX(100%);
}
33.33%{
transform: translateX(0%);
}
66.66%{
transform: translateX(-100%);
}
70%{
transform: scale(0) translateX(-100%);
}
to{
transform: translateX(100%);
}
}
@keyframes myAnimate3 {
from{
transform: translateX(-100%);
}
10%{
transform:scale(0) translateX(0%);
}
33.33%{
transform: translateX(100%);
}
66.66%{
transform: translateX(0%);
}
to{
transform: translateX(-100%);
}
}
.main{
position: relative;
overflow: hidden;
width: 800px;
height: 50px;
padding: 5px;
border: 1px solid black;
}
.test1{
/* 30s 匀速的 无限循环播放动画 */
animation: myAnimate1 30s linear infinite;
white-space: nowrap;
background-color: bisque;
position: absolute;
}
.test2{
animation: myAnimate2 30s linear infinite;
white-space: nowrap;
background-color: bisque;
position: absolute;
}
.test3{
animation: myAnimate3 30s linear infinite;
white-space: nowrap;
background-color: bisque;
position: absolute;
}
</style>
</head>
<body>
<div class="main">
<p class="test1">消息通知功能验证 zh 通知:Hi,ALL,远程检测中国站点于今天2019-07-18 22:00~24:00发布新版本Remote-Service V3.0.0.310,将尽快恢复!</p>
<p class="test2">消息通知功能验证 zh 通知:Hi,ALL,远程检测中国站点于今天2019-07-18 22:00~24:00发布新版本Remote-Service V3.0.0.310,将尽快恢复!</p>
<p class="test3">消息通知功能验证 zh 通知:Hi,ALL,远程检测中国站点于今天2019-07-18 22:00~24:00发布新版本Remote-Service V3.0.0.310,将尽快恢复!</p>
</div>
</body>
</html>
@layer
声明了一个 级联层,同一层内的规则将级联在一起,这给予了开发者对层叠机制的更多控制,且使用此规则可以有效摒弃大规模使用 !important 去覆盖样式优先级的错误做法。
使用举例:
html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style>
/* 根据层级申明顺序, A层级中的样式优先级高于B */
@layer B,A;
@layer A{
div{
color: blue;
}
}
@layer B{
div{
color: green;
}
}
</style>
</head>
<body>
<div>我是内容</div>
</body>
</html>
非 @layer 包裹的样式,拥有比 @layer 包裹样式更高的优先级。
更多关于使用@layer后的样式优先级规则,少侠请看:github.com/chokcoco/iC...
@media
用于设置在不同媒体类型下不同的样式,通过@media规则,可以根据设备的屏幕尺寸、颜色、分辨率等特性,为不同的设备提供不同的样式。
使用举例:
html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>媒体查询</title>
<style>
@media screen and (min-width:1000px) {
div{
font-size: 20px;
}
}
</style>
</head>
<body>
<div>我想在屏幕大于1000px的时候,字体大小变成20px.</div>
</body>
</html>
@namespace
用来定义使用在 CSS 样式表中的 XML 命名空间,定义的命名空间可以把通配、元素和属性选择器限制在指定命名空间里的元素。
为什么要定义命名空间 :少侠请看:juejin.cn/post/727898...
为什么命名空间要用url定义:因为URL是唯一的标识符,可以确保在全球范围内的唯一性。通过使用URL作为命名空间的标识符,可以确保在不同的文档和应用程序之间使用相同的命名空间,从而保证了数据的一致性和可重用性。
在现如今的 CSS 生态中,它属于非常冷门的一个规则,基本用不到。
@page
用于在打印文档时修改某些 CSS 属性,它可以设置页面的大小、边距、页眉、页脚等属性,以便在打印时能够得到所需的布局和样式。
@property
用于自定义 CSS 属性,允许进行属性类型检查、设定默认值以及定义该自定义属性是否可以被继承(比老的"自定义css属性"更加丰富,功能更多)。
使用举例:
html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>css自定义属性</title>
<style>
@property --my-color { /* 属性名要加上-- */
syntax: "<color>"; /* 支持的语法类型,其值有:length、number、color等 */
inherits: false; /* 是否继承 */
initial-value: red; /* 默认值 */
}
div{
color: var(--my-color);
}
</style>
</head>
<body>
<div>我是测试数据</div>
</body>
</html>
如果想了解此规则更多的用法,少侠请看:github.com/chokcoco/iC...
@supports
用于指定一个或多个特定的 CSS 功能的支持声明,它允许您检查浏览器是否支持某些CSS属性或值,然后根据结果应用不同的样式。
使用举例:
html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style>
/* 根据当前浏览器是否支持position:sticky属性,采用不同的定位方式 */
div {
position: fixed;
}
@supports (position:sticky) {
div {
position:sticky;
}
}
</style>
</head>
<body>
<div>我是测试数据</div>
</body>
</html>
总结
- 常见且好用的规则有:@counter-style、@font-face、@import、@keyframes、@layer、@media、@property、@supports。
- 重要但没必要使用的规则有:@charset、@color-profile。
- 基本不怎么使用的规则有:@container、@font-feature-values、@font-palette-values、@namespace、@page。
最初的CSS只支持一些基本的选择器和属性,没有At-rules,随着CSS的不断发展,At-rules的数量和功能也在不断增加,为开发者提供了更多的控制和灵活性。
随着CSS使用场景越来越多 ,规模越来越大,这些规则必将在更多的场景中被使用,特别是@keyframes规则,用好了有大用!
作为前端开发,不应该错过任何一次学习和使用这些规则的机会!