防御式CSS是什么?这几点属性重点防御!

目录
文章目录隐藏
  1. 1. Flexbox 包裹
  2. 2. 间距
  3. 3. 长内容
  4. 4. 防止图像被拉伸或压缩
  5. 5. 锁定滚动链接
  6. 6. CSS 变量回退
  7. 7. 使用固定宽度或高度
  8. 8. 忘记 background-Repeat
  9. 9. 垂直媒体查询
  10. 10. 使用 justify-content:space-between
  11. 11. 图片上的文字
  12. 12. 小心 CSS 网格中的固定值
  13. 13. 只在需要的时候显示滚动条
  14. 14. Scrollbar Gutter
  15. 15. CSS Flexbox 中的最小内容尺寸
  16. 16. CSS 网格中的最小内容尺寸
  17. 17. Auto Fit Vs Auto Fill
  18. 18. 图像最大宽度
  19. 19. 位置:粘性 CSS 网格
  20. 20. 分组选择器
  21. 总结

很多时候,我们希望有一种方法可以避免某种 CSS 问题或行为的发生。我们知道,网页内容是动态的,网页上的东西可以改变,从而增加了出现 CSS 问题或奇怪行为的可能性。

防御式 CSS 是一个片段的集合,可以帮助我编写受保护的 CSS。换句话说,就是将来会有更 bug 出现。

1. Flexbox 包裹

CSS flexbox 是目前最有用的 CSS 布局功能之一。在一个包装器上添加 display: flex,让子项挨着排序。

问题是,当空间不足时,那些子项默认不会被包裹成一个新的行。我们需要用 flex-wrap: wrap 来改变这一行为。

下面是一个典型的例子。

.options-list {
    display: flex;
}

Flexbox 包裹

当空间较少时,会出现水平滚动。

当空间较少时,会出现水平滚动

.options-list {
    display: flex;
    flex-wrap: wrap;
}

Flexbox 包裹

使用flexbox时,一般的经验法则是允许包裹,除非你想要一个滚动的包裹。这是另一回事,但尽量使用 flex-wrap 来避免意外的布局行为(在我们的例子中,是水平滚动)。

2. 间距

我们开发者需要考虑不同的内容长度。这意味着,间距应该添加到组件中,即使它看起来不需要。

间距

在这个例子中,我们在右边有一个section标题和一个操作按钮。目前,它看起来还不错。但是,如果标题再长一些,会发生什么呢?

如果标题再长一些,会发生什么呢?

注意到文本太靠近按钮了吗?这里,你可能会考虑多行换行,但现在,我们先关注距。

如果标题有空格和文本截断,我们不会看到这样的问题。

.section__title {
    margin-right: 1rem;
}

标题有空格和文本截断

3. 长内容

在构建布局时,考虑到长的内容是很重要的。正如你在前面所看到的,当章节的标题太长时就会被截断。这是可选的,但对于某些 UI 来说,考虑到这一点很重要。

对我来说,这是一种防御性的 CSS 方法。在 “问题 “真正发生之前就去解决它,这很好。

这里有一份人名清单,现在看起来很完美。

长内容

然而,由于这是用户生成的内容,我们需要小心如何防御布局,以防某些内容太长。请看下图:

如何防御布局,以防某些内容太长

在这种布局中,一致性非常重要。为了实现这一点,我们可以使用 text-overflow和它的好友来简单地截断名称。

使用 text-overflow 和它的好友来简单地截断名称

4. 防止图像被拉伸或压缩

在无法控制图片高宽比的情况下,如果用户上传的图片与高宽比不符,最好提前考虑并提供解决方案。

在下面的例子中,我们有一个带有照片的卡片组件。它看起来不错。

带有照片的卡片组件

当用户上传一个不同大小的图像时,它将被拉伸。这可不是什么好事。看看图像是如何被拉伸的!

图像是如何被拉伸的

最简单的修复方法是使用 CSS object-fit

.card__thumb {
    object-fit: cover;
}

使用 CSS object-fit

在项目层面上,我倾向于为所有图像添加 object-fit,以避免出现意外的结果。

