作用域 CSS 回来了

AI 概述
这是什么思路?它是如何工作的?内部范围边界近度优先 Proximity precedence转折点浏览器支持 几年前,消失的作用域 CSS,如今它回来了,而且比以前的版本要好得多。 更好的是,W3C 规范基本稳定,现在 Chrome 中已经有一个工作原型。我们只需要社区稍微关注一下,引诱其他浏览器构建它们的实现,并完...
目录
文章目录隐藏
  1. 这是什么思路?
  2. 它是如何工作的?
  3. 内部范围边界
  4. 近度优先 Proximity precedence
  5. 转折点
  6. 浏览器支持

几年前,消失的作用域 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 中检查,看到每个范围是如何根据其最近的接近性来覆盖另一个的:

近度优先 Proximity precedence

近度优先 Proximity precedence

这里的问题是,选择器的特异性仍然是优先的,所以如果外部范围以比内部更高的特异性针对一个元素,外部范围的样式将会应用。

这样,当两个范围针对同一个元素时,你可以控制哪一个优先。而不是总是让内部范围赢,你可以调整选择器的特异性,使得更高特异性的选择器优先,不管它属于哪个范围。

当你不希望这种行为时,你有几种方法可以防止它。你可以使用级联层来使一个组件——或者一个组件的某些部分——优先于另一个。或者,你可以应用一个内部范围约束到外部范围,以防止它发生。在尝试了一段时间的范围后,我觉得这是一个正确的平衡。它给了你最大的控制权,而不是让你受制于级联的一套严格的规则。

转折点

如果你开发过大型应用,并且不得不依赖 CSS-in-JS 库来防止类名冲突,作用域 CSS 是个很好的选择。如果你使用了复杂的 BEM 类名系统,并努力使所有的选择器特异性保持一致,想想这可以带来的自由。如果你曾经使用过 shadow DOM 来隔离样式,但觉得它过于重手,这是一个更好的方法(当然,shadow DOM 仍然有它的用途)。

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

  1. 定义一个组件的部分,有一个内部边界,部分没有,所以它的“chrome”样式(即包装器、切换按钮等)不影响其子内容,但它可以影响文本内的外观。
  2. 在不同的级联层上定义一个组件的部分,这样它可以影响其包含的范围,但仍然容易在更高的层次上覆盖。
  3. 嵌套的颜色主题。
  4. 在博客文章中更容易地防止样式冲突。
  5. 容器查询—我们能通过混合和匹配来提出什么?

浏览器支持

到目前为止,Chrome 似乎已经支持了—他们已经有了第一个工作原型几个月了。它可能稍微落后于规范的最新变化,所以如果你玩一下,要留意一些即将到来的小变化。

以上关于作用域 CSS 回来了的文章就介绍到这了,更多相关内容请搜索码云笔记以前的文章或继续浏览下面的相关文章,希望大家以后多多支持码云笔记。

「点点赞赏,手留余香」

1

给作者打赏,鼓励TA抓紧创作!

微信微信 支付宝支付宝

还没有人赞赏,快来当第一个赞赏的人吧!

声明:本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若内容造成侵权/违法违规/事实不符,请将相关资料发送至 admin@mybj123.com 进行投诉反馈,一经查实,立即处理!
重要:如软件存在付费、会员、充值等,均属软件开发者或所属公司行为,与本站无关,网友需自行判断
码云笔记 » 作用域 CSS 回来了

发表回复