共计 3084 个字符,预计需要花费 8 分钟才能阅读完成。
首发于公众号 大迁世界,欢送关注。📝 每周 7 篇实用的前端文章 🛠️ 分享值得关注的开发工具 😜分享集体守业过程中的趣事
快来收费体验 ChatGpt plus 版本的,咱们出的钱 体验地址: https://chat.waixingyun.cn 能够退出网站底部技术群,一起找 bug,另外新版作图神器已上线 https://cube.waixingyun.cn/home
几年前,隐没的作用域 CSS,现在它回来了,而且比以前的版本要好得多。
更好的是,W3C 标准根本稳固,当初 Chrome 中曾经有一个工作原型。咱们只须要社区略微关注一下,诱惑其余浏览器构建它们的实现,并实现这项工作。
这是什么思路?
作用域为 CSS 带来了两个关键点:
- 更好地管制哪些选择器针对哪些元素(即更好地操作级联)。
- 一组款式能够基于 DOM 中的地位笼罩另一组款式。
部分款式容许你在页面上的单个组件内蕴含一组款式。你能够应用 .title
选择器,它只在 Card 组件内工作,并应用另一个 .title
选择器,它只在 Accordion 中工作。你能够阻止一个组件的选择器针对子组件中的元素,或者如果须要,也能够容许它们达到。
你不再须要 BEM 格调的类名。
此外,近度 在级联中变成了一等公民。如果两个组件针对同一个元素(具备雷同的特异性),外部组件的款式将笼罩内部组件的款式。
它是如何工作的?
所有都始于 @scope
规定和一个选择器,如下:
@scope (.card) {
/* 将以下款式局限于 `.card` 外部 */
:scope {
padding: 1rem;
background-color: white;
}
.title {
font-size: 1.2rem;
font-family: Georgia, serif;
}
}
这些款式都限度在 .card
元素中。:scope
是一个非凡的伪类,针对 .card
元素自身,.title
针对题目外部的题目。
@scope
规定自身不减少这些选择器的特异性,所以它们都是(0, 1, 0
)。是的,特异性依然很重要,但这是坏事™️。稍后再说。
此时,你能够应用一般的后辈选择器来实现这一点。但当你在范畴内利用外部边界或在页面上重叠多个范畴时,新的、以前不可能的选项开始呈现。让咱们看看它们是怎么做的 …
外部范畴边界
假如你预计将其余组件放入你的 Cards
中,所以你不心愿.title
选择器针对除属于 Card 的那个题目之外的任何货色。为此,你在范畴上设置了一个外部边界,如下:
@scope (.card) to (.slot) {
/* 限定的款式只在 `.card` 外部,但不在 `.slot` 外部 */
:scope {
padding: 1rem;
background-color: white;
}
.title {
font-size: 1.2rem;
font-family: Georgia, serif;
}
}
把这里的 to 关键字看作 直到 :这个范畴是从.card
到.slot
定义的。当初,没有一个局限的选择器会针对 Card 的 .slot
元素外部的任何货色。所以你能够这样构建你的卡片:
<div class="card">
<h3 class="title">Moon lander</h3>
<div class="slot">
<!-- 部分款式不会针对这里的任何货色!-->
</div>
</div>
范畴的影响受到了限度,使其不针对 .slot
内的任何货色。这样,你能够嵌套两个范畴,每个范畴都能够应用雷同的通用题目类名,而不会发生冲突。实际上,你可能基本不再须要类名了:
@scope (.card) to (.slot) {
h3 {
font-size: 1.2rem;
font-family: Georgia, serif;
}
}
@scope (.accordion) to (.slot) {
h3 {
font-family: Helvetica, sans-serif;
text-transform: uppercase;
letter-spacing: 0.01em;
}
}
你能够在 Card 外部放一个 Accordion,或者在 Accordion 外部放一个 Card,它们各自的款式不会发生冲突。
这被俗称为 甜甜圈范畴,因为范畴中有一个洞。(如果外部边界选择器针对多个元素,它也能够有多个洞。)
Miriam Suzanne 倡议应用这种形式是继续应用 data-*
属性和属性选择器作为你的范畴:
@scope ([data-scope='media']) to (:scope [data-scope]) {/* 限定的款式在这里 */}
近度优先 Proximity precedence
另一个方面是近度的概念:来自外部范畴的款式将笼罩来自内部范畴的款式。设想你有这样两个范畴:
@scope (.green) {
p {color: green;}
}
@scope (.blue) {
p {color: blue;}
}
将以下内容利用于 HTML。这里没有外部范畴束缚,所以两个 p
选择器都针对这里的外部段落。在这种状况下,外部范畴总是优先:
<div class="green">
<p> 我是绿色的 </p>
<div class="blue">
<p> 我是蓝色的 </p>
</div>
</div>
<div class="blue">
<p> 我是蓝色的 </p>
<div class="green">
<p> 但我是绿色的 </p>
</div>
</div>
留神这目前只在 Chrome 中无效,须要在 chrome://flags
中启用实验性 Web 平台性能标记。
你能够在 DevTools 中查看,看到每个范畴是如何依据其最近的靠近性来笼罩另一个的:
这里的问题是,选择器的特异性依然是优先的,所以如果内部范畴以比外部更高的特异性针对一个元素,内部范畴的款式将会利用。
这样,当两个范畴针对同一个元素时,你能够管制哪一个优先。而不是总是让外部范畴赢,你能够调整选择器的特异性,使得更高特异性的选择器优先,不论它属于哪个范畴。
当你不心愿这种行为时,你有几种办法能够避免它。你能够应用级联层来使一个组件——或者一个组件的某些局部——优先于另一个。或者,你能够利用一个外部范畴束缚到内部范畴,以避免它产生。在尝试了一段时间的范畴后,我感觉这是一个正确的均衡。它给了你最大的控制权,而不是让你受制于级联的一套严格的规定。
这是一个游戏的转折点
如果你开发过大型利用,并且不得不依赖 CSS-in-JS 库来避免类名抵触,作用域 CSS 是个很好的抉择。如果你应用了简单的 BEM 类名零碎,并致力使所有的选择器特异性保持一致,想想这能够带来的自在。如果你已经应用过 shadow DOM 来隔离款式,但感觉它过于重手,这是一个更好的办法(当然,shadow DOM 依然有它的用处)。
以下只是我会尝试的一些想法:
- 定义一个组件的局部,有一个外部边界,局部没有,所以它的“chrome”款式(即包装器、切换按钮等)不影响其子内容,但它能够影响文本内的外观。
- 在不同的级联层上定义一个组件的局部,这样它能够影响其蕴含的范畴,但依然容易在更高的档次上笼罩。
- 嵌套的色彩主题。
- 在博客文章中更容易地避免款式抵触。
- 容器查问—咱们能通过混合和匹配来提出什么?
咱们须要更多的浏览器反对
到目前为止,Chrome 仿佛曾经反对了—他们曾经有了第一个工作原型几个月了。它可能略微落后于标准的最新变动,所以如果你玩一下,要注意一些行将到来的小变动。
交换
首发于公众号 大迁世界,欢送关注。📝 每周一篇实用的前端文章 🛠️ 分享值得关注的开发工具 ❓ 有疑难?我来答复
本文 GitHub https://github.com/qq449245884/xiaozhi 已收录,有一线大厂面试残缺考点、材料以及我的系列文章。