IT博客汇
  • 首页
  • 精华
  • 技术
  • 设计
  • 资讯
  • 扯淡
  • 权利声明
  • 登录 注册

    CSS @scope他来了

    张 鑫旭发表于 2024-01-21 13:53:26
    love 0

    by zhangxinxu from https://www.zhangxinxu.com/wordpress/?p=11110 鑫空间-鑫生活
    本文欢迎分享与聚合,全文转载就不必了,尊重版权,圈子就这么大,若急用可以联系授权。

    仙人掌封面图

    一、背景前言

    随着Safari TP版本已经支持CSS @scope规则,这个新特性在不久的将来在Web中大放异彩已是必然。

    @scope 规则兼容性

    那这样@scope规则是干什么用的呢?

    二、@scope的语法与作用

    使用过Sass或Less这种预编译语言的,这种写法应该不陌生。

    Sass写法示意

    @scope的作用其实与之类似,可以实现CSS选择器的嵌套书写。

    例如,有如下所示的HTML和CSS代码:

    <nav>
      <ul>
        <li><a href="">链接1</a></li>
        <li><a href="">链接2</a></li>
        <li><a href="">链接3</a></li>
      </ul>
    </nav>
    <p><a>我呢?</a></p>
    @scope(nav) {
      ul {
        list-style: none;
        padding: 0;margin: 0;
      }
      li {
        display: inline-block;
      }
      a {
        display: block;
        padding: 6px 12px;
        text-decoration: none;
        background: skyblue;
      }
    }

    渲染效果如下图所示,可以看到,只有在nav标签内的<a>元素有了背景色等样式,而外面的还是默认的样式效果。

    @scope基本效果使用示意

    优先级

    @scope规则内选择器的优先级是计算在内的,也就是下面这段CSS代码中a元素的优先级等同于nav a.

    @scope(nav) {
      a {
        …
      }
    }

    下图所示的运行结果也可以证明这一点,若@scope()内的选择器不参与优先级,那么 a {background:lightpink} 就会覆盖@scope规则中a元素的背景色设置,结果没有,说明@scope()中的选择器也参与了优先级的计算。

    优先级效果示意

    匹配自身

    伴随@scope规则一起出现的是:scope伪类,可以匹配@scope函数中选择器匹配的元素。

    例如:

    @scope(nav) {
      :scope {
        border: double red;
      }
      ...
    }

    此时,<nav>元素就出现了双层红色边框,如下截图所示:

    红色边框示意

    to语法进行排除

    如果希望范围内的某个元素不参与选择器匹配,可以使用 to (xxx)的语法,例如有如下所示的HTML代码:

    <nav>
      <ul>
        <li><a href="">链接1</a></li>
        <li><a href="">链接2</a></li>
        <li><a href="">链接3</a></li>
      </ul>
      <p><a>我呢?</a></p>
    </nav>

    如果不希望<p>元素的内<a>元素不参与样式设置,可以这么设置:

    @scope(nav) to (p) {
      :scope {
        border: double red;
      }
      ul {
        list-style: none;
        padding: 0;margin: 0;
      }
      li {
        display: inline-block;
      }
      a {
        display: block;
        padding: 6px 12px;
        text-decoration: none;
        background: skyblue;
      }
    }

    此时可以看到,p > a这个元素并未有任何样式匹配,如下图所示:

    排除语法效果示意

    支持复杂选择器

    继续上面的HTML代码,如果@scope的语句是这么设置的:

    @scope(nav:has(p)) to (p, [class], .some-class) {
      ...
    }

    依然不影响最终的CSS解析。

    三、噢啦,就这门多

    从上面的文档可以看出,@scope更像是一种语法糖,简化书写,让层次更清晰,比较适合用在模块或组件开发中。

    也就是以前如下所示的选择器命名可以优化一波了:

    .zxx-list-x{}
    .zxx-list-ul{}
    .zxx-list-item{}
    .zxx-list-info{}
    .zxx-list-img{}
    .zxx-list-opt{}

    现在可以这么一波带过去了:

    @scope(.zxx-list-x) {
      :scope{}
      .ul{}
      .item{}
      .info{}
      .img{}
      .opt{}
    }

    恩,看起来挺香的。

    不过需要注意的是,@scope所实现的并非CSS作用域功能,所谓作用域,是无论里面的CSS选择器如何书写,都不会影响外面的CSS,这个目前只存在与Shadow DOM中。

    因此,Vue和React那种模块类名自动加随机后缀实现局部CSS的功能即使在@scope普及之后,依然有一定的市场,不过不会像现在这么大就是了。

    好,就说这么多,Web更新不止,前端学习不停。

    欢迎点赞,感谢。

    紫灵

    本文为原创文章,欢迎分享,勿全文转载,如果实在喜欢,可收藏,永不过期,且会及时更新知识点及修正错误,阅读体验也更好。
    本文地址:https://www.zhangxinxu.com/wordpress/?p=11110

    (本篇完)



沪ICP备19023445号-2号
友情链接