很难在一篇简短的博客文章中概括 Flexbox 的所有优点。 虽然我们 在这里尝试过。 这里,让我们只关注 Flexbox 很好的解决的一个问题:能够让一组任意盒子填充父盒子的所有可用高度。 而且不仅如此,如果需要,还可以扩展超出该高度(不会压缩以适应)。
“盒子”指的是块级元素,例如 div、section、article 等。
默认情况下,这些盒子的高度由它们内部的内容决定。 它们将一个接一个地堆叠起来。 它们的父盒子的高度也可能由它们的组合高度决定,但也可能不同(例如,它被明确设置或它是一个可变值,如浏览器窗口)。 如果父盒子有更大的高度,在下方就会出现空的空间。
我们不能强迫这些盒子均匀地分割那个空间吗? 通过 Flexbox,我们可以做到。
假设 HTML 代码如下
<section class="fill-height-or-more">
<div>
<!-- stuff -->
</div>
<div>
<!-- stuff -->
</div>
<div>
<!-- stuff -->
</div>
</section>
然后我们使用父盒子启动 Flexbox
.fill-height-or-more {
display: flex;
}
并使盒子上下排列(列)而不是默认的左右排列(行)
.fill-height-or-more {
display: flex;
flex-direction: column;
}
仅凭这一点,它看起来与我们什么都不做时没有区别。 但是现在我们将 flex 属性应用于子元素,它们将填充空间
.fill-height-or-more > div {
/* these are the flex items */
flex: 1;
}
好了 =)。
这里需要详细说明的是,flex: 1;
等同于 flex: 1 1 auto;
它是三个不同属性的简写
flex-grow: 1;
flex-shrink: 1;
flex-basis: auto;
碰巧,让它们能够以相等的方式增长是最常见的需求,因此 flex: 1;
是一个很好的写法。
Flexbox 的优点之一是,它适用于任意数量的盒子。 可以是一个盒子! 可以是 100 个盒子! 无论多少。 如果有额外的空间,空间将被分割和填充。 如果没有,也没关系。
在没有 Flexbox 的时代,我们可能尝试去知道/找出有多少个盒子,然后用百分比设置它们的高度。 这可以填充额外的空间,但是如果盒子过多,就会被压缩。 这是 Flexbox 的另一个优点,它不会压缩这些盒子,以至于它们无法容纳其内容。 所以…
如果我们想更进一步,我们可以使用 Flexbox 将内容也居中到这些盒子中(!) 。 然而,这就是人们对 CSS 感到恼火的地方。 垂直居中很困难。 即使在这里使用 Flexbox,我们也需要将我们拥有的每个 Flex 项目子元素也变成 Flex 容器。 然后使用一个内部包装器,它成为我们居中的 Flex 项目。 所以,仍然需要一个额外的元素。 更新:Tedmotu 做到了,没有额外的元素,非常直接
要居中它,我们再次使方向为上下(列)并使用另一个 Flexbox 属性 justify-content
来居中它。
.fill-height-or-more > div {
flex: 1;
display: flex;
justify-content: center;
flex-direction: column;
}
这就是 参考指南 派上用场的地方…… 快速找出哪个属性有什么作用。
然后我们得到了这个
查看 CodePen 上 Chris Coyier 的 高度自适应的盒子(或更高) 演示 (@chriscoyier)。
浏览器支持
我只在本文中使用了最新的语法。 Chrome 和 Opera 的最新版本直接支持它。 Firefox 和 Android 的未来版本也将直接支持它。 Safari 和 iOS 支持新的语法,只是使用了 -webkit- 前缀。 Can I Use 提供了完整的故事。
IE 很奇怪。 IE 10 支持 Flexbox 的过渡版本(例如 display: -ms-flexbox;)。 IE 11 支持最新的 Flexbox。 但是,在这个特定的演示中,有些东西坏了。 虽然 .fill-height-or-more 的高度通过使用 min-height
渲染为全高度,但盒子被压缩了。

