作者都是各自领域经过审查的专家,并撰写他们有经验的主题. 我们所有的内容都经过同行评审,并由同一领域的Toptal专家验证.
Diego Díaz的头像

Diego Díaz

Diego是一位经验丰富的web开发人员,对UI和UX充满热情. 他努力为任何设备和架构创造流畅的布局.

以前在

Globant
Share

Flexible box, 或者简称为Flexbox, 2009年在CSS中引入的一组属性是否提供了一个新的, 特殊布局系统. Flexbox模块被确定为第三版CSS (CSS3)的一部分。.

你可能已经在使用了 CSS3中的许多新属性, such as box-shadow, 这个特性, 背景渐变, and so on. 然而,Flexbox还没有得到应有的广泛采用. 这可能是因为多年来它所遭受的所有突破性变化, 或者是因为ie 10只部分支持, 或者只是因为Flexbox是一个完整的生态系统,而之前的范例主要是基于单一的, 准备好了属性.

它是超级强大的,并提供了广泛的选项来实现CSS灵活布局, previously, 只能是梦想吗.

本文将带您了解Flexbox的基础知识,以及如何使用它来实现一些非常酷的Flexbox布局,否则这些布局将需要复杂的CSS技巧甚至JavaScript.

为什么要使用Flexbox?

By default, HTML块级元素堆栈, 如果你想把它们排成一行, 你需要依赖CSS属性,比如 float,或操纵 display 属性设置为表格式或行内块设置.

如果您选择使用 float (左或右),你必须 清除包装 在某个点上推它,直到最后一个浮动元素, otherwise, 它们会溢出来淹没后面的任何东西. 但是,使用float,您只能水平组织元素.

此外,您还可以操作 display 属性来尝试实现您想要的布局! 但这往往让人感觉很笨拙, 更不用说乏味了, 这通常会导致一个相当脆弱的布局,不一定会在不同浏览器之间呈现一致. 如果您的目标是不同大小的多个设备,那么这种方法尤其无效——现在几乎总是这样.

进入Flexbox!

使用应用于父元素的简单规则, 您可以轻松地控制其所有子控件的布局行为.

使用Flexbox,您可以:

  • 反转flexx父元素中的元素顺序.
  • 在列中换行子元素(列数可以根据子元素和父元素的高度而变化).
  • 指定视口大小变化时元素增长或缩小的速率.
  • 控制元素是否可收缩, 不论指定的宽度单位类型(相对或绝对).
  • 使用CSS改变元素的顺序(将其与 媒体查询 你会在你的心流中发现无限的可能性。.
  • 生成元素的复杂分布,使其与周围空间或之间的空间等距.
  • 生成流动方式不同的“叛逆者”元素(每个元素都在左边,只有一个元素在右边), 顶部/底部…由你决定).
  • 最重要的是,避免 清除修复技巧 for good!

我知道flexx刚开始的时候很难对付. 我认为学习10个不相关的CSS属性要比学习5个相互依赖的属性容易得多. However, 以你目前的CSS技能, 也许这篇文章能帮上点忙, 您将进入一个新的CSS世界.

Flexbox的基础知识

Display

Display

display 是CSS中最基本的属性之一,在Flexbox环境中非常重要, 因为它用于定义flex包装器.

有两种可能的flex包装器值: flex and inline-flex.

两者的区别是a 显示:flex 包装器的作用类似于块元素,而 显示:inline-flex 包装器的作用类似于内联块. Also, inline-flex 如果没有足够的空间容纳子元素,元素就会增长. 但除了这些不同之外,两者的行为是一样的.

尝试下面的示例代码,当inline-flex激活时减小视口宽度,然后……滚动.

See the Pen Flexbox @Toptal - Parent - ' display '属性 by DD (@Diegue) on CodePen.

.wrapper {
    显示:flex || inline-flex;
}

Flex方向

Flex方向

现在您已经看到了第一个示例, 您可以推断,默认行为是简单地生成一行元素. 但还有更多:

  • row (默认):从左到右排列元素(但如果设置了RTL,则是向后排列).
  • row-reverse: 反转行配置中元素的顺序
  • column: 从上到下排列元素
  • column-reverse: 反转列配置中元素的顺序

