当我们开始考虑将防御性CSS作为一种策略时,它将帮助我们揭示隐藏的秘密,让我们设计和构建布局时尽可能少的问题。
参考:https://defensivecss.dev/

弹性框包装

CSS flexbox是当今最有用的CSS布局功能之一。添加到包装器中并使子项彼此相邻排序是很诱人的。display: flex
问题是当没有足够的空间时,默认情况下,这些子项不会换行。我们需要使用 来更改该行为。flex-wrap: wrap
下面是一个典型的例子。我们有一组选项应该彼此相邻显示。

1
2
3
.options-list {
display: flex;
}

当空间较少时,将发生水平滚动。这是应该预料之中的,实际上并不是一个“问题”。
请注意,这些项目仍然彼此相邻。要解决这个问题,我们需要允许弹性包装。

1
2
3
4
.options-list {
display: flex;
flex-wrap: wrap;
}

图像失真

当我们无法控制网页上图像的纵横比时,最好提前考虑并在用户上传与纵横比不一致的图像时提供解决方案。
在下面的示例中,我们有一个带有照片的卡片组件。它看起来不错。
当用户上传不同大小的图像时,它将被拉伸。这不好。看看图像是如何拉伸的!
最简单的解决方法是使用 CSS .object-fit

1
2
3
.card__thumb {
object-fit: cover;
}
1
2
3
img {
object-fit: cover;
}

长内容

这是一个人名列表,现在看起来很完美。
但是,由于这是用户生成的内容,因此我们需要小心如何在时间过长的情况下保护布局。
在这样的布局中,一致性很重要。为了实现这一点,我们可以简单地通过使用文本溢出及其好友来截断名称。

1
2
3
4
5
.username {
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}

在某些情况下,我们可能需要截断对用户不重要或不影响用户体验的文本。在这种情况下,截断文本是个好主意。

组件间距

我们开发人员需要考虑不同的内容长度。这意味着,应该将间距添加到组件中,即使它看起来不需要。
在此示例中,我们在右侧有一个部分标题和一个操作按钮。目前,它看起来还可以。但是,让我们看看当标题较长时会发生什么。
注意到文本离操作按钮太近了吗?您可能正在考虑多行换行,但我将在另一节中讨论。现在,让我们专注于间距。
如果标题有间距和文本截断,我们不会看到这样的问题。

1
2
3
.section__title {
margin-right: 1rem;
}

这类似于长内容提示,但在这种情况下,我们不想截断文本,因为用户必须阅读所有文本。这里的一件小事是考虑间距,即使我们目前的内容不长。
请考虑以下演示。我们有一个简短的标题,一切都像魅力一样。
但是,当内容太长时,标题应具有“更多”按钮的边距。提前考虑这一点对于避免文本与按钮发生冲突非常重要。
粉红色轮廓表示文本元素。当您单击“切换防御”复选框时,将添加一个间距。

自动调整与自动填充

使用 CSS 网格函数时,请务必决定是否使用 or 关键字。如果使用不当,可能会导致意外结果。minmax() auto-fit auto-fill
使用函数时,关键字将展开网格项以填充可用空间。while 将保留可用空间,而不会更改网格项的宽度。minmax() auto-fit auto-fill
话虽如此,使用可能会导致网格项太宽,尤其是当它们小于预期时。请考虑以下示例。auto-fit

1
2
3
4
5
.wrapper {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));
grid-gap: 1rem;
}

如果只有一个网格项并且正在使用,则该项将展开以填充容器宽度。auto-fit
大多数时候,不需要这种行为,所以在我看来使用更好。auto-fill

1
2
3
4
5
.wrapper {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(250px, 1fr));
grid-gap: 1rem;
}

示例

1
2
3
4
5
6
7
.wrapper {
--sizing: auto-fit;
display: grid;
grid-template-columns:
repeat(var(--sizing), minmax(100px, 1fr));
grid-gap: 1rem;
}

背景重复

通常,当使用大图像作为背景时,我们往往会忘记在大屏幕上查看设计时考虑这种情况。默认情况下,该背景将重复。
这在笔记本电脑屏幕上大多不可见,但在较大的屏幕上可以清楚地看到。
要提前避免该行为,请确保重置 。background-repeat

1
2
3
4
.hero {
background-image: url('..');
background-repeat: no-repeat;
}