首页 > 其他分享 >现代 CSS 指南 -- at-rule 规则扫盲

现代 CSS 指南 -- at-rule 规则扫盲

时间:2022-11-03 10:34:21浏览次数:95  
标签:layer -- prefers counter rule 规则 CSS

大部分同学都用过 CSS 的屏幕宽度媒体查询,像是这样:

@media screen and (min-width: 900px) {
  div {
    padding: 1rem 3rem;
  }
}

这里表示的是与屏幕宽度相关的样式设置,上面的代码表示当屏幕宽度大于 900px 时,内部的样式代码块才能生效。

其实不仅仅是上面的屏幕宽度媒体查询,在 CSS 中,存在大量的以 @ 符号开头的规则。称之为 @规则(at-rule)。本文就将介绍一下除去媒体查询之外,其他有意思的且在未来会越来越重要的 @规则 规则。

at-rule @规则

OK,什么是 @规则(at-rule )呢?

一个 at-rule 是一个 CSS 语句,以 at 符号开头, '@' (U+0040 COMMERCIAL AT), 后跟一个标识符,并包括直到下一个分号的所有内容, ';' (U+003B SEMICOLON), 或下一个 CSS 块,以先到者为准。

除去我们最为熟悉的 @media 之外,CSS 还有哪些 @规则 呢?

下面是一些 @规则,由它们的标示符指定,每种规则都有不同的语法:

  • @charset, 定义样式表使用的字符集。
  • @import, 告诉 CSS 引擎引入一个外部样式表。
  • @namespace, 告诉 CSS 引擎必须考虑 XML 命名空间。

下面是一些嵌套 @ 规则,是嵌套语句的子集,不仅可以作为样式表里的一个语句,也可以用在条件规则组里:

  • @media,如果满足媒介查询的条件则条件规则组里的规则生效。

  • @page,描述打印文档时布局的变化。

  • @font-face,描述将下载的外部的字体。

  • @keyframes,描述 CSS 动画的中间步骤。

  • @supports, 如果满足给定条件则条件规则组里的规则生效。

  • @document,如果文档样式表满足给定条件则条件规则组里的规则生效。 (推延至 CSS Level 4 规范)

  • @viewport (已废弃),规则让我们可以对文档的大小进行设置。这个特性主要被用于移动设备,但是也可以用在支持类似“固定到边缘”等特性的桌面浏览器,如微软的 Edge。

  • @counter-style — 一个 @counter-style 规则定义了如何把一个计数器的值转化为字符串表示。

  • @font-feature-values (plus @swash@ornaments@annotation@stylistic@styleset and @character-variant), 允许作者在font-variant-alternates 中使用通用名称,用于在 OpenType 中以不同方式激活功能。它允许在使用几种字体时简化 CSS。

  • @property (实验性),是CSS Houdini API 的一部分,它允许开发者显式地定义他们的css 自定义属性, 允许进行属性类型检查、设定默认值以及定义该自定义属性是否可以被继承。

  • @layer, 声明了一个 级联层,同一层内的规则将级联在一起,这给予了开发者对层叠机制的更多控制。

除去我们非常熟悉的 @mediakeyframes 以及 @font-face,像是 @supports@counter-style@property@layer 等都已经或将在未来 Web 应用中扮演举足轻重的作用。

下面,就跟随本文,一起对它们一探究竟。你也可以跳过你已经掌握的,翻到对应你还不太了解的 @ 规则下,迅速了解它们。

@charset、@import、@namespace

这三个可以放在一起讲解,他们的语法比较简单,也相对好理解。其中:

  1. @charset:指定样式表中使用的字符编码。它必须是样式表中的第一个元素,而前面不得有任何字符。

像是这样:

// style.css
@charset "UTF-8";

注意,如果有多个 @charset @规则被声明,只有第一个会被使用。

很多人会有疑惑,这个声明到底有什么用呢?