5. 锁定滚动链接

你是否曾经打开一个模态并开始滚动,然后当你到达终点并继续滚动时,模态下面的内容(主体元素)会滚动?这就是所谓的滚动链。

默认情况下,当触及页面顶部或者底部时(或者是其他可滚动区域),移动端浏览器倾向于提供一种“触底”效果,甚至进行页面刷新。你可能也发现了,当对话框中含有可滚动内容时,一旦滚动至对话框的边界,对话框下方的页面内容也开始滚动了——这被称为“滚动链”。 。

在过去的几年里,有一些黑科技来实现这一点,但现在,我们只需要使用 CSS 即可,这要感谢overscroll-behavior CSS 属性。

在下面的图中,可以看到默认的滚动链接行为。

默认的滚动链接行为

为了提前避免这种情况,我们可以将其添加到任何需要滚动的组件中(例如:聊天组件、移动菜单…等)。这个属性的好处是,在有滚动之前,它不会产生影响。

.modal__content {
    overscroll-behavior-y: contain;
    overflow-y: auto;
}

6. CSS 变量回退

CSS 变量在网页设计中得到了越来越多的应用。我们可以应用一种方法,在 CSS 变量值因某种原因为空的情况下,以一种不破坏体验的方式使用它们。

通过 JS 输入 CSS 变量的值时特别有用。下面是一个例子:

.message__bubble {
    max-width: calc(100% - var(--actions-width));
}

变量 --actions-width 在 calc() 函数中被使用,其值来自 JS。假设 JS 由于某种原因失败了,会发生什么?max-width 会被计算为零。

我们可以提前避免这种情况,在 var() 中添加一个回退值。

.message__bubble {
    max-width: calc(100% - var(--actions-width, 70px));
}

这样,如果变量没有定义,就会使用回退 (70px)。这种方法可以在变量可能失败的情况下使用。

7. 使用固定宽度或高度

破坏布局的常见情况之一是对一个有不同长度内容的元素使用固定的宽度或高度。

固定高度

我经常看到主内容部分有固定的高度,而内容却大于这个高度,这就导致了布局的破坏。如下所示:

.main {
    height: 350px;
}

使用固定宽度或高度

为了避免这种情况出现,可以使用 min-height 代替 height:

使用 min-height 代替 height

固定宽度

你有没有见过按钮,它的标题内容离左右边缘太近?这是由于使用了固定宽度。

.button {
    width: 100px;
}

如果按钮的标题内容大于100px,它将靠近边缘。如果它太长,文本会泄露出来。这是不好的!

固定宽度

为了解决这个问题,我们可以简单地用 min-width 代替 width

.button {
    min-width: 100px;
}

8. 忘记 background-Repeat

很多时候,当使用一张大的图片作为背景时,我们往往会忘记考虑设计在大屏幕上观看时的情况。该背景将默认重复。

background-Repeat

这在笔记本屏幕上大多不会看到,但在大屏幕上很常见。

为了提前避免这种行为,请确保使用重置 background-repeat

.hero {
    background-image: url('..');
    background-repeat: no-repeat;
}

9. 垂直媒体查询

有时,我们很想建立一个组件,只通过调整浏览器的宽度进行测试。根据浏览器的高度进行测试可以发现一些有趣的问题。

这里有一个我见过多次的例子。我们有一个带有主要和次要链接组件。次要链接应该位于旁白部分的最底部。

考虑一下下面的例子。主导航和次导航看起来还不错。在我看到的这个例子中,开发者给二级导航添加了 position: sticky,这样它就可以粘在底部了。

垂直媒体查询

然而,如果浏览器的高度较小,bug 就来了。注意这两个导航是如何重叠的。

注意这两个导航是如何重叠的

通过使用 CSS 垂直媒体查询,我们可以避免这个问题。

@media (min-height: 600px) {
    .aside__secondary {
        position: sticky;
        bottom: 0;
    }
}

这样,只有当视口高度大于或等于600px 时,二级导航才会被粘在底部。好多了,对吗?

