使用作用域 CSS 拯救世界

Avatar of Arley McBlain
Arley McBlain

DigitalOcean 为您的旅程的每个阶段提供云产品。立即开始使用 $200 免费积分!

今天的文章来自 Arley McBlain (@ArleyM),他是位于安大略省伯灵顿的 Thrillworks 的前端开发人员。

在过去的几年里,HTML5 和 CSS3 颠覆了我们的世界以及我们处理常见网站问题的方式。似乎每隔几天就会出现一些新奇的代码片段或方法,改变着游戏规则。今天可能就是其中之一(有点)。

HTML5 中一个鲜为人知的功能是作用域 CSS。它是一种用于样式块的属性,可能会改变我们将来解决某些样式挑战的方式。

更新:据我所知,<style scoped> 已从规范中删除,甚至支持它的浏览器也已将其删除。即使在我写这篇更新(2017 年 8 月)时,作用域样式也比以往任何时候都更受欢迎和更受欢迎。Vue 文件 支持这里描述的概念,还有许多其他支持该概念的库正在出现。原生浏览器可能正在考虑将 Shadow DOM 作为该想法的替代方案。

作用域的实现很简单。让我们看看一个未经样式化页面的代码,其中所有文本默认为黑色

<div>
  <style scoped>
    h1 { color: FireBrick;   }
    p  { color: SaddleBrown; }
  </style>
  <h1>This is an H1 in a scoped div. Regardless of global styles the text should be "FireBrick".</h1>
  <p>This is a paragraph in a scoped div. The text should be "SaddleBrown".</p>
</div>

<p>This is another paragraph, that will unaffected by the scoped style and remain black.</p>

带有 scoped 属性的 style 块将覆盖通常在 head 中找到的全局样式(无论是在样式块中还是在链接样式表中),但仅限于相同父元素中的同级/后代元素。在本例中,包装 div 中的所有内容都将获得一些新的标题和段落颜色。正如 w3.org 所说 “如果存在 scoped 属性,则用户代理必须仅将指定的样式信息应用于样式元素的父元素(如果有的话),以及该元素的子节点。”

这太棒了!虽然页面上的所有其他文本可能都是黑色,但在这个 div 中,我们可以自由地进行样式化,而不必担心更改我们网站上其他任何地方类似元素的样式。这可能是一个非常强大的工具。

为什么这很酷?

“但是 Arley,”你说,用一个连词开始一个句子,“为什么不只是在那个 div 上使用一个类或 ID 并像 #foo h1#foo p 那样进行样式化?这不是只是有组织的内联样式吗?” 在某些情况下,我能想到很多情况下作用域 CSS 都是一个不错的选择

  • 将特定交互元素的 CSS 与 HTML 保持在一起可能很理想。如果所讨论的元素在网站上是唯一的(例如复杂滑块),则将其与全局样式缓存没有任何优势。
  • 为了组织而将 CSS 与 HTML 保持在一起可能具有价值。
  • 在与团队合作时,这可能是一种很棒的方法,可以允许同时开发网站的不同区域,而无需担心全局 CSS 的状态——我认为这可以作为短期解决方案。
  • 如果您的文章被其他网站聚合,则可以自定义其他网站上的样式,否则这些样式将超出您的全局样式表的范围。
  • 如果您在网站的评论部分启用标签,您就可以让读者有能力自定义他们的... 算了,这可能是一个糟糕的主意。
  • 在第三方网站的小部件中使用,这些网站的 CSS 未知,并且小部件内的样式不应影响其他任何地方。尽管能够重置小部件内的样式是这场战斗的另一半。
  • 最后(对我来说最令人兴奋的是),作用域 CSS 非常适合在内容管理系统中工作,在内容管理系统中,您对向通用模板区域添加唯一标记的灵活性要低得多,或者无法访问现有样式表。

我想更详细地讨论 CMS 的优势。

使用 CMS

当我们在 CMS 中构建网站时,我们正在构建约束以确保元素和模板的可重用性,以及维护整个网站的一致性。CMS 是让比您笨拙得多的人创建和管理内容的完美工具,而无需担心破坏任何网站组件。CMS 的一个限制是无法对唯一区域进行一次性调整。

我在企业级 CMS 中遇到了这个问题。根据最初的样机和网站范围,我们构建的 CMS 具有一致的统一外观和感觉。推出几个月后,对更大灵活性的需求出现了:添加第二种更详细的语言,以及特殊的营销活动为样式化带来了新的挑战。

我的第一个挑战是制作更大的文本块(有趣的事实:加拿大设计师在为双语设计时的一般规则是,在需要法语设计时,要留出 50% 的额外空间!)。我查看了我的页面,以及我的样式表:即使我做出的任何微小更改都意味着在整个网站上进行数小时的测试和质量保证,以确保其他区域没有因此而被破坏。后果是灾难性的!由于没有时间这样做,我发明了“穷人版的作用域 CSS”,或“代码块”,因为它后来被称为。从技术上讲,代码块只是用 ID 将 div 包裹在内容周围,然后有一个相邻的样式块来进行必要的更改(虽然这听起来很简单,但对于这项 CMS 工作来说有点超出了范围)。由于此 CSS 只适用于此页面,因此将这些样式添加到全局样式中没有任何意义。这很完美。样式块不会影响网站的任何其他区域。双语和营销活动内容变得易于开发和测试。