Hint: The column and column-reverse 值可以用来交换轴, 所以影响横轴的属性会影响纵轴.

See the Pen Flexbox @Toptal - Parent - ' flex-direction '属性 by DD (@Diegue) on CodePen.

.wrapper {
    伸缩方向:row || row-reverse || column || column-reverse;
}

Flex Wrap

如果您检查第一个代码示例, 您将发现,在默认情况下,子元素不会在flex包装器中堆叠. 这就是 flex-wrap 开始发挥作用:

  • nowrap (默认):防止伸缩容器中的项进行包装
  • wrap: 根据需要将项包装到多行(或多列)中 flex-direction)
  • wrap-reverse: Just like wrap,但是行(或列)的数量与项目的包装方向相反

See the Pen Flexbox @Toptal - Parent - ' flex-wrap '属性 by DD (@Diegue) on CodePen.

.wrapper {
    Flex-wrap: nowrap || wrap | wrap-reverse;
}

Flex Flow

你可以结合 flex-direction and flex-wrap 属性转换为单个属性: flex-flow.

.wrapper {
    Flex-flow: {flex-direction} {flex-wrap};
}

证明内容

证明内容

此属性用于控制子元素的水平对齐:

  • flex-start (默认):元素向左对齐(类似于使用 text-align:左)
  • flex-end: 元素向右对齐(类似于使用 text-align:对)
  • center: 元素居中(类似于使用 text-align:中心)
  • space-around (魔法开始的地方):每个元素都将在每个物品周围呈现相同数量的空间. 请注意,两个顺序子元素之间的空间将是最外层元素和包装器两侧之间空间的两倍.
  • 之间的空间: Just like space-around,除了元素之间的距离相同,还有 no 包装纸两边附近的空间.

注意:记住 flex-direction,当设置为 column or column-reverse,交换轴. 如果其中一个被设置, justify-content 会影响垂直对齐,而不是水平对齐.

See the Pen Flexbox @Toptal - Parent - ' justify-content '属性 by DD (@Diegue) on CodePen.

Align Items

Align Items

这个性质类似于 justify-content 但其效果的上下文是行而不是包装器本身:

  • flex-start: 元素与包装器的顶部垂直对齐.
  • flex-end: 元素与包装器的底部垂直对齐.
  • center: 元素在包装器内垂直居中(最后,实现这一点的安全实践).
  • stretch (默认):强制元素占用包装器的全高(应用于一行时)和全宽(应用于列时).
  • baseline: 垂直对齐元素到它们的实际 baselines.

See the Pen Flexbox @Toptal - Parent - align-items属性 by DD (@Diegue) on CodePen.

调整内容

调整内容

这个性质类似于 justify-content and align-items 但它在垂直轴上工作,上下文是整个包装器(不像前面的例子那样是行). 要查看其效果,您需要不止一行:

  • flex-start: 行与顶部垂直对齐(i.e.,从包装的顶部堆叠).
  • flex-end: 行与底部垂直对齐(i.e.,从包装的底部堆叠).
  • center: 行在包装器中垂直居中.
  • stretch (默认):一般情况下, 此属性拉伸元素以利用包装器的整个垂直高度. However, 如果你设置了元素的特定高度, 该高度将被尊重,剩余的垂直空间(在该行中), 在该元素下面)将为空.
  • 空间: 每一行都将在其周围垂直渲染相同数量的空间(i.e.,在其下方和上方). 注意,两行之间的空格将, therefore, 上下行与包装纸边缘之间的间距是原来的两倍.
  • 之间的空间: Just like space-around, 除了元素将被相同的距离分开,并且在包装器的顶部和底部边缘将没有空间.

See the Pen Flexbox @Toptal - Parent - ' align-content '属性 by DD (@Diegue) on CodePen.

Flex Grow

Flex Grow

此属性设置元素应该使用的可用空间的相对比例. 该值应为整数,其中0为默认值.

假设在同一个flex包装器中有两个不同的元素. 如果两者都有 flex-grow 值为1时,它们将平均增长以共享可用空间. 但是如果一个 flex-grow 值1和另一个a flex-grow 值2,如下面的例子所示,这个带有a flex-grow 值2会增长,占用的空间是第一个的两倍.

.wrapper .elements {
    flex-grow: 1; /* Default 0 */
}
.wrapper .元素:第一个孩子{
    flex-grow: 2;
}

