自学内容网 自学内容网

【CSS in Depth 2 精译_057】第九章 CSS 的模块化与作用域 + 9.1 CSS 模块的定义(上)

当前内容所在位置(可进入专栏查看其他译好的章节内容)

  • 【第三部分 现代 CSS 代码组织】 ✔️
  • 【第九章 CSS 的模块化与作用域】 ✔️
    • 9.1 模块的定义 ✔️
      • 9.1.1 模块和全局样式 ✔️
      • 9.1.2 一个简单的 CSS 模块 ✔️
      • 9.1.3 模块的变体
      • 9.1.4 多元素模块

《CSS in Depth》新版封面

《CSS in Depth》新版封面

译者按
因为照顾生病住院的父亲,专栏的更新不得不中断了一周多。好在手术非常成功,术后也恢复得很好,这才重新回归。让大家等了这么多天,先说声抱歉。上一篇我们结束了全新章节层叠图层的学习,这一篇则开始学习模块化 CSS 的相关内容。由于引入了图层的全新概念,本章内容在第一版的基础上也作了相应调整,同时还新增了最新的 @scope 语法,非常值得期待!

第九章 模块化 CSS 和范围 Modular CSS and scope


本章概要

  • 将 CSS 整理成可复用的模块
  • 防止选择器优先级不断攀升
  • 组织 CSS 代码的通用命名规则
  • @scope 更好地控制层叠规则
  • 使用模式库编写模块文档

在修改现有样式表时,这些样式变更可能会影响到整个网站中任意多个页面及其页面元素。有个老笑话是这么说的:两个 CSS 属性走进了一间酒吧,结果另一间酒吧的高脚凳却摔倒了(two CSS properties walk into a bar; a barstool in a different bar falls over.)。那么问题来了:怎样确保这些样式修改仅对希望变更的位置生效、而不影响到其他无关的元素样式呢?

上一章介绍的 CSS 层叠图层是控制页面样式优先级的第一步;当时我还给出了页面图层的推荐组织方案。其中最大的图层,即模块图层(modules layer),也是大多数页面样式所在的图层。本章将围绕该层展开讨论,并将其组织为易于管理的模块化代码。

9.1 模块的定义 Defining modules

