现代CSS:原生 CSS 嵌套快速入门
1.原生 CSS 嵌套
原生 CSS 嵌套可以像 SASS、LESS 预处理器一样,将相关的选择器组合在一起,从而减少需要编写的规则数量。它可以节省打字时间,并使语法更易于阅读和维护。您可以将选择器嵌套到任意深度,但要小心不要超过两层或三层。嵌套深度没有技术限制,但它会使代码更难以阅读,并且生成的 CSS 可能会变得不必要的冗长。
.button {
background-color: red;
&.warning {
background-color: blue;
}
& .icon {
width: 1rem;
height: 1rem;
}
}
虽然原生 CSS 嵌套语法在过去几年中不断发展,使大多数 Web 开发人员感到满意,但不要指望所有 SCSS 代码都能像您期望的那样直接工作。
2.原生 CSS 嵌套规则
您可以将任何选择器嵌套在另一个选择器中,但它必须以符号开头,例如 &
, .
(类选择器)、#
(ID选择器)、@
(对于媒体查询)、:
、::
、+
、 ~
、 >
或 [
。换句话说,它不能是对 HTML 元素的直接引用。下面的代码是无效的,不会对 input
元素选择器进行解析:
.parent {
color: red;
input {
margin: 1em;
}
}
/* Invalid, because "input" is an identifier. */
解决此问题的最简单方法是使用与号 ( &),它以与 Sass 相同的方式引用当前选择器。
2.1.& 符号的使用
.parent {
color: red;
& input {
margin: 1em;
}
/* use pseudo-elements and pseudo-classes */
&::after {}
&:hover {}
&:target {}
}
/* valid, no longer starts with an identifier */
或者,您可以使用其中之一:
> input
:只对子元素生效:is(input)
:将选择器列表作为参数,并选择该列表中任意一个选择器可以选择的元素:where(input)
:优先级总是为 0
它们都可以在这个简单的示例中工作,但是稍后您可能会遇到更复杂的样式表的特异性问题。
它还&允许您在父选择器上定位伪元素和伪类。例如:
p.my-element {
&::after {}
&:hover {}
&:target {}
}
请注意,&
可以在选择器中的任何位置使用。例如:
.child1 {
.parent3 & {
color: red;
}
}
这将转换为以下非嵌套语法:
.parent3 .child1 { color: red; }
您甚至可以在选择器中使用多个 &
符号:
ul {
& li & {
color: blue;
}
}
这将以嵌套 <ul>
元素 ( ul li ul) 为目标,但如果您想保持理智,我建议不要使用它!
2.2.@ 符号的使用
嵌套媒体查询示例:
p {
color: cyan;
@media (min-width: 800px) {
color: purple;
}
}
3.原生 CSS 嵌套陷阱
3.1.场景一:父选择器包装在 :is()
中
原生 CSS 嵌套将父选择器包装在 :is()
中,这可能会导致与 Sass 输出的差异,比如以下嵌套代码:
.parent1, #parent2 {
.child1 {
}
}
当它在浏览器中解析时,它实际上变成以下内容:
:is(.parent1, #parent2) .child1 {
}
Sass 将相同的代码编译为:
.parent1 .child1,
#parent2 .child1 {
}
3.2.场景二:& 符号后置
您可能还会遇到一个更微妙的问题。考虑一下:
.parent .child {
.grandparent & {}
}
原生 CSS 等效项是:
.grandparent :is(.parent .child) {}
这与以下错误排序的 HTML 元素匹配:
<div class="parent">
<div class="grandparent">
<div class="child">MATCH</div>
</div>
</div>
Sass 中的情况并非如此,它编译为:.grandparent .parent .child {} 上面的 HTML 没有样式化,因为元素类不遵循严格的grandparent、parent、 和child顺序。
3.3.场景三:字符串替换
Sass 使用字符串替换,因此如下所示的声明是有效的,并且与类的任何元素相匹配 .btn-primary
:
.btn {
&-primary {
color: blue;
}
}
但是原生 CSS 嵌套会忽略&-space选择器。
4.CSS 预处理器还需要吗?
从短期来看,现有的 CSS 预处理器仍然至关重要。Sass 开发团队宣布,他们将支持 .css 文件中的原生 CSS 嵌套,并按原样输出代码。他们将一如既往地编译嵌套 SCSS 代码,以避免破坏现有代码库,但当全球浏览器支持率达到 98% 时,他们将开始输出 :is() 选择器。
我猜想,PostCSS 插件等预处理器目前会扩展嵌套代码,但随着浏览器支持的普及,就会取消这一功能。当然,使用预处理器还有其他很好的理由,比如将部分代码捆绑到一个文件中,以及对代码进行精简。但如果嵌套是你唯一需要的功能,你当然可以考虑在较小的项目中使用原生 CSS。
5.总结
CSS 嵌套是最有用、最实用的预处理器功能之一。浏览器供应商努力创造了一个与 CSS 非常相似的原生 CSS 版本,以满足网络开发人员的需求。虽然两者之间存在细微差别,而且在使用(过于)复杂的选择器时可能会遇到不寻常的特殊性问题,但很少有代码库需要进行彻底修改。
原生嵌套可能会让你重新考虑是否需要 CSS 预处理器,但它们仍能提供其他好处。Sass 和类似工具仍然是大多数开发者工具包的重要组成部分。
大家都在看