事实上,如果 CSS 文件中有任何非 ASCII 文本,例如字体名称,伪元素的 content 属性值、选择器等中的非 ASCII 字符,都需要确保 CSS 解析器知道如何转换字节正确转换为字符,以便它理解 CSS 代码。

所以如果当你发现你的伪元素 content 中插入了一些内容,但是经过打包编译后它乱码了,很有可能是因为你忘了声明这个字符集。

  1. @import:用于从其他样式表导入样式规则。这些规则必须先于所有其他类型的规则,@charset 规则除外

@import 有两种语法:

  1. url() 内包含 style sheet 的 URI
  2. 直接写 style sheet 的 URI 的字符串

还可以直接在后面定义媒体查询规则,像是这样:

@import 'custom.css';
@import url('landscape.css');
@import url('landscape.css') screen and (orientation:landscape);

合理的使用 @import 其实也是有好处的:

  1. 可以合理的控制 CSS 文件的大小
  2. 更好的分治与复用

很多人可能会经常看到,网络上会有各种抵制 @import的文章,不过既然设计了 @import,总有它的有用之处,不能过于绝对。使用 @import 影响页面性能的地方主要体现在两个方面:

  1. 影响浏览器的并行下载
  2. 优先级问题,样式互相覆盖
  3. 导致页面闪烁

这里可以简单解释一下。首先我们得知道,加载页面时,link 标签引入的 CSS 被同时加载,而 @import 引入的 CSS 将在页面加载完毕后被加载。

CSS 解析引擎在对一个 CSS 文件进行解析时,如在文件顶部遇到 @import 规则,将被替换为该 @import 导入的 CSS 文件中的全部样式。而 @import 内的规则其后被加载,却会在加载完毕后置于样式表顶部,最终渲染时,如果存在同名同优先级样式,会被下面的同名样式层叠,导致所谓的优先级冲突。

实际上,浏览器渲染的动作一般会执行多次的。最后一次渲染,一定是基于之前加载过的所有样式整合后渲染树进行绘制页面的,
而由于 @import 内的规则的加载时机问题,会在页面内容加载完后再加载。相当于把 CSS 放在了 body 底部,从而造成了页面的闪烁。当网络较差时,闪烁体验更为明显。

  1. @namespace@namespace 是用来定义使用在 CSS 样式表中的 XML 命名空间的 @规则。定义的命名空间可以把通配、元素和属性选择器限制在指定命名空间里的元素。

并且,任何 @namespace 规则都必须在所有的 @charset@import规则之后,并且在样式表中,位于其他任何样式声明之前。

总的来说,@namespace 在现如今的 CSS 生态中,属于非常冷门的一个规则。基本上我从业这么久,没怎么见过这个属性的具体使用。

如果你对它确实感兴趣,可以看看这篇详解 -- spacing-out-on-css-namespaces.

@media@keyframes@font-face

这三个 @ 规则,大家应该非常熟悉。

  • @media:如果满足媒介查询的条件则条件规则组里的规则生效
  • @keyframes:定义 CSS 动画的中间步骤
  • @font-face:描述将下载的外部的字体

@keyframes@font-face 这两个大家肯定非常熟悉。

但是 @media 其实内有乾坤!除了屏幕宽度媒体查询外,其实还存在非常多不同功能的媒体查询!

下面我会列出一些在未来,我认为会越来越被提及使用到的 @media 规则。

prefers-reduced-motion 减弱动画效果

prefers-reduced-motion 规则查询用于减弱动画效果,除了默认规则,只有一种语法取值 prefers-reduced-motion: reduce,开启了该规则后,相当于告诉用户代理,希望他看到的页面,可以删除或替换掉一些会让部分视觉运动障碍者不适的动画类型。

规范原文:Indicates that user has notified the system that they prefer an interface that removes or replaces the types of motion-based animation that trigger discomfort for those with vestibular motion disorders.

vestibular motion disorders 是一种视觉运动障碍患者,中文我只能谷歌翻译,翻译出来是前庭运动障碍,我感觉不太对,谷歌了一下是一种会导致眩晕的一类病症,譬如一个动画一秒闪烁多次,就会导致患者的不适。

