【CSS in Depth 2 精译_064】10.3 CSS 中的容器查询相对单位 + 10.4 CSS 容器样式查询 + 10.5 本章小结

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

  • 【第十章 CSS 容器查询】 ✔️
    • 10.1 容器查询的一个简单示例
      • 10.1.1 容器尺寸查询的用法
    • 10.2 深入理解容器
      • 10.2.1 容器的类型
      • 10.2.2 容器的名称
      • 10.2.3 容器与模块化 CSS
    • 10.3 与容器相关的单位 ✔️
    • 10.4 容器样式查询的用法 ✔️
      • 10.4.1 将模块与所在容器解耦 ✔️
      • 10.4.2 减少重复代码 ✔️
    • 10.5 本章小结 ✔️

文章目录

    • 10.3 容器相对单位 Container-relative units
    • 10.4 容器样式查询 Container style queries
      • 10.4.1 将模块与所在容器解耦 Decoupling a module from its container
        • 10.4.1.1 样式查询相较于其他方法的优势 The benefits of style queries over other approaches
      • 10.4.2 减少重复代码 Reducing code duplication
    • 10.5 本章小结 Summary

《CSS in Depth》新版封面

《CSS in Depth》新版封面

译者按
再次怀着敬畏之心完成了本章剩余内容的翻译。时隔数月,全新的容器样式查询功能已经得到了 Chrome、Edge、Safari 等主流浏览器的全面支持(仅剩 Firefox 暂不支持),深感前端技术更迭的迅猛。大伙也无需过度焦虑,因为万丈高楼平地起,所有的新功能、新特性都不是空中楼阁,都需要接受时间的终极检验。只要我们筑牢 CSS 基础,稳扎稳打,就一定能以不变应万变。

10.3 容器相对单位 Container-relative units

容器查询也引出了几个基于容器的相对单位。它们在概念上类似于第二章中介绍的视口相对单位,只不过是基于查询容器而言的。具体包括以下六种:

  • cqw —— 1cqw 表示容器宽度的 1%;
  • cqh —— 1cqh 表示容器高度的 1%;
  • cqi —— 1cqi 表示容器行内尺寸的 1%;
  • cqb —— 1cqb 表示容器块级尺寸的 1%;
  • cqmin —— 一单位 cqmin 指代 cqicqb 中较小的那个相对单位;
  • cqmax —— 一单位 cqmax 指代 cqicqb 中较大的那个相对单位。

就像无法对设置了 inline-size 类型的容器进行块级尺寸查询一样,容器类型为 inline-size 的容器也无法使用块级方向上的相对单位(即水平书写模式下的 cqbcqh)。如果在 DOM 树的更高层级存在一个容器类型为 size 的容器,则这些相对单位均以该容器为基础进行度量;否则将回退到视口相对单位的行为模式。

接下来演示这些相对单位在一些容器查询中的具体用法。示例页面包含一组公路赛跑的详情卡片。本例将对这些卡片设置网格布局,并让某些卡片比其他卡片更大,以此来演示容器相对单位在响应不同容器尺寸时的工作原理。最终效果如图 10.6 所示 1

图 10.6 经过容器查询相对单位处理后的公路赛跑详情卡片效果图

【图 10.6 经过容器查询相对单位处理后的公路赛跑详情卡片效果图】

首先要在您的本地示例页添加一些卡片的 HTML 标记,包括一个 <main> 元素,里面又包含一个 <h1> 标题;还应该有个与 <main> 平级的 <aside> 元素(详见第 10 章概述部分的代码清单 10.1)。然后将代码清单 10.5 中的示例 HTML 同步更新到本地页面,里面的几个带图片的详情卡片共同构成了本例中的比赛网格;而 <aside> 元素暂时不变。

代码清单 10.5 公路赛跑网格及详情卡片 HTML 标记

<main><h1>Franklin Running Club</h1><div class="race-grid"><div class="race-detail"><img src="race.jpg" /><div class="race-detail__body"><h3>Union County 10K</h3><p class="rate-detail__date">Saturday, April 14</p></div></div><div class="race-detail"><img src="shoe.jpg" /><div class="race-detail__body"><h3>St. Patrick's Day 5K</h3><p class="rate-detail__date">Saturday, March 17</p></div></div><div class="race-detail"><img src="runner-hill.jpg" /><div class="race-detail__body"><h3>2 mile uphill</h3><p class="rate-detail__date">Thursday, March 29</p></div></div></div>
</main>

