本文概述
灵活框(简称Flexbox)是2009年推出的CSS中的一组属性, 可提供新的出色的布局系统。 Flexbox模块被标识为CSS第三版(CSS3)的一部分。
你可能已经在CSS3中使用了许多新属性, 例如框阴影, 边界半径, 背景渐变等。但是, Flexbox尚未看到应有的广泛采用。这可能是由于它多年来遭受的所有重大变化, 或者是因为它在Internet Explorer 10中仅得到部分支持, 或者仅仅是因为Flexbox是一个完整的生态系统, 而以前的范例主要基于单一的, 随时可去属性。
它超级强大, 并提供了广泛的选择来实现以前只能梦dream以求的布局。
本文将带你逐步了解Flexbox的基础知识, 以及如何使用它来实现一些非常酷的布局, 否则这些布局将需要复杂的CSS hack甚至JavaScript。
为什么要使用Flexbox?
默认情况下, HTML块级元素会堆叠, 因此, 如果要在一行中对齐它们, 则需要依赖CSS属性(例如float), 或使用table-ish或inline-block设置来操纵display属性。
如果选择使用float(向左或向右), 则必须在某个时候清除包装器, 以将其推入最后一个浮动元素, 否则, 它们将溢出之后的所有内容。但是, 使用float时, 你只能水平组织元素。
另外, 你还可以操纵显示属性以尝试获得所需的布局!但这充其量常常使人感到困惑, 更不用说乏味了, 并且通常会导致布局相当脆弱, 并不一定会在浏览器中始终呈现。如果你要针对大小不同的多个设备, 这种方法特别无效-如今几乎总是如此。
输入Flexbox!
通过将简单规则应用于父元素, 你可以轻松控制其所有子元素的布局行为。
使用Flexbox, 你可以:
- 反转Flexbox父级中元素的顺序。
- 将子元素包装在列中(列数可根据子元素和父元素的高度而变化)。
- 指定在视口大小更改时元素增长或收缩的速率。
- 控制元素是否可收缩, 而不管指定的宽度单位类型(相对还是绝对)。
- 使用CSS更改元素的顺序(将此与媒体查询结合使用, 你将在流程中找到无限可能)。
- 生成元素的复杂分布, 使其与周围空间或两者之间的空间等距。
- 生成流动不同的”叛逆”元素(每个人都在左边, 但每个人都在右边, 顶部/底部, 这是你的要求)。
- 而且, 最重要的是, 要永远避免清除漏洞!
我了解Flexbox一开始可能会很艰难。我认为学习十个不相关的CSS属性要比学习五个相互依赖的属性要容易得多。但是, 利用你当前的CSS技能, 或者从本文中获得一些帮助, 你将可以进入一个新的CSS世界。
Flexbox的基础
显示
display是CSS中最基本的属性之一, 在Flexbox的上下文中非常重要, 因为它用于定义Flex包装器。
有两种可能的Flex包装器值:flex和inline-flex。
两者之间的区别在于, display:flex包装器的作用就像一个块元素, 而display:inline-flex包装器的作用就像一个内联块。另外, 如果没有足够的空间容纳子代, 则内联柔性元素也会增长。但是除了这些差异之外, 两者的行为是相同的。
尝试下面的示例代码, 当inline-flex处于活动状态时减小视口宽度, 然后…滚动。
请参阅CodePen上DD(@Diegue)的Pen Flexbox @srcmini-父级-” display”属性。
.wrapper {
display: flex || inline-flex;
}
弯曲方向
既然你已经看到了第一个示例, 则可以推断出默认行为是仅制作一行元素。但是还有更多:
- row(默认):从左到右排列元素(但是如果设置了RTL, 它将向后)。
- row-reverse:反转行处理中元素的顺序
- 列:从上到下排列元素
- column-reverse:反转列处理中元素的顺序
提示:可以使用column和column-reverse值来交换轴, 因此会影响水平轴的属性将影响垂直轴。
请参阅CodePen上DD(@Diegue)的Pen Flexbox @srcmini-父级-” flex-direction”属性。
.wrapper {
flex-direction: row || row-reverse || column || column-reverse;
}
弹性包装
如果你检查第一个代码示例, 则会发现默认情况下, 子元素不会在Flex包装器中堆叠。这是flex-wrap发挥作用的地方:
- nowrap(默认设置):防止包装弹性容器中的项目
- 包装:根据需要将项目包装到多行(或列, 具体取决于伸缩方向)
- wrap-reverse:与wrap一样, 但是行(或列)的数量在包装项目时沿相反的方向增长
请参阅CodePen上DD(@Diegue)的Pen Flexbox @srcmini-父级-” flex-wrap”属性。
.wrapper {
flex-wrap: nowrap || wrap || wrap-reverse;
}
弹性流
你可以将flex-direction和flex-wrap属性组合为一个属性:flex-flow。
.wrapper {
flex-flow: {flex-direction} {flex-wrap};
}
证明内容合理
此属性用于控制子元素的水平对齐:
- flex-start(默认):元素向左对齐(类似于带有text-align的行内元素:向左)
- flex-end:元素向右对齐(类似于具有text-align:right的内联元素)
- center:元素居中(类似于带有text-align的内联元素:center)
- 空格(魔术开始的地方):每个元素将在每个项目周围以相同的空间呈现。请注意, 两个顺序的子元素之间的空间将是最外面的元素与包装器侧面之间的空间的两倍。
- space-between:就像space-around, 除了元素将被相同的距离分开, 并且包装的任何边缘附近都没有空间。
注意:请记住, 将flex-direction设置为column或column-reverse时, 将交换轴。如果设置其中之一, 则对齐内容将影响垂直对齐, 而不是水平对齐。
请参阅CodePen上DD(@Diegue)的Pen Flexbox @srcmini-父级-`justify-content`属性。
对齐项目
此属性类似于justify-content, 但其影响的上下文是行而不是包装器本身:
- flex-start:元素垂直对齐到包装的顶部。
- flex-end:元素与包装的底部垂直对齐。
- center:元素在包装内垂直居中(最后, 安全的做法是做到这一点)。
- Stretch(默认):强制元素占据包装器的整个高度(应用于行时)和整个宽度(应用于列时)。
- 基线:将元素垂直于其实际基线对齐。
请参阅CodePen上DD(@Diegue)的Pen Flexbox @srcmini-父级-`align-items`属性。
对齐内容
此属性类似于justify-content和align-items, 但它在垂直轴上有效, 并且上下文是整个包装器(而不是上一示例中的行)。要查看其效果, 你将需要多个行:
- flex-start:行与顶部垂直对齐(即从包装器的顶部堆叠)。
- flex-end:行与底部垂直对齐(即, 从包装器的底部堆叠)。
- center:行在包装中垂直居中。
- Stretch(默认):通常, 此属性拉伸元素以利用包装的整个垂直高度。但是, 如果你设置了某些特定的元素高度, 则将遵循该高度, 剩余的垂直空间(在该行中, 该元素下方)将为空。
- 围绕空间:每行将在垂直方向(即自身下方和上方)周围具有相等的空间。请注意, 因此, 两行之间的空间将是顶部和底部行与包装纸边缘之间的空间的两倍。
- 间隔:像间隔一样, 除了元素之间的距离相同, 并且包装的顶部和底部边缘没有空间。
请参阅CodePen上DD(@Diegue)的Pen Flexbox @srcmini-父级-`align-content`属性。
弹性成长
此属性设置元素应使用的可用空间的相对比例。该值应为整数, 其中默认值为0。
假设你在同一个Flex包装器中有两个不同的元素。如果两个的flex-grow值均为1, 则它们将平均增长以共享可用空间。但是, 如果一个的flex-grow值为1, 另一个的flex-grow值为2, 如下面的示例所示, 则这个flex-grow值为2的空间将增长到第一个的两倍。
.wrapper .elements {
flex-grow: 1; /* Default 0 */
}
.wrapper .elements:first-child {
flex-grow: 2;
}
请参见CodePen上DD(@Diegue)的Pen Flexbox @srcmini-子级-” flex-grow”属性。
弹性收缩
与flex-grow相似, 此属性使用整数值设置元素是否可”收缩”。与flex-grow相似, flex-shrink指定flex项目的收缩因子。
请参阅CodePen上DD(@Diegue)的Pen Flexbox @srcmini-子级-” flex-shrink”属性。
.wrapper .element {
flex-shrink: 1; /* Default 0 */
}
弹性基础
此属性用于定义元素的初始大小, 然后分配可用空间并相应地调整元素。
提示:flex-basis在每个浏览器中都不支持calc()和box-sizing:border-box, 因此, 如果你需要使用width, 我建议使用width(注意, 你还需要设置flex-basis:auto ;)。
请参阅CodePen上DD(@Diegue)的Pen Flexbox @srcmini-子级-” flex-basis”属性。
.wrapper .element {
flex-basis: size || auto; /* Default auto */
}
柔性
你可以将flex-grow, flex-shrink和flex-basis属性组合为一个属性:flex如下:
.wrapper {
flex: {flex-grow} {flex-shrink} {flex-basis};
}
提示:如果你打算使用flex, 请确保定义每个值(即使你想使用默认值), 因为某些浏览器可能无法识别它们(常见的错误与未定义flex-grow值有关)。
自我对齐
此属性类似于align-items, 但效果分别应用于每个元素。可能的值为:
- flex-start:将元素垂直对齐到包装的顶部。
- flex-end:将元素垂直对齐到包装器的底部。
- center:将元素在包装内垂直居中(最后是实现此目的的简单方法!)。
- Stretch(拉伸)(默认):拉伸元素以占据包装器的整个高度(应用于行时)或占据包装器的整个宽度(应用于列时)。
- 基线:根据元素的实际基线对齐它们。
请参阅CodePen上DD(@Diegue)的Pen Flexbox @srcmini-子级-`align-self`属性。
订购
Flexbox包含的最好的功能之一是能够对元素进行重新排序(使用order属性), 而无需修改DOM或使用JavaScript。 order属性的工作方式非常简单。与z-index控制呈现项目的顺序大致相同, order控制元素在包装内的放置顺序;也就是说, 具有较低阶值的元素(顺便说一下, 它甚至可以是负数)位于具有较高阶值的元素之前。
请参阅CodePen上DD(@Diegue)的Pen Flexbox @srcmini-Children-`order`属性。
.wrapper .elements {
order: 1; /* this one will be positioned second */
}
.wrapper .elements:last-child {
order: -1; /* this one will be positioned first */
}
整合在一起:Flexbox的示例用法
在设计布局时, Flexbox释放了无限的可能性。在下面, 你可以找到一些使用Flexbox属性的示例。
垂直对齐组件
使用Flexbox, 你可以垂直对齐任何内容, 包括一次对齐多个元素。没有Flexbox, 你需要使用定位或表格技巧, 这些技巧要求我们创建一个包含多个元素的子元素。但是使用Flexbox, 你可以将这些繁琐而脆弱的技术抛在后面, 而只需在包装器中定义几个属性即可, 无论容器中的内容更改了多少次或更改的类型如何!
.wrapper {
display: flex; /* always present for Flexbox practices */
flex-direction: column; /* elements stack */
justify-content: center; /* now that flex-direction is a column, the axis are swapped so this centers the content vertically */
min-height: 100vh /* make sure wrapper is taller enough */
}
请参见Pen Flexbox @srcmini-我们可以提供的实际用法-通过CodePen上的DD(@Diegue)进行垂直对齐。
半/半布局
“半/半”布局是具有两列的全高度布局, 每列的内容垂直居中。通常在”首屏”之上实现(即, 在页面加载后用户向下滚动之前)。
使用更传统的技术, 你可以使用浮动元素(每个元素的宽度为50%)创建此布局, 将浮动元素清除到包装器中(” clearfix”:before和:after, overflow:隐藏, 或者使用清晰的怪异<div>:两者;最后)。但是, 这需要大量工作, 结果却不如Flexbox所提供的那样稳定。
在下面的代码片段中, 你将看到设置布局的容易程度, 以及子元素也将成为Flexbox包装器, 因为所有内容也都垂直对齐。
外包装:
.wrapper {
display: flex;
flex-direction: column; /* only for mobile */
}
内包装:
.inner-wrapper {
flex-grow: 1; /* Allow the element to grow if there is available space */
flex-shrink: 1; /* Elements shrink at the same rate */
flex-basis: 100%; /* Elements will cover the same amount, if is possible the 100% of the width */
}
请参阅Pen Flexbox @srcmini-我们可以提供的实际用途-CodePen上DD(@Diegue)的一半出血部分。
全宽导航栏按钮
全宽导航栏会在导航栏项目的同一行中平均分配空间, 而不考虑元素的数量。
在下面的示例中, 还有一些没有这种行为的图标按钮, 表明你可以按照需要的方式将两者结合在一起。如果没有Flexbox, 要实现这种布局, 就需要JavaScript代码来计算可用空间, 然后根据哪些按钮跨度和哪些按钮不跨度以编程方式进行分配。
Flexbox使这一过程变得更加简单。
包装器属性:
.navbar {
display: flex;
}
跨越子属性:
.navbar-item {
flex-grow: 1; /* They will grow */
}
非扩展子属性:
.navbar-other {
flex-grow: 0; // They won’t grow
}
请参阅Pen Flexbox @srcmini-我们可以提供的实际用途-CodePen上DD(@Diegue)的全出血按钮导航栏。
模糊
你必须在不同的项目中实施几次带有图标和文本的信息框集合?
元素的这种分布在数字营销中最有用, 但在软件开发中可以有其他用途。借助Flexbox的强大功能, 你可以设置一种网格, 也可以对齐元素, 无论有多少元素。
包装器属性:
.wrapper {
display: flex;
flex-wrap: wrap;
}
子属性:
.blurb {
flex-grow: 0; /* elements don’t grow */
flex-shrink: 0; /* elements don’t shrink in a flexible way */
flex-basis: auto; /* the width of the elements will be set by proportions in `width` due to flex-basis not support workaround */
width: calc(33.33% - 60px); /* calculate proportional width without space taken by padding (workaround for IE 11) */
}
对于平板电脑和移动视口, 宽度在50%和100%之间变化。
请参阅Pen Flexbox @srcmini-我们可以提供的实际用途-通过CodePen上的DD(@Diegue)进行模糊处理。
增强跨浏览器的兼容性
在不同的浏览器版本中, Flexbox的语法已多次更改。当使用Flexbox实现布局并尝试支持较旧的Web浏览器(尤其是较旧版本的Internet Explorer)时, 这可能是一个问题。
幸运的是, Flexbug中列出了许多使代码能够在最广泛的Web浏览器上运行的技术和变通办法, 这是一个很好的资源。如果你遵循该站点上的信息, 则在不同的Web浏览器上将获得更好, 一致的结果。
前缀任务在这方面特别有用。要自动执行CSS规则的前缀, 可以选择以下工具之一:
红宝石:
- 自动前缀导轨
- 中间人自动前缀
Node.js:
- PostCSS自动前缀
- 自动前缀土地
- Gulp自动前缀
开始构建智能布局
Flexbox是加速, 改进和扩展我们的工作的绝佳工具。限制仅在开发人员的想象中。
如果你需要视觉帮助来计划下一个布局, 可以尝试以下整洁的游乐场:
请参阅CodePen上的DD(@Diegue)的Pen Flexbox @srcmini-Flexbox运动场。
在新窗口中打开它。
随着大多数用户越来越多地采用现代Web浏览器, 使用Flexbox将使你可以轻松创建惊人的布局, 而无需深入研究凌乱的JavaScript代码或复杂的CSS。