See the Pen Flexbox @Toptal - Children - ' flex-grow '属性 by DD (@Diegue) on CodePen.

Flex Shrink

Similar to flex-grow,此属性以整数值设置元素是否“可收缩”. Similar to flex-grow, flex-shrink 指定伸缩项的收缩系数.

See the Pen Flexbox @Toptal - Children - ' flex-shrink '属性 by DD (@Diegue) on CodePen.

.wrapper .element {
    flex-shrink: 1; /* Default 0 */
}

Flex Basis

此属性用于在分配可用空间并相应地调整元素之前定义元素的初始大小.

Hint: flex-basis 不支持 calc() and box-sizing: border-box ,所以我建议使用 width 如果您需要使用其中一个(请注意,您还需要设置 flex-basis:汽车;).

See the Pen Flexbox @Toptal - Children - ' flexible -basis '属性 by DD (@Diegue) on CodePen.

.wrapper .element {
    flex-basis: size || auto; /* Default auto */
}

Flex

你可以结合 flex-grow, flex-shrink, and flex-basis 属性转换为单个属性: flex as follows:

.wrapper {
    Flex: {Flex -grow} {Flex -shrink} {Flex -basis};
}

提示:如果您打算使用 flex, 确保定义每个单独的值(即使您想使用默认值),因为有些浏览器可能无法识别它们(一个常见的错误与没有定义 flex-grow value).

Align Self

Align Self

这个性质类似于 align-items 但是效果是单独应用于每个元素的. 可能的值是:

  • flex-start: 将元素垂直对齐到包装器的顶部.
  • flex-end: 将元素垂直对齐到包装器的底部.
  • center: 在包装器中使元素垂直居中(这是实现这一点的一种简单方法)!).
  • stretch (默认):拉伸元素以占据包装器的全部高度(当应用于一行时)或包装器的全部宽度(当应用于列时).
  • baseline: 根据元素的实际基线对齐元素.

See the Pen Flexbox @ total - Children - align-self属性 by DD (@Diegue) on CodePen.

Order

Flexbox可以像这个例子中展示的那样重新排序图像

flex中包含的最好的功能之一是元素重新排序的能力(使用 order 属性),而无需修改DOM或使用JavaScript. The way the order 房地产工作超级简单. 就像 z-index 控制项的呈现顺序, order controls the order in which elements are positioned within the wrapper; that is, 低的元素 order 价值(它甚至可以是负的,顺便说一下)被定位在那些具有更高的 order value.

See the Pen Flexbox @Toptal - Children - order属性 by DD (@Diegue) on CodePen.

.wrapper .elements {
    order: 1;   /* this one will be positioned second */
}
.wrapper .元素:胎{
    order: -1;   /* this one will be positioned first */
}

把它放在一起:Flexbox布局的例子

当涉及到设计布局时,Flexbox释放了一个充满可能性的世界. 下面,您可以找到一些使用flexx属性的示例.

垂直对准分量

使用Flexbox,你可以垂直对齐任何东西,包括同时对齐多个元素. 没有Flexbox, 您需要使用定位或类似表格的技术,这些技术要求我们创建一个子元素来包含多个元素. 但是有了Flexbox, 你可以把这些乏味而脆弱的技术抛在脑后, 只需在包装器中定义一些属性,就可以了, 无论容器内的内容更改了多少次或更改的类型如何!

.wrapper {
    显示:flex; /* always present for Flexbox practices */
    flex-direction: column; /* elements stack */
    justify-content: center; /* now that flex-direction is a column, 轴被交换了,所以内容垂直居中*/
    最小高度:100vh /*确保包装足够高*/
}

See the Pen Flexbox @Toptal -我们可以给出的实际用途-垂直对齐 by DD (@Diegue) on CodePen.

/一半布局

“半/半”布局是两列的全高布局, 每个页面的内容垂直居中. 它通常是在“上面”实现的.e.,在用户在页面加载后向下滚动之前).

使用更传统的技术, 你可以用浮动元素创建这个布局(每个元素宽度为50%), 将浮点清除到包装器中(" clearfix ") :before and :after, 隐藏溢出:,或者是个怪人

with clear: both; in the end). 然而,这需要大量的工作,而且结果不像Flexbox提供的那样稳定.

