[译] CSS min-content、max-content 和 fit-content 属性值介绍

原文连接:Intrinsic Sizing In CSS,by Ahmad Shadeedcss

CSS 中存在两种尺寸:内在尺寸(intrinsic)和外在尺寸(extrinsic)。为元素的 widthheight 设置的固定属性值,就是指外部尺寸,这是最经常使用的方式。而内部尺寸,则是由元素包含的内容量决定的。html

本篇将会详细介绍控制内在尺寸的每一个值,看看它们的使用能带来什么好处。同时,我还会举例说明这些值与 CSS Grid 布局/其余属性如何结合使用。sql

外在尺寸

外在尺寸是指用精确的值指定元素尺寸。举个例子:浏览器

.c-button {
    width: 100px;
}
复制代码

这个按钮的尺寸是 100px,这就是外在尺寸了。再好比一个 <div> 元素,它默认是个块级元素,就是说它的宽默认等于 100% 父元素的宽。app

有时,咱们想要根据元素实际的内容来设置尺寸,这个时候,使用外在尺寸就没有用了。接下来,咱们来看看如何是用内在属性值来解决问题的吧!ide

min-content

min-content 值表示内在最小宽度(译注:这里说的不许确,也能够是“最小高度”,所以应该称为“最小尺寸”),它等于元素内容里最长的那个单词宽度。函数

CSS Working Group (CSSWG) 的说法是:布局

The inline size that would fit around its contents if all soft wrap opportunities within the box were taken.post

坦率地讲,我太理解 CSSWG 关于这个概念的定义。我本身是这么理解的:我在元素的周围包裹了一个框,元素内容(不少单词)会所以而折行,这个框的宽度将等于元素中最长的那个单词。若是我这里表述有误的话,但愿你们来更正。ui

举一个例子,有一个标题元素:

<h2>A title for an awesome article</h2>
复制代码
h2 {
  width: min-content;
}
复制代码

intrinsic-sizing-1.png

你们能够看见,当元素的 width 设置成 min-content 后,其宽度等于最长单词的宽度,也就是这里的“awesome”。

image.png

A pen by Ahmad Shadeed

max-content

max-content 表示元素的内在首选宽度(intrinsic preferred width),它等于元素内容的宽。

还举一个标题元素的例子,不过此次改用 max-content 了:

h2 {
  width: max-content;
}
复制代码


intrinsic-sizing-2.png

注意观察,元素宽度等于标题宽度了。这个宽度是动态的,随着标题内容的改变,max-content 所表明的值也相应改变。

fit-cotent

这个属性能够当作是 min-contentmax-content 的结合。搜索的时候,我发现 Stackoverflow 上的这个回答我很喜欢:

fit-content 默许使用 max-content;若是 available < max-content,那就使用 available;若是 available < min-content,那就使用 min-content

画一个流程图表示,就是下面这样的:

intrinsic-sizing-3.png

注意,这里的“available”表示元素在视口中的可用空间。

🤔 译注
上面的流程图跟 Stackoverflow  上的回答比起来,并不十分清晰,反而是后者更容易理解起来。关于 Stackoverflow  上的回答个人理解以下:

fit-content 属性到底取用何值,跟当前元素的可用空间(available)是紧密相关的。

1. 若是可用空间充足,那就用你元素的 max-conetnt 又何妨,反正够装你的。
2. 若是可用空间不够充裕,比 max-conetnt 小点,那就得用可用空间的值了,这才显得合适(fit),不会致使内容越界。
3. 若是可用空间不多,甚至比 min-conetnt 还小,那很差意思,得用 min-content 了,否则显示会很难看,就不合适了。

让咱们举个例子看看它是如何工做的。

h2 {
    width: fit-content;
}
复制代码

查看下面的 GIF 图,观察标题尺寸是如何随着视口的变化作调整的。

fit-content.gif

咱们再回顾一下关于 fit-content 的知识:若是当前的可用空间比 max-content 还大的话,width 就等于 max-content;若是可用空间比 max-content 的小的话,那么 width 就等于可用空间的宽了;最后,若是可用空间比 min-content 还小,那么 width 就等于 min-content

到目前为止,我解释完了每个内在值。让咱们转向真实的案例来看下吧。

使用案例

<figure><caption>

如今咱们假设有一个带 <caption><figure>,由于它是个块级元素,所以默认等于 100% 父元素宽度的。

<figure>
    <img src="blueberry-cheesecake-x.png" alt="">
    <figcaption>..</figcaption>
</figure>
复制代码

intrinsic-figure-0.png

咱们预期的行为是但愿 <figure> 包裹图像的,使用 max-content 就能取得这些效果,让 <figure> 与内容(最大)宽度同样。

figure {
    width: max-content;
    margin-left: auto;
    margin-right: auto;
}
复制代码

intrinsic-figure.png

但有一个问题,若是图片比视口范围还大的话,这时由于 <figure> 的宽度就等于图片的宽度,所以就会致使水平滚动条的出现。

intrinsic-figure-2.png

为了解决这个问题,咱们就要为图片使用 fit-content 了。它不会让大图片超出视口以外显示。

figure {
    width: fit-content;
}
复制代码

image.png

A pen by Ahmad Shadeed

带分隔符的标题