如您所见,每个详情卡片都包含一张图片和一段正文,而正文部分又包含一个标题和一个日期。

接下来设置网格布局,并给详情卡片设计一些基础样式,如代码清单 10.6 所示。示例代码中的相对单位 cqi 主要有两个作用,分别控制图片和标题文字的大小。按照示例代码更新样式,也放到样式表的 modules 图层:

代码清单 10.6 响应式设计下的详情卡片示例样式代码

@layer modules {.race-grid {display: grid;grid-template-columns: 2fr 3fr;grid-auto-rows: 1fr;gap: 1rem;}.race-grid > :nth-child(3n - 1) { /* 从第二个详情卡片开始,每隔两张卡片横跨两个网格行 */grid-row: span 2;}.race-detail {container: layout / inline-size; /* 为卡片建立容器 */border: 1px solid #ccc;}.race-detail > img {inline-size: 100%;max-block-size: 30cqi; /* 图像高度不超过容器宽度的 30% */object-fit: cover; /* 图片填充过程中允许裁剪,以免拉伸变形 */}.race-detail__body {padding: 1rem 1.5rem;}.race-detail__body > h3 {font-size: clamp(1rem, 3.5cqi, 1.8rem); /* 字号定义为容器宽度的 3.5% */font-family: Helvetica, sans-serif;}
}

以上代码用到了伪类选择器 :nth-child() 来选中自然编号为三的倍数的网格单元,从第二个元素开始。这样就能满足本例中右侧卡片列较宽的实际需要。这么写之所以有效,是因为 :nth-child(3n) 依次选中的是页面第三、第六、第九项……以此类推;而写作 :nth-child(3n - 1) 就能对应选中第二、第五、第八项……以此类推。有关 :nth-child() 选择器的更多写法,详见本书 附录 A 2

此外,代码中也用到了相对单位 cqi,使得标题字号直接与详情卡片的宽度成正比,具体取值为容器尺寸的 3.5%;而内置函数 clamp() 进一步限制了字号的上下边界:最小字号为 1rem、最大字号为 1.8rem。 同理,图片高度的设置也是响应式的,具体取值为容器宽度的 30%。这些样式声明不仅能在大小两类详情卡片中响应容器尺寸的变化,还能根据整体视口的宽度同步缩放,因为网格本身的尺寸也在发生改变。

值得注意的是,尽管上述代码使用了容器相对单位,但并不需要添加任何 @container 查询规则。容器查询的应用场景仅限于需要基于容器尺寸大小选择性地生效某些 CSS 样式;而在本例中,样式始终是生效的。

10.4 容器样式查询 Container style queries

容器查询(container query 一词长期以来一直用于指代根据容器的尺寸大小做出相应调整的基本思路;但除了响应容器尺寸的变化情况,还可以根据容器样式的其他方面做出响应,由此引入了另一个与 容器尺寸查询(container size queries 相对的全新概念,人们称之为 容器样式查询(container style queries

有了容器样式查询,人们就能根据自定义属性的取值有选择性地应用某些样式。书写时需要利用 style() 函数语法,具体格式如下:

@container style(--color-theme: dark) {/* conditional styles */
}

当一个元素继承了指定的自定义属性值后,样式查询代码块内的选择器就可以选中其后代元素,并对这些元素应用条件样式。例如上述代码,其判定条件即:自定义属性 --color-theme 的值是否为 dark

使用样式查询前无需显式地定义某个容器。这是因为当您无需基于容器尺寸进行容器查询时,自然也不需要对容器的尺寸进行限制或约束。

警告

ChromeEdge 浏览器已于 2023 年 3 月正式添加了对容器样式查询的特性支持。截至 2024 年 6 月前后,FirefoxSafari 浏览器仍未提供相应支持,该功能仍被视为实验阶段的功能特性,未来可能会有所变化。查看容器样式查询在当前浏览器的最新支持情况,请参阅 Can I use 官网:https://mng.bz/8wQZ。

译注

根据 Can I use 官网提供的最新数据,截至 2024 年 11 月 29 日,Safari 已经对容器样式查询提供了相应支持,当前主流浏览器中仅 Firefox 暂不支持该特性,该功能的整体覆盖率已达 74.12%,以下为最新查询结果截图:

当前浏览器各大厂商对容器样式查询功能的最新支持情况(截至 2024 年 11 月 29 日)

【当前浏览器各大厂商对容器样式查询功能的最新支持情况(截至 2024 年 11 月 29 日)】

由于尚未得到浏览器的广泛支持,容器样式查询也仅限部分支持渐进式增强的应用场景,该功能的全面推广应用尚需时日;然而这丝毫不影响容器样式查询成为前端一个非常实用的全新工具,越来越多的开发者都热切期盼着容器样式查询真正推广普及这一天的到来。接下来就让我们先睹为快,看看这个容器样式查询究竟好用在哪里。

10.4.1 将模块与所在容器解耦 Decoupling a module from its container

有时候,人们希望模块能在页面某个特定的上下文中渲染出不一样的效果。为了举例说明,本节将通过样式查询对放置在特定上下文中的详情卡片样式进行调整,并通过设置一个自定义属性 --sidebar 来识别该上下文。

如图 10.7 所示,示例页面的右侧边栏中已经添加了一个上节演示过的详情卡片。同时在这个侧边栏中设置了 --sidebar 属性,详情卡片将基于该属性实现响应式布局。

图 10.7 公路赛跑详情卡片在侧边栏中改为横向布局

【图 10.7 公路赛跑详情卡片在侧边栏中改为横向布局】

我们先将主内容区的一个比赛详情卡片复制到旁边的 <aside> 元素中。在真实网站场景下,也许并不会像这样重复使用一张卡片,而是以某个独立的页面单独渲染到侧边栏中;但对于本节要演示的重点而言已经完全够用了。

接着添加 CSS 样式来设置自定义属性 --sidebar,并让详情卡片的样式布局基于该属性作响应式变更。根据代码清单 10.7 所示内容同步更新本地样式表的 layoutmodules 图层。这样就触发了对属性 --sidebar 的样式查询,容器样式仅在该属性值为 true 时生效:

代码清单 10.7 利用容器样式查询变更模块的布局样式

@layer layout {.l-page > aside {--sidebar: true; /* 在侧边栏中设置属性 --sidebar 的值 */}
}@layer modules {@container style(--sidebar: true) { /* 容器样式仅在 --sidebar 属性为 true 时生效 */.race-detail {margin-block: 1em;display: flex;}.race-detail > img {flex: 0 0 30cqi;}.race-detail__body > h3 {margin-block-start: 0;}}
}

上述代码中,容器样式查询通过设置 Flexbox 布局将侧边栏内的详情卡片改为了横向布局,图片宽度则调整为容器行内尺寸(译注:即容器宽度)的 30%;此外还对标题部分的外边距作了微调。这些基于自定义属性 --sidebar 的布局样式变更仅在右侧边栏中生效。

10.4.1.1 样式查询相较于其他方法的优势 The benefits of style queries over other approaches

如果不用容器样式查询,通过其他方式也能实现类似的效果,但它们往往需要开发者做出一些必要的取舍(tradeoff)。

例如,可以根据模块在 DOM 树中的位置直接修改对应的样式,比如通过选择器 .l-page > aside .race-detail 实现。但正如我在第 9 章中提过的,该方案违背了模块化 CSS 的核心构建原则 —— 此时 race-detaill-page 严重耦合,对其中一个的样式进行修改很可能需要同步修改另一个的样式。

此外,后续可能还会出现其他上下文,也需要做类似的调整。如果侧边栏出现在另一个单独的页面布局中,之前那个选择器就失效了,只能再加一个类似 .l-search-results > .sidebar .race-detail 的选择器,其优先级(selector specificity)也会因此居高不下。

另一个替代方案是引入模块的变体形式(module variant)。例如将侧边栏的 HTML 标记改为 <div class="race-detail race-detail--horizontal">,并利用第二个样式类定义一个模块变体,与第 9 章示例中的做法类似。

使用模块变体的解决方案固然没有明显的硬伤,并且在某些特定场景下甚至还可能是最佳方案,例如希望构建 HTML 的开发者能根据需求使用相应的变体,这时就可以考虑这种实现方式;然而有时拿到的需求是希望通过 CSS 而非 HTML 来实现响应式效果,此时样式查询就派上用场了,无需将模块样式与特定的包裹元素耦合到一起。

10.4.2 减少重复代码 Reducing code duplication

有时也会遇到这样的情况:只要预设几种情况发生了其中任意一种,就选择性地启用相应的样式。此时,容器样式查询就提供了一个单一的切入口,可以省去书写大量重复代码的麻烦。您可以通过 JavaScript、媒体查询或者元素的类名来设置需要的自定义属性;然后让容器样式查询基于该属性对这些预设情况做出响应,让对应的样式规则生效。

上述问题的一个常见应用场景,出现在需要切换明暗模式的网站中。理想情况下,我们可以利用一个 prefers-color-scheme 的媒体查询来初始化页面的正常渲染模式;同时也允许网站通过一些由 JavaScript 控制的用户输入来自主切换明暗模式。

接下来通过实现一个页面的深色模式来演示样式查询在当中所起到的简化作用。本节演示分三步走。首先通过 prefers-color-scheme 媒体查询来设置一个自定义属性 --color-theme;然后规定当 <html> 元素中存在 data-theme 属性,就覆盖该自定义属性的值;接着再添加一些按钮来切换 data-theme 的属性值,从而实现页面主题的切换。最后就可以利用样式查询在特定位置将模块切到深色模式。启用页面深色模式的最终效果如图 10.8 所示。

图 10.8 利用样式查询实现的页面深色模式效果图

【图 10.8 利用样式查询实现的页面深色模式效果图】

代码清单 10.8 给出了第一步的示例代码,即根据用户的系统设置或者 HTML 元素是否存在 data-theme 属性来决定是否启用页面深色模式。请按照以下代码同步更新本地样式表。

代码清单 10.8 通过自定义属性启用深色模式的样式代码

@layer base {:root {--color-theme: light; /* 根据系统设置切换浅色主题 */}@media (prefers-color-scheme: dark) {:root {--color-theme: dark; /* 根据系统设置切换深色主题 */}}/* 如果用户手动指定了主题,则覆盖系统设置 */[data-theme="light"] {--color-theme: light;}[data-theme="dark"] {--color-theme: dark;}/* 将深色主题色应用到页面 */@container style(--color-theme: dark) {body {background-color: #555;color: white;color-scheme: dark;}}
}

通过这里的容器样式查询,您已经不用重复编写最终的样式了:只要根据媒体查询条件和 HTML 属性的变更情况作出响应,就能启用相应的样式了。要是不用容器样式查询来实现,最终的 CSS 代码估计会像下面这样(切勿添加到本地样式表):

@layer base {body {background-color: white;color: black;color-scheme: light;}@media (prefers-color-scheme: dark) {body {background-color: #555;color: white;color-scheme: dark;}}[data-theme="light"] body {background-color: white;color: black;color-scheme: light;}[data-theme="dark"] body {background-color: #555;color: white;color-scheme: dark;}
}

对比代码清单 10.8,为了确保主题颜色准确无误地渲染,平替方案需要在相对简单的前一版样式基础上编写大量的重复代码。此外,当需要根据深色模式对模块进行样式调整时——稍后就会这么干——每次都得重复类似的操作,无疑将使样式表变得越来越复杂。因此大多数开发者都认为这样的平替方案不太可靠。

现如今有了样式查询来解决重复代码的问题,就可以进一步在页面设置按钮,让用户自行切换主题了。代码清单 10.9 给出了对应的 HTML 标记和 JavaScript 示例脚本。请将它们同步添加到页面的 <aside> 标签后、</body> 闭标签前。

代码清单 10.9 允许用户自主切换深色或浅色模式的示例组件代码

<footer><button id="light-theme">Light mode</button><button id="dark-theme">Dark mode</button>
</footer>
<script type="text/javascript">const lightThemeButton = document.getElementById("light-theme");const darkThemeButton = document.getElementById("dark-theme");lightThemeButton.addEventListener("click", () => {document.documentElement.setAttribute("data-theme", "light");});darkThemeButton.addEventListener("click", () => {document.documentElement.setAttribute("data-theme", "dark");});
</script>

上述代码中的按钮可以在 <html> 元素指定适当的 data-theme 属性值。结合代码清单 10.8 中的 CSS 样式,可以实现用户自主切换颜色主题。

最后一步,是在启用深色模式时,根据需要对页面上的模块样式进行微调。浅色模式已经能正常工作了,毕竟它是页面构建时的默认主题。

代码清单 10.10 给出了具体的样式变更设置。将这些代码同步到本地样式表。为了方便演示,这里省略了已有的 CSS 样式;但作为最佳实践,应该将当中关于媒体模块的调整代码与页面其他媒体模块的代码放到一起;而与详情卡片相关的调整代码与页面其他详情卡片的代码放到一起。(同时还需要确保这两个样式查询位于浅色模式的样式代码后面,确保它们能按预期方式覆盖掉那些样式)

代码清单 10.10 页面启用深色模式后相关模块的样式调整代码

@layer modules {@container style(--color-theme: dark) {.media {background-color: #5f5f5f;}}@container style(--color-theme: dark) {.race-detail {background-color: #333;color: #eee;}}
}

至此,页面深色模式的切换就大功告成了。当页面首次加载时,页面主题会根据操作系统的设置进行初始化;当用户单击浅色模式或深色模式按钮,页面则切换到对应的页面主题。

本例中的部分内容还可以进一步优化,例如通过精心规划自定义属性来进一步调整相关元素的背景色及文字颜色。这些细节处理也可以在样式表的开头根据样式查询一次性变更过来。下一章我将介绍一些利用这种方式管理页面颜色变量的实用策略。

作为进一步的功能增强,还可以添加更多 JavaScript 逻辑,确保相关设置在后续的页面访问中自动加载,比如调用 localStorage 相关的 API 接口。不过,为了不超出本书讲述的知识范围,这里就不过多展开 JavaScript 的应用了。

遗憾的是,容器样式查询至今尚未得到广泛支持(译注:其实主流浏览器中目前只剩 Firefox 浏览器了),无法用于日常工作。在对页面进行功能方面的小幅增强时可以放心大胆地尝试;若要将其作为页面核心功能使用,最好先关注一下最新的浏览器兼容情况,综合各方面因素后再做打算。

容器样式查询展望

在未来,浏览器可能会支持基于 CSS 值(CSS values)的容器样式查询,而不仅限于自定义属性。起初,这一概念是包含了这个想法的 —— 例如,可以基于字体颜色来查询,写作 @container style(color: black)。但最终的规范将适用范围缩小至仅限自定义属性,似乎这样就已经能满足绝大多数的实际需求;但后续不排除将 CSS 值重新纳入语法规范中,相关进展值得进一步关注。

容器尺寸查询为响应式设计带来了期待已久的重大改进,而容器样式查询则有望在此基础上实现相关功能的进一步提升。这两个新特性可谓近年来 CSS 语言领域里极为重要的增强功能。

在实际应用这些功能时,请务必考虑浏览器的兼容情况。容器尺寸查询目前仍是前端开发非常新的特性功能,在某些浏览器中仍处于有待支持状态。如果对旧版浏览器中展示的备选样式还算满意的话,可以考虑通过 CSS 的渐进式增强来启用这些新写法;但要注意尽量在 @container 规则外书写样式,以便更好地定义这些备选样式。

10.5 本章小结 Summary

  • 容器尺寸查询可以基于容器尺寸的变化响应不同的样式,这往往比传统的媒体查询更加实用。
  • 给元素指定容器类型就能建立一个容器。再利用 @container 规则查询容器尺寸,就能对其子元素设置相应的样式。
  • 对于设置了 inline-sizesize 类型的容器,其内部元素可能不会影响对应维度上的尺寸大小。
  • 容器相对单位通过目标元素的实际尺寸与所在容器的行内或块级尺寸的百分比来丈量大小,概念上与视口相对单位非常类似。
  • 在容器查询中,style() 函数可以基于容器中的自定义属性值来选择性地启用相关样式。这是一个当前浏览器正在逐步提供支持的全新功能特性。


关于《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 本章小结
  • 第九章 CSS 的模块化与作用域
    • 9.1 模块的定义
      • 9.1.1 模块和全局样式
      • 9.1.2 一个简单的 CSS 模块
      • 9.1.3 模块的变体
      • 9.1.4 多元素模块
    • 9.2 将模块组合为更大的结构
      • 9.2.1 模块中多个职责的拆分
      • 9.2.2 模块的命名
    • 9.3 CSS 的作用域
      • 9.3.1 CSS 作用域的就近原则
      • 9.3.2 划定作用域的边界
      • 9.3.3 CSS 中的隐式作用域
      • 9.3.4 关于 CSS 作用域与层叠图层
    • 9.4 CSS 模式库
    • 9.5 本章小结

  1. 详见随书源码示例页 ch10/listing-10.06.html ↩︎

  2. 译注:考虑到书中多次提及附录内容,待第 10 章译完再列入计划,届时也将同步更新各专栏文章中的附录引用链接,敬请关注。 ↩︎

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/diannao/62592.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

TYUT设计模式精华版

七大原则 单一职责原则 职责要单一不能将太多的职责放在一个类中 开闭原则 软件实体对扩展是开放的&#xff0c;但对修改是关闭的 里氏代换原则 一个可以接受基类对象的地方必然可以接受子类 依赖倒转原则 要针对抽象层编程&#xff0c;而不要针对具体类编程 接口隔离原则 …

电阻的基本应用

从使用数量的角度来看&#xff0c;电阻在电子元器件中的数量要占到30%以上&#xff0c;电阻可以在电路中用于分压、分流、限流、负载、反馈、阻抗匹配、RC充放电电路、上下拉、运算放大器外围电路、兼容设计电路、电流转电压等&#xff0c;下面介绍一下电阻的基本应用 在集总参…

EXCEL截取某一列从第一个字符开始到特定字符结束的字符串到新的一列

使用EXCEL中的公式进行特定截取 假设列A是一组产品的编码&#xff0c;我们需要的数据是“-”之前的字段。 我们需要在B1单元格输入公式“LEFT(A1,SEARCH("-",A1)-1)”然后选中B1至B4单元格&#xff0c;按“CTRLD”向下填充&#xff0c;就可以得出其它几行“-”之前的…

Cisco WebEx 数据平台:统一 Trino、Pinot、Iceberg 及 Kyuubi,探索 Apache Doris 在 Cisco 的改造实践

导读&#xff1a;Cisco WebEx 早期数据平台采用了多系统架构&#xff08;包括 Trino、Pinot、Iceberg 、 Kyuubi 等&#xff09;&#xff0c;面临架构复杂、数据冗余存储、运维困难、资源利用率低、数据时效性差等问题。因此&#xff0c;引入 Apache Doris 替换了 Trino、Pinot…

python基础(五)

正则表达式 在编写处理字符串的程序或网页时&#xff0c;经常会有查找符合某些复杂规则的字符串的需要。正则表达式就是用于描述这些规则的工具。换句话说&#xff0c;正则表达式就是记录文本规则的代码。 符号解释示例说明.匹配任意字符b.t可以匹配bat / but / b#t / b1t等\…

电机瞬态分析基础(7):坐标变换(3)αβ0变换,dq0变换

1. 三相静止坐标系与两相静止坐标系的坐标变换―αβ0坐标变换 若上述x、y坐标系在空间静止不动&#xff0c;且x轴与A轴重合&#xff0c;即&#xff0c;如图1所示&#xff0c;则为两相静止坐标系&#xff0c;常称为坐标系&#xff0c;考虑到零轴分量&#xff0c;也称为αβ0坐标…

Mac 环境下类Xshell 的客户端介绍

在 Mac 环境下&#xff0c;类似于 Windows 环境中 Xshell 用于访问 Linux 服务器的工具主要有以下几种&#xff1a; SecureCRT&#xff1a; 官网地址&#xff1a;https://www.vandyke.com/products/securecrt/介绍&#xff1a;支持多种协议&#xff0c;如 SSH1、SSH2、Telnet 等…

Java 泛型详细解析

泛型的定义 泛型类的定义 下面定义了一个泛型类 Pair&#xff0c;它有一个泛型参数 T。 public class Pair<T> {private T start;private T end; }实际使用的时候就可以给这个 T 指定任何实际的类型&#xff0c;比如下面所示&#xff0c;就指定了实际类型为 LocalDate…

arkTS:持久化储存UI状态的基本用法(PersistentStorage)

arkUI&#xff1a;持久化储存UI状态的基本用法&#xff08;PersistentStorage&#xff09; 1 主要内容说明2 例子2.1 持久化储存UI状态的基本用法&#xff08;PersistentStorage&#xff09;2.1.1 源码1的相关说明2.1.1.1 数据存储2.1.1.2 数据读取2.1.1.3 动态更新2.1.1.4 显示…

OSPTrack:一个包含多个生态系统中软件包执行时生成的静态和动态特征的标记数据集,用于识别开源软件中的恶意行为。

2024-11-22 &#xff0c;由格拉斯哥大学创建的OSPTrack数据集&#xff0c;目的是通过捕获在隔离环境中执行包和库时生成的特征&#xff0c;包括静态和动态特征&#xff0c;来识别开源软件&#xff08;OSS&#xff09;中的恶意指标&#xff0c;特别是在源代码访问受限时&#xf…

UDP客户端服务器通信

在这篇博客中&#xff0c;我们将探索 UDP&#xff08;用户数据报协议&#xff09; 通信&#xff0c;简要地说&#xff0c;UDP 是一种无连接、快速但不可靠的通信协议&#xff0c;适用于需要快速数据传输但对丢包容忍的场景&#xff0c;比如视频流和在线游戏。就像《我是如此相信…

Unreal Engine使用Groom 打包后报错

Unreal Engine使用Groom打包后报错 版本5.4.4 blender 4.2.1 项目头发用了groom&#xff0c;运行后报错 错误&#xff1a; Assertion failed: Offset BytesToRead < UncompressedFileSize && Offset > 0 [File:E:\UnrealEngine-5.4.4-release\Engine\Source\R…

deepin 安装 chrome 浏览器

deepin 安装 chrome 浏览器 最近好多小伙伴儿和我说 deepin 无法安装最新的谷歌浏览器 其实是因为最新的 谷歌浏览器 其中的一个依赖需要提前安装 提前安装依赖然后再安装谷歌浏览器就可以了 安装 fonts-liberationsudo apt -y install fonts-liberation安装 chrome 浏览器sudo…

ffmpeg 增亮 docker 使用

使用最新的 docker pull jrottenberg/ffmpeg docker run -it --rm -v /path/to/input:/input -v /path/to/output:/output jrottenberg/ffmpeg <ffmpeg command>比如我想增亮 在 /home 目录下 有一个 video.mp4 docker run --rm -v /home:/home jrottenberg/ffmpeg:7…

小白可以报名鸿蒙开发培训吗

随着科技的飞速发展&#xff0c;尤其是移动互联网和智能硬件的不断进步&#xff0c;各大科技公司纷纷推出了自家的操作系统&#xff0c;而华为的鸿蒙系统(HarmonyOS)无疑成为了其中的佼佼者。随着鸿蒙系统的逐步推广&#xff0c;越来越多的开发者开始关注这一新的开发平台。那么…

Figma入门-原型交互

Figma入门-原型交互 前言 在之前的工作中&#xff0c;大家的原型图都是使用 Axure 制作的&#xff0c;印象中 Figma 一直是个专业设计软件。 最近&#xff0c;很多产品朋友告诉我&#xff0c;很多原型图都开始用Figma制作了&#xff0c;并且很多组件都是内置的&#xff0c;对…

Linux内核机制自学笔记

摘抄于大学期间记录在QQ空间的一篇自学笔记&#xff0c;当前清理空间&#xff0c;先搬移过来&#xff0c;也不知道到底是对是错了。 1、Linux内存管理 在计算机的世界&#xff0c;内存犹如一条长河&#xff0c;在这条长河中&#xff0c;cpu将这条长河划分成了段和页。cpu要将一…

ES----安装 elasticsearch入门,elasticsearch安装,centos安装es,centos安装elasticsearch

ES 如需要对应资源&#xff0c;请评论留言&#xff0c;或再最后视频中关注获取 1. 安装 1.1 安装es 创建网络&#xff08;centos系统&#xff0c;docker环境&#xff09; docker network create es-netdocker安装es —如果下载失败&#xff0c;请看我的docker配置镜像的文章…

Milvus×Florence:一文读懂如何构建多任务视觉模型

近两年来多任务学习&#xff08;Multi-task learning&#xff09;正取代传统的单任务学习&#xff08;single-task learning&#xff09;&#xff0c;逐渐成为人工智能领域的主流研究方向。其原因在于&#xff0c;多任务学习可以让我们以最少的人力投入&#xff0c;获得尽可能多…

172页PPT集团数字化转型采购供应链及财务管控业务流程指南

一、供应商管理与数字化转型 1.1供应商管理数字化的重要性与挑战 重要性&#xff1a; 效率提升&#xff1a; 数字化可以提高供应商管理的效率&#xff0c;通过自动化流程减少手动操作&#xff0c;加快决策速度。透明度增强&#xff1a; 数字化工具可以提供实时数据&#xff…