乐趣区

关于javascript:作用域-CSS-回来了

首发于公众号 大迁世界,欢送关注。📝 每周 7 篇实用的前端文章 🛠️ 分享值得关注的开发工具 😜分享集体守业过程中的趣事

快来收费体验 ChatGpt plus 版本的,咱们出的钱 体验地址: https://chat.waixingyun.cn 能够退出网站底部技术群,一起找 bug,另外新版作图神器已上线 https://cube.waixingyun.cn/home

几年前,隐没的作用域 CSS,现在它回来了,而且比以前的版本要好得多。

更好的是,W3C 标准根本稳固,当初 Chrome 中曾经有一个工作原型。咱们只须要社区略微关注一下,诱惑其余浏览器构建它们的实现,并实现这项工作。

这是什么思路?

作用域为 CSS 带来了两个关键点:

  1. 更好地管制哪些选择器针对哪些元素(即更好地操作级联)。
  2. 一组款式能够基于 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 依然有它的用处)。

以下只是我会尝试的一些想法:

  1. 定义一个组件的局部,有一个外部边界,局部没有,所以它的“chrome”款式(即包装器、切换按钮等)不影响其子内容,但它能够影响文本内的外观。
  2. 在不同的级联层上定义一个组件的局部,这样它能够影响其蕴含的范畴,但依然容易在更高的档次上笼罩。
  3. 嵌套的色彩主题。
  4. 在博客文章中更容易地避免款式抵触。
  5. 容器查问—咱们能通过混合和匹配来提出什么?

咱们须要更多的浏览器反对

到目前为止,Chrome 仿佛曾经反对了—他们曾经有了第一个工作原型几个月了。它可能略微落后于标准的最新变动,所以如果你玩一下,要注意一些行将到来的小变动。

交换

首发于公众号 大迁世界,欢送关注。📝 每周一篇实用的前端文章 🛠️ 分享值得关注的开发工具 ❓ 有疑难?我来答复

本文 GitHub https://github.com/qq449245884/xiaozhi 已收录,有一线大厂面试残缺考点、材料以及我的系列文章。

退出移动版