可能有更好的方法来实现这一行为(比如使用 margin-auto),但在这个例子中专注于垂直查询。

10. 使用 justify-content:space-between

在一个 flex 的容器中,我们可能会使用 justify-content 来使子项目之间有一定的间距。如果有一定数量的子项目,布局看起来会很好。然而,当它们增加或减少时,布局会看起来很奇怪。

考虑以下例子:

使用 justify-content:space-between

我们有一个有四个项目的 flex 容器。每个项目之间的间距不是 gap 或 margin,它之所以存在是因为容器有 justify-content: space-between

.wrapper {
    display: flex;
    flex-wrap: wrap;
    justify-content: space-between;
}

当项目的数量少于 4 个时,将发生以下情况:

当项目的数量少于 4 个时,将发生以下情况

这并不是好事。对此有不同的解决方案:

  • margin
  • flexbox gap(谨慎使用)
  • padding(可应用于每个子元素的父元素)
  • 增加空的元素,作为间隔。

为了简单起见,我使用 gap

.wrapper {
    display: flex;
    flex-wrap: wrap;
    gap: 1rem;
}

使用 gap

11. 图片上的文字

当在图片上放置文本时,必须考虑到图像无法加载的情况。文本会是什么样子。下面是一个例子:

图片上的文字

文本看起来是可读的,但当图像加载失败时,它的可读性变得很差。

当图像加载失败时,它的可读性变得很差

我们通过给<img>元素添加一个背景色来轻松解决这个问题。这个背景只有在图片加载失败时才会显示出来。

给<img>元素添加一个背景色来轻松解决

12. 小心 CSS 网格中的固定值

假设我们有一个包含asidemain的网格。CSS 看起来是这样的:

.wrapper {
    display: grid;
    grid-template-columns: 250px 1fr;
    gap: 1rem;
}

由于缺乏空间,这在小的视口尺寸上会出现问题。为了避免这样的问题,在使用上述 CSS 网格时,一定要使用媒体查询。

@media (min-width: 600px) {
    .wrapper {
        display: grid;
        grid-template-columns: 250px 1fr;
        gap: 1rem;
    }
}

13. 只在需要的时候显示滚动条

我们可以控制显示滚动条或不只是在有很长的内容的情况下。尽管如此,强烈建议使用auto作为overflow的值。考虑以下例子:

只在需要的时候显示滚动条

请注意,即使内容很短,也有一个滚动条可见。这对一个用户界面来说并不是好事。作为用户,在不需要滚动条的情况下看到滚动条是很混乱的。

.element {
    overflow-y: auto;
}

使用overflow-y: auto,滚动条只有在内容较长时才可见。否则,它就不显示。

使用 overflow-y: auto,滚动条只有在内容较长时才可见

14. Scrollbar Gutter

另一件与滚动有关的事情是 Scrollbar Gutter。以前面的例子为例,当内容变长时,增加一个滚动条会导致布局的转移。布局移动发生的原因是为滚动条保留了一个空间。

Scrollbar Gutter 是内边框边缘和外填充边缘之间的空间。 对于经典滚动条,Scrollbar Gutter 的大小与滚动条的宽度相同。 这些滚动条通常是不透明的,并从相邻的内容中占用一些空间。

请看下图:

Scrollbar Gutter

请注意,由于显示了滚动条,当内容变长时,它是如何移位的。我们可以通过使用scrollbar-gutter属性来避免这种行为。

.element {
    scrollbar-gutter: stable;
}

使用 scrollbar-gutter 属性

15. CSS Flexbox 中的最小内容尺寸

如果一个 flex 项目中的文本元素或图像大于或长于该项目本身,浏览器就不会缩小它们。这是 Flexbox 的默认行为。考虑以下例子:

.card {
    display: flex;
}

当标题有一个很长的词时,它不会被包成一个新行。

CSS Flexbox 中的最小内容尺寸

即使我们使用 overflow-wrap: break-word,也不会起作用。

.card__title {
    overflow-wrap: break-word;
}

要改变这种默认行为,我们需要将 flex 项目的 min-width 设置为 0。 这是因为 min-width 的默认值是 auto,溢出会发生。