模块化 CSS(Modular CSS 是指将页面分割成不同的组成部分,并让它们在多种上下文语境中重复使用,但相互之间并不存在依赖关系。其最终目的是,当我们修改其中一部分 CSS 样式时,不会对其他部分产生意料之外的影响。

这个概念类似于宜家厨房(IKEA kitchen)采用的模块化家具设计:顾客可以随意选择风格一致、组合起来毫无违和感的多个独立小件;而不是购置一个大型的橱柜单元。此外还可以将这些小件随意摆放到自己喜欢的位置,从而形成完整的布局;模块化 CSS 也是如此,不必再构建一个大型网页,而是独立构建页面的各个部分,然后按照既定设计将它们组合到一起。

在计算机科学中,编写模块化代码并不是什么新潮的做法,但许多开发人员并没有意识到可以将其应用于 CSS 领域。随着现代网站和 Web 应用的体量日渐庞大且复杂,人们不得不另寻出路来管理日益庞大且繁杂的样式表。模块化 CSS 便是一种行之有效的解决方案。

之前的样式表可以使用选择器在页面上随意修改样式;而模块化的样式则可以让开发人员添加一些限制条件。我们把样式表的每个组成部分称为 模块(module),每个模块独立负责自己的样式,并且不会影响其他模块内的样式。由此在 CSS 中引入了软件封装的原则。

封装的定义

封装(Encapsulation 是将相关功能和数据组合在一起,构成一个对象。通常用来隐藏结构化对象内部的状态或值,从而无法从外部操作对象内部。

CSS 没有数据和传统函数的概念,但是有选择器及其选中的页面元素;为了达到封装的目的,它们会成为模块的组成部分,并且每个模块都只负责少量的 DOM 元素样式。此外,CSS 全新推出的 @scope 功能也为样式封装和模块化设计的落地提供了极大的便利。

牢固树立封装的思想后,就可以为页面上相互独立的组件定义模块了,如导航菜单、对话框、进度条、缩略图(thumbnail images)等。每个模块都可以通过作用于 DOM 元素的唯一类名来进行标识。同时,每个模块又包含各自的子元素来构成页面上的组件。模块内部还可以嵌套其他模块,最终构成一个完整的页面。

注意

如果用的是 ReactVueSolidJS 这样的 JavaScript 框架,那么您就不会对模块这个概念感到陌生,因为其中的 JavaScript 也是以类似的方式组织成组件(component)的。在按模块组织 CSS 时,所构建的 CSS 模块很可能与 JavaScript 组件一一对应,只是这样的关联并非强制要求。

9.1.1 模块和全局样式 Modules and global styles

在开始编程模块化样式前,需要提前备好一些基础样式(basic styles),包括常用的重置样式(resets)和全局样式(如字体)。鉴于这些样式会影响到页面上的所有内容,在构建任何特定模块之前,都需要提前设置这些样式。

新建一个页面并关联一个样式表,然后将代码清单 9.1 中的基础样式和全局样式添加到 CSS 中。reset 重置图层的样式取自上一章代码清单 8.5。

代码清单 9.1 添加重置样式与全局样式代码

@layer reset, global, modules;

@layer reset {
  *,
  *::before,
  *::after {
    box-sizing: border-box;
  }

  body {
    margin: unset;
  }

  button,
  input,
  textarea,
  select {
    font: inherit;
  }

  img,
  picture,
  svg,
  canvas {
    display: block;
    max-width: 100%;
    height: auto;
  }
}

@layer global {
  body {
    font-family: Helvetica, Arial, sans-serif;
  }
}

根据第 8 章的介绍,我们知道一个完整的网站可能会用到更多的图层;但上述代码已经足以让我们对模块进行更深入的了解。

层叠图层并非编写模块化 CSS 的先决条件(prerequisite)。如果因为浏览器不支持 CSS 图层功能而无法正常使用,您仍然可以遵循这些模块构建原则。

9.1.2 一个简单的模块 A simple module

下面来创建一个用于发送简短通知信息的简单模块。每个模块都需要一个唯一的名称,不妨将该模块命名为 message(即“消息”模块)。为了吸引用户注意,可以加上一些颜色和边框效果,如图 9.1 所示:

图 9.1 message 消息模块样式示意图

【图 9.1 message 消息模块样式示意图】

该模块的 HTML 标记是一个带 message 样式类的 div 元素。将其添加到您的页面。

代码清单 9.2 message 消息模块的 HTML 标记

<div class="message">
  Save successful
</div>

模块的 CSS 是一个规则集,可通过类名选中该模块。CSS 中设置了内边距、边框、圆角半径以及字体颜色等样式。只要将代码清单 9.3 添加到基础样式后,就可以令这些样式应用到消息模块了。

代码清单 9.3 message 消息模块的样式实现

@layer modules {
  .message { /* 通过类名选中 message 消息模块 */
    padding: 0.8em 1.2em;
    border-radius: 0.2em;
    border: 1px solid #265559;
    color: #265559;
    background-color: #e0f0f2;
  }
}

这些属性应该非常熟悉了,至少现在看上去跟您在本书见到的其他 CSS 代码类似,并没有什么特别之处。事实上,我们写过的 CSS 代码有很多是符合模块化 CSS 的原则的,只是之前并没有专门提及罢了。下面来重点分析一下这些 CSS 是如何模块化的。

有一点非常重要:该模块的选择器只包含一个类名。该选择器中并没有其他规则来限制这些样式只对页面某个位置生效。例如使用像 #sidebar .message 这样的选择器,则表示该模块只能在 #sidebar 元素内使用;一旦取消这一限制条件,该模块即可在任何上下文中重复使用。

通过给元素添加类名,就可以把这些样式复用到很多场景,比如根据表单输入提供用户反馈信息、提供醒目的帮助文字,抑或是提醒用户注意某个系统通知等等。通过复用同一个模块,就能在任意位置实现一致的用户界面,不必担心某些地方的蓝绿色有色差,或者某些地方的内边距偏大等问题。

我曾经在没有模块化 CSS 的项目里工作过,其中一个项目出现过好几个类似的按钮:.save-form button.login-form button 以及 .toolbar .options button。同样的代码在样式表中重复出现了多次,尽管并不是完全的复制。这么做旨在获得一致的用户体验,本无可厚非;但随着时间的推移,不同的按钮间还是出现了一些不一样的样式调整,导致有的按钮内边距略有不同,而有的按钮又红得更鲜艳。

这个问题的解决办法,就是把按钮样式重构成一个可复用的模块,不受页面位置的限制。创建 CSS 模块不仅可以精简代码(减少冗余),还可以保证视觉上的一致性。这样处理后看上去也更专业,不会给人仓促堆砌的感觉。用户在潜意识里也会更容易信赖我们的应用程序。

篇幅原因,9.1 节的后面两小节内容放到下篇介绍,敬请关注!



关于《CSS in Depth》(中译本书名《深入解析 CSS》)

第 1 版第 2 版
读者评分原版:4.7(亚马逊);中文版:9.3(豆瓣)原版:5.0(亚马逊);中文版:暂无,待出版
出版时间原版:2018 年 3 月;中文版:2020 年 4 月原版:2024 年 7 月;中文版:暂无,待出版
原价原版:$44.99;中文版:¥139.00原版:$59.99;中文版:暂无,待出版
现价原版:$36.49;中文版:¥52.54 起步原版:$52.09;中文版:暂无,待出版
原版国内预订起步价 ¥461.00起步价 ¥750.00

本专栏为该书第 2 版高分译文专栏,全网首发,精译精校,持续更新,计划今年内完成全书翻译,敬请期待!!!

目前已完结的章节(可进入本专栏查看详情,连载期间完全免费):

  • 第一章 层叠、优先级与继承(已完结)
    • 1.1 层叠
    • 1.2 继承
    • 1.3 特殊值
    • 1.4 简写属性
    • 1.5 CSS 渐进式增强技术
    • 1.6 本章小结
  • 第二章 相对单位(已完结)
    • 2.1 相对单位的威力
    • 2.2 em 与 rem
    • 2.3 告别像素思维
    • 2.4 视口的相对单位
    • 2.5 无单位的数值与行高
    • 2.6 自定义属性
    • 2.7 本章小结
  • 第三章 文档流与盒模型(已完结)
    • 3.1 常规文档流
    • 3.2 盒模型
    • 3.3 元素的高度
    • 3.4 负的外边距
    • 3.5 外边距折叠
    • 3.6 容器内的元素间距问题
    • 3.7 本章小结
  • 第四章 Flexbox 布局(已完结)
    • 4.1 Flexbox 布局原理
    • 4.2 弹性子元素的大小
    • 4.3 弹性布局的方向
    • 4.4 对齐、间距等细节处
    • 4.5 本章小结
  • 第五章 网格布局(已完结)
    • 5.1 构建基础网格
    • 5.2 网格结构剖析 (上)
      • 5.2.1 网格线的编号(下)
      • 5.2.2 网格与 Flexbox 配合(下)
    • 5.3 两种替代语法
      • 5.3.1 命名网格线
      • 5.3.2 命名网格区域
    • 5.4 显式网格与隐式网格(上)
      • 5.4.1 添加变化 (中)
      • 5.4.2 让网格元素填满网格轨道(下)
    • 5.5 子网格(全新增补内容)
    • 5.6 对齐相关的属性
    • 5.7 本章小结
  • 第六章 定位与堆叠上下文(已完结)
    • 6.1 固定定位
      • 6.1.1 创建一个固定定位的模态对话框
      • 6.1.2 在模态对话框打开时防止屏幕滚动
      • 6.1.3 控制定位元素的大小
    • 6.2 绝对定位
      • 6.2.1 关闭按钮的绝对定位
      • 6.2.2 伪元素的定位问题
    • 6.3 相对定位
      • 6.3.1 创建下拉菜单(上)
      • 6.3.2 创建 CSS 三角形(下)
    • 6.4 堆叠上下文与 z-index
      • 6.4.1 理解渲染过程与堆叠顺序(上)
      • 6.4.2 用 z-index 控制堆叠顺序(上)
      • 6.4.3 深入理解堆叠上下文(下)
    • 6.5 粘性定位
    • 6.6 本章小结
  • 第七章 响应式设计(已完结)
    • 7.1 移动端优先设计原则(上篇)
      • 7.1.1 创建移动端菜单(下篇)
      • 7.1.2 给视口添加 meta 标签(下篇)
    • 7.2 媒体查询(上篇)
      • 7.2.1 深入理解媒体查询的类型(上篇)
      • 7.2.2 页面断点的添加(中篇)
      • 7.2.3 响应式列的添加(下篇)
    • 7.3 流式布局
    • 7.4 响应式图片
    • 7.5 本章小结
  • 第八章 层叠图层及其嵌套
    • 8.1 用 layer 图层来操控层叠规则(上篇)
      • 8.1.1 图层的定义(上篇)
      • 8.1.2 图层的顺序与优先级(下篇)
      • 8.1.3 revert-layer 关键字(下篇)
    • 8.2 层叠图层的推荐组织方案
    • 8.3 伪类 :is() 和 :where() 的用法
    • 8.4 CSS 嵌套的使用
      • 8.4.1 嵌套选择器的使用
      • 8.4.2 深入理解嵌套选择器
      • 8.4.3 媒体查询及其他 @规则 的嵌套
    • 8.5 本章小结

原文地址:https://blog.csdn.net/frgod/article/details/143824455

免责声明:本站文章内容转载自网络资源,如本站内容侵犯了原著者的合法权益,可联系本站删除。更多内容请关注自学内容网(zxcms.com)!