在这个例子里,“Top Stories”要折成两行显示。宽度仍是动态的,就是说无论实际标题如何,都须要折行。为了实现这个效果,咱们可使用 min-content

span {
    width: min-content;
}
复制代码

image.png

A pen by Ahmad Shadeed

带下划线的标题

内在值的另外一个有趣的用例是带边框的标题,要求边框跟标题内容同样长。考虑下图:

intrinsic-title.png

注意,标题是个块状元素。为了获得上述的效果,之前的作法是将内容包装在 <span> 标签里,给 <span> 设置边框效果。

<h2><span>A title for an awesome article</span></h2>
复制代码
<h2><span>A title for an awesome article</span></h2>
复制代码

固然,咱们还能够借助 fit-content 来让标题宽度与内容同样长。

h2 {
    width: fit-content;
    margin-left: auto; /* For centering */
    margin-left: auto; /* For centering */
    border-bottom: 2px solid #e2deed;
}
复制代码

image.png

A pen by Ahmad Shadeed

导航


若是一个页面导航的宽度是基于内容的。那么,能够经过使用 max-content,轻松实现效果:

.c-nav {
    width: max-content;
}
复制代码

Demo

Todo 列表

在网上找内在值的使用案例的时候,看到了 一篇文章,将我吸引了。

考虑下面的例子:

这个 Todo 列表包含:页眉、列表和页脚。

无论有多少列表项,中间部分的高度都应该是 100% - header - footer。为了实现这个效果,咱们能够将 CSS Grid 与 min-content 搭配使用。

.c-todo {
  display: grid;
  grid-template-rows: min-content auto min-content;
  height: 100vh;
}
复制代码


你可能想知道,若是咱们不使用 min-content,会是什么结果呢?好吧,来看看:

聊天窗口

设想构建一个聊天程序。在下面的示例里,布局结构与 Todo 列表很是类似。当没有\聊天记录,而且没有使用 min-content 时,就会致使布局遭到破坏。

Demo

Hero

假设咱们页面 <header> 里包含一个 Hero 组件。咱们的目标是让这个 Hero 组件实现动态布局,占据一屏里剩下的空间。

.c-section {
    display: grid;
    grid-template-rows: min-content 1fr;
}
复制代码

有两行内容,第一行使用的是最小内容高度,而第二行则能够扩展、填充完剩下的可用空间。

image.png

A pen by Ahmad Shadeed

Sidebar 和 Main

我老是想知道为何咱们非要给侧边栏一个固定宽度呢。若是它的宽度是基于内容的呢?好比说,它有一个基于内容的最小宽度和一个最大宽度?咱们来试试。

<div class="wrapper">
  <aside></aside>
  <main></main>
</div>
复制代码
.wrapper {
    grid-template-columns: fit-content(150px) 1fr;
    grid-gap: 1rem;
}
复制代码

经过使用 CSS Grid fit-content 函数,咱们能够确保侧边栏的宽度不会超过 150px,而且能够在内容很短的状况下缩小到 150px 如下。

当侧边栏的内容不多时,它会缩小一点:

🤔译注
这的 fit-content() 文中并无讲到。能够简单把它理解为一个公式:min(max-content, max(min-content, argument)),即

先将咱们带入的参数 argument(即这里的 150px)与 min-content 比较 取大 的那一个,而后将获得的数与 max-content 比较 取小 的那一个,最终的比较结果就是 fit-content() 的返回值。

也就是说,根据 argument 的不一样,fit-content() 会有三个可能的返回值:

1. 当 argument 比 max-content 大时,fit-content() 返回的是 max-content
2. 当 argument 比 max-content 小一点时,fit-content() 返回的是 argument
3. 当 argument 比 min-content 还小时,fit-content() 返回的是 min-content

更多信息,查看 MDN 上的 fit-content() 文档

再来看文中表述:

1. 侧边栏的宽度不会超过 150px:这是说 argument 的值比 max-content 小,有两种结果——argument(即 150px。对应状况 2) 和 min-content(对应状况 3)。
2. 内容很短的状况下缩小到 150px 如下:这是说 argument 的值比 max-content 大的状况,这时候返回的是 max-content(对应状况 1)。

标题和描述

咱们有一个标题和一个描述文本。描述文字的宽度不能超过主标题的宽度。对我来讲,这是一个有趣的用例,我之前认为它不可能仅用 CSS 就能实现。

看下下面的模型。

为了实现上述功能,咱们须要将 min-content 设置为包装元素的宽度,而为标题元素设置 width: max-content

section {
  width: min-content;
  margin: 0 auto;
  text-align: center;
}

h2 {
  width: max-content;
}
复制代码

请注意,上面代码须要在移动端作些调整额,不然可能会致使致使水平滚动条的出现。

image.png

A pen by Ahmad Shadeed

浏览器兼容性

根据 Can I Use 数据,除了 Microsoft Edge (EdgeHTML) 以外的全部主流浏览器都支持内在值的设置了。

注意:Microsoft Edge (Chromium)  从发布的第一个版本(79)就已经支持了。

image.png

(正文完)


广告时间(长期有效)

我有一位好朋友开了一间猫舍,在此帮她宣传一下。如今猫舍里养的都是布偶猫。若是你也是个爱猫人士而且有须要的话,不妨扫一扫她的【闲鱼】二维码。不买也没关系,看看也行。

(完)

相关文章
相关标签/搜索