.card__title {
    overflow-wrap: break-word;
    min-width: 0;
}

同样也适用于 flex-direction:column 布局,对应的使用 min-height: 0

适用于 flex-direction:column 布局

16. CSS 网格中的最小内容尺寸

与 flexbox 类似,CSS grid 对其子项目有一个默认的最小内容尺寸,即auto。这意味着,如果有一个元素比网格项大,它将溢出。

CSS 网格中的最小内容尺寸

在上面的例子中,我们在主部分中有一个 carousel

<div class="wrapper">
    <main>
        <section class="carousel"></section>
    </main>
    <aside></aside>
</div>

CSS 代码:

@media (min-width: 1020px) {
    .wrapper {
        display: grid;
        grid-template-columns: 1fr 248px;
        grid-gap: 40px;
    }
}

.carousel {
    display: flex;
    overflow-x: auto;
}

由于 carousel是一个 flex 布局,当内容超出时,默认是不会换行的,所以会出现水平滚动的。

为了解决这个问题,我们有三种不同的解决方:

  • 使用 minmax()
  • 将 min-width 应用于网格项目
  • 在网络中添加 overflow: hidden

作为一种防御性的 CSS 机制,我会选择第一种,即使用 minmax() 函数。

@media (min-width: 1020px) {
    .wrapper {
        display: grid;
        grid-template-columns: minmax(0, 1fr) 248px;
        grid-gap: 40px;
    }
}

使用 minmax() 函数

17. Auto Fit Vs Auto Fill

在使用 CSS 网格 minmax() 函数时,决定使用 auto-fit 还是 auto-fill 的关键字很重要。一旦使用不当,会导致意外的结果。

当使用minmax()函数时,auto-fit关键字将扩展网格项目以填补可用空间。而auto-fill将保留可用的空间,而不改变网格项的宽度。

Auto Fit Vs Auto Fill

也就是说,使用auto-fit可能会导致网格项目太宽,特别是当它们小于预期时。考虑以下示例。

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

如果只有一个网格项并被auto-fit使用,则该项将扩展以填充容器宽度。

只有一个网格项并被 auto-fit 使用

大多数时候,不需要这种行为,所以auto-fill我认为使用更好。

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

auto-fill

18. 图像最大宽度

作为一般规则,不要忘记设置max-width: 100%所有图像。这可以添加到您使用的 CSS 重置中。

img {
    max-width: 100%;
    object-fit: cover;
}

19. 位置:粘性 CSS 网格

您是否尝试过position: sticky与网格容器的子项一起使用?网格项的默认行为是拉伸。因此,下面示例中的 side 元素等于主要部分的高度。

位置:粘性 CSS 网格

要使其按预期工作,您需要重置align-self属性。

aside {
    align-self: start;
    position: sticky;
    top: 1rem;
}

重置 align-self 属性

20. 分组选择器

不建议对用于不同浏览器的选择器进行分组。例如,为每个浏览器设置输入占位符的样式需要多个选择器。根据 w3c,如果我们对选择器进行分组,则整个规则将无效。

/* 请不要这样做 */
input::-webkit-input-placeholder,
input:-moz-placeholder {
    color: #222;
}

相反,请执行此操作。

input::-webkit-input-placeholder {
    color: #222;
}

input:-moz-placeholder {
    color: #222;
}

总结

这是我个人根据我正在从事的项目使用的防御性 CSS 技术的持续列表总结,希望对大家有用。

译文:原文链接

「点点赞赏,手留余香」

0

给作者打赏,鼓励TA抓紧创作!

微信微信 支付宝支付宝

还没有人赞赏,快来当第一个赞赏的人吧!

声明:本站所有文章,如无特殊说明或标注,均为本站原创发布。任何个人或组织,在未征得本站同意时,禁止复制、盗用、采集、发布本站内容到任何网站、书籍等各类媒体平台。如若本站内容侵犯了原著者的合法权益,可联系我们进行处理。
码云笔记 » 防御式CSS是什么?这几点属性重点防御!

发表回复