原生CSS嵌套简介
嵌套是使用Sass等CSS预处理器的核心原因之一。现在,该功能已经以类似的语法出现在标准浏览器CSS中。你能否在构建系统时放弃对预处理器的依赖?
CSS嵌套可以节省输入时间,并使语法更易于阅读和维护。迄今为止,你必须像这样键入完整的选择器路径:
.parent1 .child1,
.parent2 .child1 {
color: red;
}
.parent1 .child2,
.parent2 .child2 {
color: green;
}
.parent1 .child2:hover,
.parent2 .child2:hover {
color: blue;
}
现在,你可以将子选择器嵌套在父选择器中,比如:
.parent1, .parent2 {
.child1 {
color: red;
}
.child2 {
color: green;
&:hover {
color: blue;
}
}
}
你可以嵌套任意层级的选择器,但要注意不要超过两到三级。嵌套层级没有技术层面的限制,但是会让代码更难阅读,并且让最终CSS变得很冗长。
直到2023年四月,暂没有浏览器支持CSS嵌套语法。你需要使用 CSS 预处理器(如 Sass、Less 或 PostCSS)进行构建步骤,以便将嵌套代码转换为常规的全选择器语法。嵌套功能现已在Chrome 112+和Safari 16.5+中实现,Firefox将在2023年晚些时候提供支持。
CSS原生嵌套规则
你可以将任何选择器嵌套到另一个选择器中,但必须以符号开头,如&,.(用于HTML class),#(用于HTML id),@(用于媒体查询),:,::,*,+,~,>,或 [。换句话说,它不能直接引用HTML元素。下面的代码无效,<p>选择器不会被解析:
.parent1 {
/* FAILS */
p {
color: blue;
}
}
修复该问题最简单的方法就是使用&,其与Sass相同的方式引用当前选择器:
.parent1 {
/* WORKS */
& p {
color: blue;
}
}
或者,可以这么解决:
> p- 但这将仅对.parent1的直接子元素进行样式调整:is(p)- 但是:is()使用最优先选择器的优先级:where(p)- 但是:where()的优先级为0
在这个简单的示例中,它们都可以工作,但在以后使用更复杂的样式表时,你可能会遇到优先级问题。
&还允许你在父选择器上定位伪元素和伪类。例如:
p.my-element {
&::after {}
&:hover {}
&:target {}
}
如果你不使用&,你的目标将是选择器的所有子元素,而不是p.my-element本身。(在Sass中也会出现同样的情况)。
需要注意的是,你可以在选择器的任何位置使用&,比如:
.child1 {
.parent3 & {
color: red;
}
}
这会转换为下列非嵌套语法:
.parent3 .child1 { color: red; }
你甚至可以在一个选择器中使用多个&符:
ul {
& li & {
color: blue;
}
}
这会作用于嵌套的<ul>元素(ul li ul),如果你不想被逼疯我建议还是不要这么使用了!
最后,你可以嵌套媒体查询。下面的代码为段落元素应用了cyan颜色,除非浏览器宽度至少为800px,否则将变为purple:
p {
color: cyan;
@media (min-width: 800px) {
color: purple;
}
}
CSS原生嵌套问题
原生嵌套在:is()中包裹父选择器,这可能会导致与Sass输出的差异。
考虑下列的嵌套代码:
.parent1, #parent2 {
.child1 {}
}
在浏览器中解析时,这实际上变成了以下内容:
:is(.parent1, #parent2) .child1 {}
.parent1中的.child1元素的优先级为101,因为:is()使用了其最优先选择器的优先级--在本例中,是#parent2 ID。
Sass编译的代码与此相同:
.parent1 .child1,
#parent2 .child1 {
}
在本例中,.parent1 中的 .child1 元素的特异性为 002,因为它匹配两个类(#parent2 被忽略)。它的选择器比原生选项的优先级低,在级联中被覆盖的可能性更大。
你可能还会遇到一个更微妙的问题。考虑下列代码:
.parent .child {
.grandparent & {}
}
原生CSS等价于:
.grandparent :is(.parent .child) {}
这与下列排序错误的HTML元素相匹配:
<div class="parent">
<div class="grandparent">
<div class="child">MATCH</div>
</div>
</div>
由于CSS解析器会执行以下操作,因此MATCH会改变样式:
- 在DOM层次结构中的任意位置,找到所有类为
child的元素,同时祖先元素的类为parent。 - 在找到包含
MATCH的元素后,解析器会检查该元素是否有一个祖先为grandparent的元素--同样是在DOM层次结构中的任意位置。找到后,解析器会相应地对该元素应用样式。
在Sass中不是这种情况,最终会编译成这样:
.grandparent .parent .child {}
上面的HTML没有样式化,因为元素的类没有遵循严格的grandparent、parent和child顺序。
最后,Sass使用字符串替换,所以像下面这样的声明是有效的,可以匹配任何具有outer-space类的元素:
.outer {
&-space { color: black; }
}
而原生CSS会忽略&-space选择器。
还需要CSS预处理器吗
在短期内,现有的CSS预处理器仍然必不可少。
Sass开发团队已经宣布,他们将支持.css文件中的原生CSS嵌套,并按原样输出代码。他们将一如既往地编译嵌套的SCSS代码,以避免破坏现有代码库,但当全球浏览器支持率达到98%时,他们将开始输出:is()选择器。
我猜测PostCSS插件等预处理器目前会扩展嵌套代码,但当浏览器支持率越来越高时,就会移除该功能。
当然,使用预处理器还有其他很好的理由--比如将部分代码捆绑到单一文件中,以及精简代码。但如果嵌套是你唯一需要的功能,那么你当然可以考虑在小型项目中使用本地CSS。
总结
CSS嵌套是最有用、最实用的预处理器功能之一。浏览器供应商努力创造了一个本地CSS版本,其相似性足以让Web开发人员满意。虽然两者之间存在细微差别,而且在使用(过于)复杂的选择器时可能会遇到不寻常的优先级问题,但很少有代码库需要进行彻底修改。
原生嵌套可能会让你重新考虑对CSS预处理器的需求,但它们仍能提供其他好处。Sass和类似工具仍然是大多数开发人员工具包的重要组成部分。
以上就是本文的全部内容。如果对你有所帮助,欢迎点赞、收藏、转发~
原生CSS嵌套简介的更多相关文章
- css012 css布局简介
css012 css布局简介 一. 网页布局的类型 网页布局的类型 1.固定宽度 2.流式 3.相应式web设计 二. 如何进行css布局 1.强大的<div>标签 网页的h ...
- 原生 CSS 网格布局学习笔记
下是来自Oliver Williams的帖子. Oliver已经学习了相当长时间的原生CSS网格,可以说是在CSS网格方面有一定的发言权.在这篇文章中,他将以非同寻常的思路分析自己的CSS网格布局学习 ...
- 利用Div+CSS(嵌套+盒模型)布局页面完整实例流程
Div+CSS(嵌套+盒模型)布局页面完整实例流程: <!DOCTYPE html><html> <head> <meta charset="UT ...
- CSS 选择器简介
前言:这是笔者学习之后自己的理解与整理.如果有错误或者疑问的地方,请大家指正,我会持续更新! 选择器权重 如果以4位数表示选择符权重,那么: 元素选择器的权重是1: id 选择器的权重为100: cl ...
- 原生css 中变量的使用
前两天看到阮大神的一篇在css中使用变量的文章,整理了一下. 这个重要的 CSS 新功能,所有主要浏览器已经都支持了.本文全面介绍如何使用它,你会发现原生 CSS 从此变得异常强大. 一.变量的声明 ...
- 在原生CSS中使用变量
本文首发于我的博客 一直以来,CSS作为一种申明式的样式标记语言,很难像如javascript等命令式编程语言一样通过定义和使用变量的方式来维护和追踪某些状态.后来随着scss,less等CSS预处理 ...
- LESS CSS 框架简介(转)
原文地址:http://www.ibm.com/developerworks/cn/web/1207_zhaoch_lesscss/ 简介 CSS(层叠样式表)是一门历史悠久的标记性语言,同 HTML ...
- LESS CSS 框架简介
使用 LESS 简化层叠样式表(CSS)的编写 LESS 是动态的样式表语言,通过简洁明了的语法定义,使编写 CSS 的工作变得非常简单.本文将通过实例,为大家介绍这一框架. 简介 CSS(层叠样式表 ...
- 转:LESS CSS 框架简介
原文来自于:http://www.ibm.com/developerworks/cn/web/1207_zhaoch_lesscss/ 简介 CSS(层叠样式表)是一门历史悠久的标记性语言,同 HTM ...
- 【转】 LESS CSS 框架简介
简介 CSS(层叠样式表)是一门历史悠久的标记性语言,同 HTML 一道,被广泛应用于万维网(World Wide Web)中.HTML 主要负责文档结构的定义,CSS 负责文档表现形式或样式的定义. ...
随机推荐
- 2022-07-27:小红拿到了一个长度为N的数组arr,她准备只进行一次修改, 可以将数组中任意一个数arr[i],修改为不大于P的正数(修改后的数必须和原数不同), 并使得所有数之和为X的倍数。
2022-07-27:小红拿到了一个长度为N的数组arr,她准备只进行一次修改, 可以将数组中任意一个数arr[i],修改为不大于P的正数(修改后的数必须和原数不同), 并使得所有数之和为X的倍数. ...
- 2022-02-04:组合总和 Ⅳ。 给你一个由 不同 整数组成的数组 nums ,和一个目标整数 target 。请你从 nums 中找出并返回总和为 target 的元素组合的个数。 题目数据保证
2022-02-04:组合总和 Ⅳ. 给你一个由 不同 整数组成的数组 nums ,和一个目标整数 target .请你从 nums 中找出并返回总和为 target 的元素组合的个数. 题目数据保证 ...
- 2021-07-01:最长连续序列。一个未排序的arr,找出数字连续的最长序列的长度。输入:[100,4,1,20,3,2,50],输出:4。解释:最长数字连续序列是[1,2,3,4],所以长度是4。
2021-07-01:最长连续序列.一个未排序的arr,找出数字连续的最长序列的长度.输入:[100,4,1,20,3,2,50],输出:4.解释:最长数字连续序列是[1,2,3,4],所以长度是4. ...
- 2021-08-20:打砖块。有一个 m x n 的二元网格,其中 1 表示砖块,0 表示空白。砖块 稳定(不会掉落)的前提是:1.一块砖直接连接到网格的顶部,或者,2.至少有一块相邻(4 个方向之一
2021-08-20:打砖块.有一个 m x n 的二元网格,其中 1 表示砖块,0 表示空白.砖块 稳定(不会掉落)的前提是:1.一块砖直接连接到网格的顶部,或者,2.至少有一块相邻(4 个方向之一 ...
- 2021-10-15:单词拆分。给定一个非空字符串 s 和一个包含非空单词的列表 wordDict,判定 s 是否可以被空格拆分为一个或多个在字典中出现的单词。说明:拆分时可以重复使用字典中的单词。你
2021-10-15:单词拆分.给定一个非空字符串 s 和一个包含非空单词的列表 wordDict,判定 s 是否可以被空格拆分为一个或多个在字典中出现的单词.说明:拆分时可以重复使用字典中的单词.你 ...
- 2021-09-24:给定一个正整数 n ,输出的第 n 项。前五项如下:1:1。2:11。3:21。4:1211。5:111221。第一项是数字 1 。描述前一项,这个数是 1 即 “ 一 个 1
2021-09-24:给定一个正整数 n ,输出的第 n 项.前五项如下:1:1.2:11.3:21.4:1211.5:111221.第一项是数字 1 .描述前一项,这个数是 1 即 " 一 ...
- 7-8 估值一亿的AI核心代码
题目描述: 以上图片来自新浪微博. 本题要求你实现一个稍微更值钱一点的 AI 英文问答程序,规则是: 无论用户说什么,首先把对方说的话在一行中原样打印出来: 消除原文中多余空格:把相邻单词间的多个空格 ...
- SpringMVC 解决中文乱码问题以及前后端Json格式数据交互的测试
1.今日遇到的报错: 跳转网页出现404原因: 1.检查project structure里面的webapp路径是否正确: 2.检查project structure里的artifaccts里的WEB ...
- Springboot——参数校验
springboot参数校验注解 在controller层需要对前端传来的参数进行校验 校验简单数据类型 使用springboot自带的validation工具可以从后端对前端传来的数据进行校验 使用 ...
- 聊一聊 Python 安装中的 --enable-shared
由于微信不允许外部链接,你需要点击文章尾部左下角的 "阅读原文",才能访问文中链接. 今天在 CentOS 7.4 使用源码编译安装 Python-2.7.15 的时候,发现了一个 ...