如果使用 height 而不是 flex 容器,它“可以工作”——但这里的重点是使用 min-height 来避免压缩。 对我来说,这似乎是一个实现错误。
更新: Nirav Zaveri 写信告诉我,在 IE(我测试了 v11)中,flex: 1
不等于 flex: 1 1 auto
,即使它应该相等(?)。 如果您设置后者,它可以工作。
您可以理解,您可能需要在浏览器支持方面退后一步。 Firefox 27、iOS 6 和 Safari 6 都是非常合法的浏览器支持目标,它们都使用一些变体的老语法,有时带前缀,有时不带前缀。
我们的示例在尽可能完整地支持所有浏览器的情况下看起来像这样
.fill-height-or-more {
display: -webkit-box;
display: -webkit-flex;
display: -moz-box;
display: -ms-flexbox;
display: flex;
-webkit-box-orient: vertical;
-webkit-box-direction: normal;
-webkit-flex-direction: column;
-moz-box-orient: vertical;
-moz-box-direction: normal;
-ms-flex-direction: column;
flex-direction: column;
}
.fill-height-or-more > div {
-webkit-box-flex: 1;
-webkit-flex: 1;
-moz-box-flex: 1;
-ms-flex: 1;
flex: 1;
display: -webkit-box;
display: -webkit-flex;
display: -moz-box;
display: -ms-flexbox;
display: flex;
-webkit-box-pack: center;
-webkit-justify-content: center;
-moz-box-pack: center;
-ms-flex-pack: center;
justify-content: center;
-webkit-box-orient: vertical;
-webkit-box-direction: normal;
-webkit-flex-direction: column;
-moz-box-orient: vertical;
-moz-box-direction: normal;
-ms-flex-direction: column;
flex-direction: column;
}
天啊。 我的建议? 像我上面那样用现代语法编写,让 Autoprefixer 处理它,它不仅处理前缀,而且还处理老语法。
视频演示
不妨试试? 我 在这里发布了它,我也会嵌入它
另外,为了记录,促使我进行这项工作的真实场景是 这个页面。
写得真好! 我很喜欢 Flexbox。 我甚至使用 Flexbox 构建了我的个人网站。
迫不及待地想在 2020 年将它用于生产网站。 :(
啊,一个乐观主义者。
我很想知道 Flexbox 是否能解决我一直试图解决的问题。 场景是,您有两列内容。 列 A 是博客的特色图片,列 B 是预览文本。 有时列 A 会为空,因此列 B 会填满整个空间。
如果列 A 使用可选的
img
,您可能想看看:empty
伪类.col-a:empty { display: none; }
MDN 文档
哇。 这是我读过的最及时的博客文章。 今天早上我一直在尝试解决这个问题。 感谢 Chris!
在其中一个项目中,我们没有使用多余的 flexes 来进行垂直居中,而是使用了以下方法。 它效果很好 :) http://zerosixthree.se/vertical-align-anything-with-just-3-lines-of-css/
我 也喜欢 translate 居中,但您需要一个单独的元素来执行该转换,所以有点像驴唇不对马嘴。
我已经加入了 Flex 的行列大约六到八个月了,现在迫不及待地想让它投入使用。 到目前为止,我们仍然在 Safari(align-self 直到去年年底才得到支持)、Firefox(flex-wrap 在公开版本中直到 4 月才得到支持)以及 IE8 和 IE9 上遇到问题。
真的,真的期待着能够在没有回退的情况下使用 Flex 的那一天。 我前几天在 Twitter 上看到一条推文说,一旦您使用 Flex,您将再也无法忍受其他任何布局页面方式,我完全同意!
太好了。
但您也知道让人扫兴的是:IE。
即使是 IE9 也无法帮助您。
一如既往,很棒,感谢您的提示,Chris。
Flexbox 非常棒,**如果我们能够使用它的话**。 在现实世界中,IE8 的使用率仍然太高,无法在一个面向世界的网站上依赖 Flexbox。 Net Applications(微软信任的 ie6countdown 组织)在 2013 年 12 月给出了 IE8 在全球范围内占 20% 以上的比例;StatCounter 的数据一直都比较低,但仍然说是 6.6%(而且奇怪的是,IE9 还有 3.9%;我认为这些人至少应该使用 IE10 了)。 例如,即使按照最低估计,也有 10% 以上的人没有使用 Flexbox,这部分流量实在太大了,无法忽视。
(由于微软不愿为 XP 发布现代浏览器,同时又继续为批量许可客户(即大型企业和政府)在 Windows 7 的整个生命周期内提供 XP 支持,因此 IE8 将继续存在很长时间。)
微软终于加入了“保持浏览器更新”的行列,这真是太好了。 现在如果我们能让他们像其他所有供应商一样做,支持他们的浏览器在 XP 上(因为他们无法改变批量协议……)
请记住,哪些统计数据才是重要的:您网站的统计数据。
如果我正在建立一个销售园艺设备的电子商务网站,我可能会让它一直支持到 IE 6。
当我下次在 CSS-Tricks 上进行设计更新时,我可能会使用 flexbox 并将 IE 10 设为最低版本。
(回复我自己,因为 Chris 的评论中没有“回复”链接)
当你创建新东西时,你会使用什么统计数据?平均统计数据很重要。
为什么要添加一个额外的 div 元素?
不需要。'justify-content: center' 应该足够了,如果你也想要跨轴对齐,你可以使用 'align-items: center'。
任何拥有这两个样式的盒子,其子元素都将完美地居中。它们不需要一个虚拟父元素。
我无法让它工作。你可以随意 fork 它,删除元素并使其居中。我很乐意更新文章,使其更简洁。
Fork(没有额外的 div)
我正在使用 Chrome 32,上面的笔看起来与你的笔相同。也许我遗漏了什么?
我通常更喜欢 flexbox 来专门针对此功能进行对齐 - 它允许我将兄弟元素对齐,而不需要虚拟包装器。
确实有效!天哪,我为什么这么难?无论如何,我更新了演示,并在文章中做了一个说明。
Flexbox,真棒!
Flexbox 确实很棒 :)
我当前的项目也正在使用 flexbox。它解决了许多 CSS 布局问题,并使我们能够进行“Web 应用程序”样式的布局。我不得不承认,我还没有真正习惯它,一直在查看 常见 演示。
我最近尝试使用 flexbox 在网格中对齐 web-card 样式的对象。我的想法是:如果只有一个项目,它位于中间(垂直和水平 // 也称为圣杯)。然后它会填充。每一行可以有三个项目,可以有多行。
我的问题从第二行开始(使用 flex-wrap: wrap):我难以将一个三乘三的网格平均对齐(水平和垂直使用“space-around”)。对于第二行,中心属性看起来很奇怪。第一行有三个项目,第二行有两个水平居中的项目,嗯。尝试了各种模糊的技巧(例如 nth-child),最后放弃了。
@Chris:你在这里的示例像往常一样简洁明了。也许我可以用它代替。在移动设备上,无论如何都没有列。
但我很好奇是否有代码笔示例展示了上面提到的两种轴(x 和 y)的对齐方式。
你的示例实际上在 Firefox 22+ 上也能正常工作。Firefox 直到 28 版本才支持 flex-wrap 和 flex-flow。所以,如果你觉得不需要这些,并且需要决定是否要实现 flexbox,那么可以将 Firefox 用户算作“支持使用 flexbox”的群体。
我今天遇到了这个问题和 IE10/11 的问题,你说的没错,Chris,这看起来像是 M$ 的实现错误。
https://connect.microsoft.com/IE/feedback/details/802625/min-height-and-flexbox-flex-direction-column-dont-work-together-in-ie-10-11-preview
如果有人愿意注册 MS Connect 网站并为这个错误投票 +1,将不胜感激。
嗯,真令人沮丧。有人有在 IE10 中填充满容器的有效解决方法吗?
Chris,
这似乎在 table-cell 元素中不起作用。请查看此示例:http://jsbin.com/xexojefu/2/