使用方法,还是上面那段代码:

.ele {
    animation: aniName 5s infinite linear;
}

@media (prefers-reduced-motion: reduce) {
    .ele {
        animation: none;
    }
}

如果我们有一些类似这样的动画:

在用户开启了 prefers-reduced-motion: reduce 时,就应该把它去掉。那么该如何开启这个选项呢?MDN -- prefers-reduced-motion 给出的是:

  • 在 GTK/Gnome 中,可以通过 GNOME Tweaks (在“通用”或“外观”菜单中,取决于具体版本) 的配置,设置 gtk-enable-animations 的值为 false
  • 可以在 GTK 3 的配置文件中的 [Settings] 模块下设置 gtk-enable-animations = false
  • 在 Windows 10 中:设置 > 轻松获取 > 显示 > 在 Windows 中显示动画
  • 在 Windows 7 中:控制面板 > 轻松获取 > ?是计算机更易于查看 > 关闭不必要动画
  • 在 MacOS 中:系统偏好 > 辅助使用 > 显示 > 减少运动
  • 在 iOS 上:设置 > 通用 > 辅助性 > 减少运动
  • 在 Android 9+ 上:设置 > 辅助性 > 移除动画

prefers-color-scheme 适配明暗主题

prefers-color-scheme 还是非常好理解的,它用于匹配用户通过操作系统设置的明亮或夜间(暗)模式。它有两个不同的取值:

  • prefers-color-scheme: light: 明亮模式
  • prefers-color-scheme: dark: 夜间(暗)模式

语法如下,如果我们默认的是明亮模式,只需要适配夜间模式即可:

body {
    background: white;
    color: black;
}

@media (prefers-color-scheme: dark) {
    body {
        background: black;
        color: white;
    }
}

当然,上述只是 CSS 代码示意,要做到两套主题的切换肯定不是这么简单,方法也很多,本文不赘述,读者可以自行了解各种实现主题切换,或者是明暗切换的方案。

prefers-contrast 调整内容色彩对比度

prefers-contrast 该 CSS 媒体功能是用来检测用户是否要求将网页内容以更高或者更低的对比度进行呈现。其中:

  • prefers-contrast: no-preference:默认值,不作任何变化
  • prefers-contrast: less:希望使用对比度更低的界面
  • prefers-contrast: more:希望使用对比度更高的界面

prefers-contrast: less 为例子,语法如下:

body {
    background: #fff; // 文字与背景对比度为 5.74
    color: #666;
}

// 提升对比度
@media (prefers-contrast: more) {
    body {
        background: #fff; // 文字与背景对比度为 21
        color: #000;
    }
}

上面只是伪 CSS 代码,具体可能需要对具体的一些元素进行处理,或者使用 filter: contrast() 全局统一处理,当开启配置时,用于实现类似这样的功能:

什么是色彩对比度

是否曾关心过页面内容的展示,使用的颜色是否恰当?色弱、色盲用户能否正常看清内容?良好的色彩使用,在任何时候都是有益的,而且不仅仅局限于对于色弱、色盲用户。在户外用手机、阳光很强看不清,符合无障碍标准的高清晰度、高对比度文字就更容易阅读。

这里就有一个概念 -- 颜色对比度,简单地说,描述就是两种颜色在亮度(Brightness)上的差别。运用到我们的页面上,大多数的情况就是背景色(background-color)与内容颜色(color)的对比差异。

最权威的互联网无障碍规范 —— WCAG AA规范规定,所有重要内容的色彩对比度需要达到 4.5:1 或以上(字号大于18号时达到 3:1 或以上),才算拥有较好的可读性。

prefers-reduced-transparency 减少透明元素

prefers-reduced-transparency 该 CSS 媒体功能是用来检测用户是否要求减少网页中的透明元素:

  • prefers-contrast: no-preference:默认值,不作任何变化
  • prefers-contrast: reduce:希望界面元素存在尽可能少的透明元素

prefers-contrast: reduce 为例子,语法如下:

.ele {
    opacity: 0.5;
}

// 减少透明元素
@media (prefers-contrast: reduce) {
    .ele {
        opacity: 1;
    }
}

我在上一次,介绍这个功能的时候,它还是一片红色,但是短短半年,整个兼容性已经有了很大的提升!

prefers-reduced-data 减少数据传输

对于部分网速较差的地区,或者流量很贵的情况,用户会希望减少页面中的流量请求,基于此有了 prefers-reduced-data

prefers-reduced-data 该 CSS 媒体查询功能是用于告知用户代理,希望减少页面的流量请求。

  • prefers-reduced-data: no-preference:默认值,不作任何变化
  • prefers-reduced-data: reduce:希望界面元素消耗更少的互联网流量

prefers-reduced-data: reduce 为例子,语法如下:

.ele {
    background-image: url(image-1800w.jpg);
}

// 降低图片质量
@media (prefers-reduced-data: reduce) {
    .ele {
        background-image: url(image-600w.jpg);
    }
}

当检测到用户开启了 prefers-reduced-data: reduce,我们将提供压缩度更高,尺寸更小,消耗流量更少的图片。

当然,上述代码只是个示意,我们可以做的其实有更多。

不过,这是仍处于实验室的功能,暂时没有任何浏览器支持该媒体查询~

标签:layer,--,prefers,counter,rule,规则,CSS
From: https://www.cnblogs.com/coco1s/p/16853591.html

相关文章

  • 2022-11-03 v-html will override element children.
    v-htmlwilloverrideelementchildren. v-html将覆盖元素子级。源代码:<divv-html="title"class="title">{{title}}</div>原因:使用了v-html的标签,该标签里面不能......
  • 【AcWing-Linux】04. SSH
    SSH(SecureShell,安全外壳协议)一、SSH简介SSH为建立在应用层和传输层基础上的安全协议(对数据进行加解密),专为远程登录会话和其他网络服务提供安全性的协议,可以有效防止......
  • A Framework for Multiple-Instance Learning的复现与思考
    思考1.任何都是基于假设去处理数据。本文的假设就是出现一点在正包的交点中。假设是正包交于一点且该点距离所有的包距离最短。遇到的问题:1.我想找一点尽可能降低该点......
  • win7安装node高版本
    1.通过nvm-win下载不同版本的node2.nvmuse[version]切换版本,运行node,结果如下:3.在win7系统环境变量中新建环境变量NODE_SKIP_PLATFORM_CHECK,值为1,记得保存4.运行n......
  • 看IE版本号
    https://xinzhi.wenda.so.com/a/1521774086208433开始菜单中打开IE浏览器。ie内核_2022新版下载查看详情>>广告2点击“设置”按钮,找到“关于InternetExplorer”......
  • odoo16,windows开发环境搭建
    python3.7pipinstall-r requirements.txtPostgreSQL >12   https://www.cnblogs.com/inpool/p/pg-lite.htmlPostgreSQLForWindows全功能绿色精简版  默......
  • fiddler的基础操作
    接口的组成url+请求方式+响应=接口(url+域名+端口号+方法名+入参)请求方法:post/get请求参数:username、password、tel、idcard入参类型:json、xml、form返回:状态码(code)+......
  • laravel入门教程(一)
    laravel入门教程(一)本教程是针对laravel5来讲解的####0.1、一个简单的示例//文件:routes/web.php<?phpRoute::get('/','WelcomeController@index');//文件:app/Http/Contro......
  • 跟炒鸡辣鸡一起学用go写游戏后端2
    上回说完了采用何种方式与前端进行交互,这次来说说使用何种形式的数据格式与前端进行交互。也就是通常所说的protocol(协议)。目前,比较主流的是json和xml的方式,不过鉴于游戏......
  • springboot javax.servlet.Filter使用
    请求拦截器优点:1、拦截非法请求重定向2、验证用户token下面是demo程序,有问题的可以在评论区留言@WebFilter(filterName="authenticationFilter",urlPatterns={"/user/*......