Springboot(四十八)SpringBoot3开启缓存(本地缓存caffeine,远程缓存redis)

阅读 7

2024-12-03

文章目录

《CSS in Depth》新版封面

《CSS in Depth》新版封面

10.2 深入理解容器 A closer look at containers

上一节定义容器时,我们给容器指定了一个名称和对应的容器类型。本节我们将深入考察这些属性的行为模式,并了解它们的具体用途。虽然前面的示例并不难,但在使用容器时,也需要了解一些特定的限制;深入理解容器类型带来的影响尤为重要。

10.2.1 容器的类型 Container types

十多年来,浏览器厂商一直认为这个功能永远无法实现,主要是因为他们担心会产生无限循环。假设有这样一个场景,需要查询一个高度小于 300px 的容器;当符合查询条件时,其中一个元素的字号会放大至 2em,这反过来又将增加该元素的高度,从而撑大所在容器的高度,最终导致容器查询条件匹配失败——进而字号回落到原始大小,然后查询条件再次触发,循环往复,永无休止。

而在容器查询的设计过程中,决不允许出现这样的无限循环。为此,CSS 引入了 局限(containment 的概念。它为部分隔离 DOM 子节点和页面其余部分提供了一种有效途径。

在容器查询的上下文或语境中,这就意味着不能使用容器查询来改变被查容器的尺寸大小,并且该尺寸的设置也只能通过不依赖于其子元素的方式来予以明确。

该限制的具体表现取决于容器类型的具体取值。属性 container-type 的合法值有三个:normalinline-size 以及 size;其初始值为 normal,表示该元素并非查询容器,因此也无法对其进行容器查询。

10.2.1.1 inline-size 容器类型 The inline-size container type

令容器类型的值为 inline-size,正如在之前的示例中演示的那样,可以仅凭行内尺寸(即元素宽度)来实现容器查询。设为 inline-size 的容器也无法使用基于高度的容器查询。在大多数实际应用中,inline-size 往往就是开发者需要的容器类型。容器的高度仍然会根据其内容的高度正常确定,您也可以根据可用空间的宽度调整样式,但容器中的任何内容都无法改变容器的行内尺寸。而这也正是 inline-size 起到的作用。

在常规文档流(normal document flow)中,块级元素的宽度将自动填满所有可用的空间。这就为容器查询提供了一个已知的宽度。在某些情况下,或许需要添加额外的样式声明来明确指定宽度,例如当容器为一个弹性元素时这一点尤为重要:务必确保弹性元素设置了 flex-basisflex-grow 属性的值,否则容器宽度将为零,导致后续容器查询无法进行。

10.2.1.2 size 容器类型 The size container type

container-type 的值为 size,则容器将在行内方向(inline direction)与块级方向(block direction)上实现全尺寸局限(full-size containment)。换句话说,浏览器将无法通过子元素来确定其容器的高度;相反,子元素会根据容器的高度进行查询。

容器类型指定为 size 后,容器的高度就需要以某种方式显式地定义,例如直接设置 heightmin-height 属性;或者通过容器外部的样式声明来定义其高度大小,比如网格布局或 Flexbox 布局;再或者,如果容器用到了绝对定位或固定定位,也可以利用 inset 属性来指定容器高度。而当上述方法都无法确定容器高度时,容器高度将为零,基于该高度的容器查询也将无法正常工作。

一般来说,在大多数情况下,容器类型都应该设为 inline-size。而当容器为网格布局或 Flexbox 的一部分、并且高度可以明确确定时,如果想针对高度做容器查询,则可以将容器类型设为 size。但大多数响应式设计都是基于行内尺寸实现的,因此通常也不需要这样设置。

10.2.2 容器的名称 Container names

指定容器名称后,就可以针对具体的容器实现容器查询。为此 CSS 提供了很大的自由度,既可以为某容器指定一个唯一的名称,同时也可以为多个容器复用相同的名称。

其中一个好的做法是使用一个通用名称,例如指定为 layout,并将其应用到页面上的大多数(或者所有)容器。在大多数情况下,它们多半就是您要查询的目标容器,因为您大概率希望模块能根据现有宽度做出响应。容器查询将沿 DOM 树向上查找,并选中指定名称的最近的祖先级容器(如图 10.4 所示)。

图 10.4 容器查询将选中所有匹配名称中距离最近的容器

【图 10.4 容器查询将选中所有匹配名称中距离最近的容器】

遇到需要不同容器的特殊情况时,也可以指定不同的名称,甚至可以对同一容器指定多个容器名称。例如 container: layout sidebar / inline-size 就将名称 layoutsidebar 同时指定给该容器,这样一来,带有这两个名称中任意一个的 @container 查询都将与该容器成功匹配。

容器查询还会绕过所有名称匹配失败的容器,如图 10.5 所示。通常情况下,我们要匹配的都是距离最近的容器;当需要对某个特定容器做出响应时,就可以使用此类技术。

图 10.5 容器查询忽略了名称匹配失败的容器

【图 10.5 容器查询忽略了名称匹配失败的容器】

为容器添加名称不是必需操作,您也可以利用 container-type: inline-size 来建立一个不带名称的容器,并在容器查询时省略名称(如 @container (min-width: 450px));此时浏览器将查找 DOM 树,直至找到第一个容器。

虽然可以在容器查询中省略容器名称(例如写作 @container (width > 400px) 完全有效),但我还是强烈建议您养成为所有容器命名的习惯。对于不带名称的容器查询,浏览器会从当前元素开始,向上遍历 DOM 树中第一个匹配到的容器,无论该容器是否命名。

10.2.3 容器与模块化 CSS(Containers and modular CSS)

在为网站构建模块化 CSS 的过程中,开发人员应当采取某种策略来确保容器能以可预测的方式进行定义,以便后续对模块进行有效的查询。每当一个模块存在某个包裹元素、并且可能包含其他模块时,我更倾向于将该包裹元素视为容器。

例如在媒体模块中,media__body 用于装填内容,同时也可能包含其他模块。因此在这种情况下,我通常会将 media__body 定义为一个容器,这样就能对放置其中的任何内容作出适当响应。

根据如下代码清单 10.4 所示的示例代码,同步更新您的本地示例页面。该代码片段对容器进行了定义,同时还对媒体模块的正文部分(media body)设置了一个 flex-grow 属性值,以确保其具有确定的宽度。

代码清单 10.4 将媒体模块中的正文部分设置为容器

@layer modules {
  .media {
    padding: 1.5rem;
    background-color: #eee;
    border-radius: 5px;
  }

  .media__image {
    margin-inline: auto;
  }

  .media__body {
    container: layout / inline-size;
    flex-grow: 1;
  }
}

这样,该模块就可以放置后期可能需要嵌入其中的其他模块了,甚至可以在一个模块内嵌套多个媒体模块,它们会根据情况分别做出响应——尽管没有什么实用价值,但看到这些模块的实际效果也挺有意思的。采用这种方法时,还需要确保任何布局样式也能定义容器,就像对 .l-page 设置布局时那样(详见 10.1 小节代码清单 10.3)。

这种方法的另一个替代方案,是通过各自带有的容器来定义模块。例如,用 <div class="media-container"> 来包裹媒体模块,并指定 container-type: inline-size 来设计样式。但我不太喜欢给众多模块添加额外的 HTML 标记,因此这种方法用得也不多。

在使用模块时,容器查询的表现向来优于媒体查询。只要能在整个页面中始终如一地定义好容器,往往就能将它们用于所有模块。



第 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 版高分译文专栏,全网首发,精译精校,持续更新,计划今年内完成全书翻译,敬请期待!!!

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

精彩评论(0)

0 0 举报