值得庆幸的是,作用域 CSS 将比我的拼凑解决方案更简洁和更容易实现。将不需要特殊的 ID,实际上能够使用像“p”这样非常简单的选择器将使您的 CSS 看起来非常简洁。

实践操作

您是否曾经想过让您流中的某个特定帖子以某种方式脱颖而出?即使您的 CMS 不允许在编辑器中进行编码,您仍然可能拥有选项,这得益于作用域 CSS。

WordPress 是 CMS 的一个示例,它将限制您可以在内容区域中输入的代码。WordPress 原生会从所见即所得编辑器中删除许多标记,这实际上是一件非常非常好的事情,因为它会清除新手用户可能意外引入的任何杂乱代码。让用户访问 CMS 中的代码相当于让他们访问破坏网站的权利!过多的关闭 div 标签将意味着完全混乱的布局!

通过一些前期工作,您可以创建一个“代码块”自定义字段,它将允许您将作用域 CSS 直接注入到该帖子中。如果您真的想变得花哨,您可以使用来自 Custom Field Template 等插件的功能,让即使是最不精通的用户也能通过简单的表格做出样式选择,从而轻松地利用此功能!

在下面的 WordPress 演示中,我创建了一个 Twenty Eleven 子主题(这意味着我完全依赖默认的 WordPress 模板,除了我进行了一些小调整的三个页面)。我所做的更改很少且简单(我可能还应该提到,在撰写本文时,还有另一个微不足道的问题需要考虑,但我将在稍后保存)。为了让作用域 CSS 正常工作,我只是将一小段逻辑添加到 content.php 和 content-single.php 中,以查找“scopedcss”自定义字段,然后将其弹出到样式块中。我只是将此代码放在相关内容循环的 <article> 块中

<?php 
  $scopedcss = get_post_meta($post->ID, 'scopedcss', false); 

  foreach($scopedcss as $css) {
    echo '<style scoped>'.$css.'</style>';
  } 
?>

然后,在我的 WordPress 帖子中,我只是添加了“scopedcss”自定义字段,并写下了我想要为此帖子写的任何样式。

简单易懂。如果您在帖子编辑器屏幕上没有看到自定义字段,请单击屏幕顶部的“屏幕选项”选项卡,并确保选中该选项卡上的复选框。

注意:如果您对每个帖子使用此艺术指导的想法感兴趣,但还没有准备好使用作用域样式,请查看此插件,它为您提供了用于声明样式的元框,但它们不会被作用域化,您需要像常规 CSS 一样具体。

一句警告

我自己使用“穷人版”的经验并非全是阳光和玫瑰;这种方法和作用域 CSS 存在一个主要弱点:组织变得非常困难——您最终会到处都有样式!作用域 CSS 能够拯救世界,但如果有可能,您应该使用 ID 选择器和链接样式表。

这是我们应该避免内联样式的主要原因之一,它们很混乱,它们增加了页面权重,而这些权重可能应该被缓存,它们很难被覆盖,它们会使故障排除变得复杂,最重要的是,它们很难维护。与内联样式一样,作用域样式也有其用武之地,并且可以成为一个强大的工具。明智地使用它们。

更大的警告

使用作用域样式没有适当的 polyfill 非常危险。在不支持作用域样式的浏览器中,你声明的样式将影响整个页面。 想象一下,你使用作用域样式在一个网站文章的 h1 标题中使用图像替换技术。你的网站 logo 也是 h1,因此在不支持作用域样式的浏览器中,logo 也会被替换。结果是级联样式的反向灾难。

请注意,作用域样式是一个非常有用的想法,但是没有 polyfill 的情况下使用它们的日子还很遥远。

jQuery 解决方案

由于缺乏原生浏览器支持,如果今天没有这个由 Simon Madine 制作的伟大的 jQuery Polyfill,这将是一个令人失望的演示。为了让我的演示在 WordPress 中工作,我还

  1. 将 jQuery 加入到我的 WordPress 主题中。
  2. 将以下代码添加到主题的页脚(主题文件夹中的 footer.php)。
<script src="<?php bloginfo( 'stylesheet_directory' ); ?>/jquery.scoped.js"></script>
<script>
  $.scoped();
</script>
它起作用了!

想要玩吗?

在撰写本文时,Chrome 20 是唯一支持作用域样式的浏览器。Chrome 20 目前处于 Canary 阶段,这是一个预发布版本,你可以与稳定的 Chrome 并行运行,没有任何问题。要使用它,你需要启用一个标志,方法是

  1. 访问 URL chrome://flags/
  2. 在页面中搜索“scoped”
  3. 点击“启用”
这里还有很多其他有趣的东西。

Chrome 的更新速度很快,因此在撰写本文后的 12 周左右(2012 年 7 月中旬),Chrome 20 应该会稳定下来。该功能是否会启用发布是另一个问题(我们还不知道)。

演示

不久的将来,作用域 CSS 将在浏览器中原生实现,无需额外的 JavaScript 就能完成这些演示中看到的令人惊叹的功能。在此之前,你可以梦想着它,阅读关于它的信息 在 w3.org 上,并查看这些演示

作用域样式,除了提供上述功能外,还将在 Web Components 中非常强大,这是一个 W3C 的提案,用于在下一代 Web 应用中定义可重用的小部件。令人兴奋的事情。