在以下代码片段中, 你将会看到使用flexbox设置布局是多么容易,同时也会看到子元素是如何成为flexbox包装器的,因为所有的东西都是垂直对齐的.

外层包装:

.wrapper {
    显示: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 */
}

See the Pen Flexbox @Toptal -我们可以给出真正的用途-半流血部分 by DD (@Diegue) on CodePen.

全宽度导航栏按钮

全宽导航条在同一行导航条项中平均分配空间,而不考虑元素的数量.

在下面的示例中,也有一些标志性的按钮 without 这种行为表明,您可以以任何您想要的方式组合这两者. 没有Flexbox, 实现这些布局需要JavaScript代码来计算可用空间,然后根据按钮的跨度和不跨度以编程方式进行分配.

Flexbox让这变得更简单.

包装属性:

.navbar {
    显示:flex;
}

跨子属性:

.navbar-item {
    flex-grow: 1; /* They will grow */
}

非生成子属性:

.navbar-other {
    flex-grow: 0; // They won’t grow
}

See the Pen Flexbox @Toptal -真正的用途,我们可以给-全流血按钮导航栏 by DD (@Diegue) on CodePen.

Blurbs

有多少次你必须在不同的项目中实现一组带有图标和文本的信息框?

这种元素分布在数字营销中非常有用,但在软件开发中也有其他用途. 有了Flexbox的强大功能,你可以设置一种 grid 并且对齐元素,不管有多少.

包装属性:

.wrapper {
    显示:flex;
    flex-wrap:包装;
}

孩子属性:

.blurb {
    flex-grow: 0; /* elements don’t grow */
    flex-shrink: 0; /* elements don’t shrink in a flexible way */
    flex-basis:汽车; /* the width of the elements will be set by proportions in `width` due to flex-basis not support workaround */
    宽度:钙(33.33% - 60px); /* calculate proportional width without space taken by padding (workaround for IE 11) */
}

对于平板电脑和手机视口,宽度在50%到100%之间变化.

See the Pen Flexbox @Toptal -真正的用途,我们可以给-宣传 by DD (@Diegue) on CodePen.

增强跨浏览器兼容性

Flexbox的语法在不同的浏览器版本中已经改变了很多次. 当使用Flexbox实现布局并试图支持旧的web浏览器时,这可能是一个问题, 尤其是旧版本的ie浏览器.

Fortunately, 中列出了许多使代码在最广泛的web浏览器上工作的技术和解决方法 Flexbugs,这是一个很好的资源. 如果你按照网站上的信息去做, 你会有更好的, 跨不同浏览器的一致结果.

前缀任务在这方面特别有用. 要自动添加CSS规则的前缀,你可以选择以下工具之一:

Ruby:

Node.js:

开始构建智能布局与Flexbox

Flexbox是一个很棒的工具,可以加快、优化和扩展我们的工作. 限制只存在于开发者的想象中.

我们希望你喜欢我们的Flexbox布局示例, 如果你需要一些视觉辅助来规划你的下一个布局,你可以试试这个整洁的游乐场:

See the Pen Flexbox @Toptal - Flexbox游乐场 by DD (@Diegue) on CodePen.

打开它。 new window.

随着大多数用户越来越多地采用现代网络浏览器, 使用Flexbox可以让你轻松创建令人惊叹的布局,而不需要深入研究混乱的JavaScript代码或制作笨拙的CSS. 您还可以尝试各种flex模板,并使用它们作为灵感或自己布局的起点.

聘请Toptal这方面的专家.
Hire Now
Diego Díaz的头像
Diego Díaz

Located in 乌拉圭蒙得维的亚,蒙得维的亚省

成员自 2017年1月27日

作者简介

Diego是一位经验丰富的web开发人员,对UI和UX充满热情. 他努力为任何设备和架构创造流畅的布局.

Toptal作者都是各自领域经过审查的专家,并撰写他们有经验的主题. 我们所有的内容都经过同行评审,并由同一领域的Toptal专家验证.

以前在

Globant

世界级的文章,每周发一次.

订阅意味着同意我们的 隐私政策

世界级的文章,每周发一次.

订阅意味着同意我们的 隐私政策

Toptal开发者

加入总冠军® community.