最直观的方式学习flexbox属性

511 查看

弹性盒模型(Flexbox Layout)是CSS3新增的一种布局模式。它可以很方便地用来改善动态或未知大小的子元素在父元素中的对齐,方向和顺序等等。flex容器的主要特性是它可以调整子元素的宽度或高度去填充可用的空白区,以最优的方式达到兼容不同屏幕大小。

很多设计师和开发人员发现flexbox布局很容易使用,因为元素的定位非常简单,只需要写很少的代码,就能达到预期效果。Flexbox布局算法不同于那些基于垂直或水平的块或内联布局。Flexbox布局应该用在小项目中的组件。

这篇文章主要集中在说明flex属性如何影响布局,而不是这些属性如何工作。

可能你会觉得flex很多属性很难记住,或是看了很多文字说明但是不知道具体效果如何,那么这篇文章就非常适合你了。

让我们开始吧!

BASICS

在我们开始之前先来定下规则,我们把父容器称为flex container,它的直接子元素称为flex items

上面的盒子中,你可以看到用来描述flex container 和 它的子元素的属性与术语。如果你需要查看更多,点击这里

flexbox从2009年的初稿走到现在,经历了时间的洗练和各种语法的变更。所以为了避免冲突,这篇文章我们只使用最新并且有效的版本。如果你需要兼容旧浏览器,你可以看看这篇文章(英文)

最新的flexbox兼容以下浏览器:

  • Chrome 29+
  • Firefox 28+
  • Internet Explorer 11+
  • Opera 17+
  • Safari 6.1+ (prefixed with -webkit-)
  • Android 4.4+
  • iOS 7.1+ (prefixed with -webkit-)

如果你需要查看更多浏览器兼容性,你可以看这里

USAGE

使用flexbox布局,你需要在父元素上设置display属性

.flex-container {
  display: -webkit-flex; /* Safari */
  display: flex;
}

或者你可以把它当行内元素使用

.flex-container {
  display: -webkit-inline-flex; /* Safari */
  display: inline-flex;
}

注意:你给父容器设置了这个属性后,它的子元素都会自动变成flex items

有很多种给flexbox属性分组的方式,到目前为止,我认为最简单,并且最容易理解的方式是按照flex containerflex items分成两组。下面,我们来解释各个元素是如何影响布局效果的。

Flexbox Container 属性

flex-direction

这个属性指定了flex itemsflex container中是如何布局的。通过设置flex container的主轴的方向,它们会按照两个方向布局,水平的行或者垂直的列。

例子:

.flex-container {
  -webkit-flex-direction: row; /* Safari */
  flex-direction:         row;
}

设置为行,那么在ltr上下文环境下,所有flex items会按照从左到右的顺序排成一行。

图片描述

.flex-container {
  -webkit-flex-direction: row-reverse; /* Safari */
  flex-direction:         row-reverse;
}

使用row-reverse属性,那么在ltr上下文环境下,子元素则会按照从右到左的顺序排成一行。

图片描述

.flex-container {
  -webkit-flex-direction: column; /* Safari */
  flex-direction:         column;
}

使用column属性,flex items会按照从上到下的方式排列。

图片描述

.flex-container {
  -webkit-flex-direction: column-reverse; /* Safari */
  flex-direction:         column-reverse;
}

使用column-reverse,则会放过来。

图片描述

默认值:row
注:row和row-reverse的排列方式取决于书写模式,所以如果是在rtl上下文环境下,它们都会反转。


flex-wrap

默认的flexbox概念是把所有子元素都放在一行里面,你可以通过flex-wrap属性来控制flex container是否将子元素分多行处理,以及新增行的方向。

例子:

.flex-container {
  -webkit-flex-wrap: nowrap; /* Safari */
  flex-wrap:         nowrap;
}

Flex items会被置在一行里面,并且默认它们会被压缩来适应容器的宽度。

图片描述

.flex-container {
  -webkit-flex-wrap: wrap; /* Safari */
  flex-wrap:         wrap;
}

wrap, Flex items会被按照从上到下从左到右的顺序分配到多行。

图片描述

.flex-container {
  -webkit-flex-wrap: wrap-reverse; /* Safari */
  flex-wrap:         wrap-reverse;
}

wrap-reverse, Flex itms会被按照从左到右从下到上的顺序在多行中显示。

图片描述

默认值:nowrap
注:这个属性也跟书写模式相关。


flex-flow

这个属性是flex-directionflex-wrap属性的缩写。

例子:

.flex-container {
  -webkit-flex-flow: <flex-direction> || <flex-wrap>; /* Safari */
  flex-flow:         <flex-direction> || <flex-wrap>;
}

默认值:row nowrap

justify-content

这个属性会根据当前容器的主轴来排列子元素。它可以在所有flex items都在同一行并且不可伸缩,或是可伸缩但是达到它们的最大尺寸时候,分配剩余空间。

例子:

.flex-container {
  -webkit-justify-content: flex-start; /* Safari */
  justify-content:         flex-start;
}

Flex itemslrt上下文中会向左边靠拢

图片描述

.flex-container {
  -webkit-justify-content: flex-end; /* Safari */
  justify-content:         flex-end;
}

Flex itemsltr上下文中向右靠拢

图片描述

.flex-container {
  -webkit-justify-content: center; /* Safari */
  justify-content:         center;
}

Flex items会居中

图片描述

.flex-container {
  -webkit-justify-content: space-between; /* Safari */
  justify-content:         space-between;
}

除了第一个和最后一个,Flex items会有相同的间隔。

.flex-container {
  -webkit-justify-content: space-around; /* Safari */
  justify-content:         space-around;
}

所有Flex item 都会有相同间隔

图片描述

默认值: flex-start


align-items

Flex items 会根据当前容器的主轴线对齐,跟justify-content很相似,但是方向垂直。
这个属性设置所有flex items默认对齐方式。

例子:

.flex-container {
  -webkit-align-items: stretch; /* Safari */
  align-items:         stretch;
}

Flex items会占满flex container的高度,从cross start到cross end

图片描述

.flex-container {
  -webkit-align-items: flex-start; /* Safari */
  align-items:         flex-start;
}

Flex items会与flex container 的交叉轴起始(cross start)线对齐。

图片描述

.flex-container {
  -webkit-align-items: flex-end; /* Safari */
  align-items:         flex-end;
}

Flex items会与flex container 的交叉轴结尾(cross end)线对齐。

图片描述

.flex-container {
  -webkit-align-items: center; /* Safari */
  align-items:         center;
}

Flex items会在交叉轴(cross axis)上对齐

图片描述

.flex-container {
  -webkit-align-items: baseline; /* Safari */
  align-items:         baseline;
}

Flex items会按照它们的基线(baselines)对齐

图片描述

默认值:stretch
注:点击这里查看更多关于基线如何运算


align-content

align-content属性对齐flex container上的行,控制交叉轴的多余间隔,跟主轴上的justify-content属性很相似。

例子:

.flex-container {
  -webkit-align-content: stretch; /* Safari */
  align-content:         stretch;
}

每一行Flex items后面都会有区分开的间隔。

图片描述

.flex-container {
  -webkit-align-content: flex-start; /* Safari */
  align-content:         flex-start;
}

Flex items会向交叉轴起始位置靠拢

图片描述

.flex-container {
  -webkit-align-content: flex-end; /* Safari */
  align-content:         flex-end;
}

Flex items会向交叉轴的结束位置靠拢

图片描述

.flex-container {
  -webkit-align-content: center; /* Safari */
  align-content:         center;
}

flex items的行会在交叉轴上居中显示

图片描述

.flex-container {
  -webkit-align-content: space-between; /* Safari */
  align-content:         space-between;
}

除了起始和结尾行,flex items的其他行都会有相同的间隔。

图片描述

.flex-container {
  -webkit-align-content: space-around; /* Safari */
  align-content:         space-around;
}

每一行都会有相同上下间隔

图片描述

默认值:stretch
注:这个属性只会在flex container有多行的时候才会有效,如果只有一行那么这个属性就不会有效果。

关于flex containers

  • 所有的column-*属性在flex container上都不会有效果
  • ::first-line::first-letter伪类在flex container上不会被应用。

FlexBox Item 属性

Order

order属性定义子元素在父容器中的顺序,默认它们会被最加到后面
例子:

.flex-item {
  -webkit-order: <integer>; /* Safari */
  order:         <integer>;
}

不需要调整HTML,就能修改显示顺序

图片描述

默认值:0


flex-grow

这个属性是一个flex拉伸因子,决定了flex items会相对于父容器剩余空间增长多少。

.flex-item {
  -webkit-flex-grow: <number>; /* Safari */
  flex-grow:         <number>;
}

如果所有flex items都有相同的flex-grow,那么他们都会在父容器中有相同的尺寸。

图片描述

调整一下,看看有什么区别

图片描述

默认值:0
注:负数是不合法的


flex-shrink

flex-shrink是一个flex收缩因子,它决定了当父容器体积不足时,flex items收缩的相对比例。

.flex-item {
  -webkit-flex-shrink: <number>; /* Safari */
  flex-shrink:         <number>;
}

默认所有flex items都是可以压缩的,但如果我们把它设为0,那么它将保持原有大小。

图片描述

默认值: 1
注:负数是不合法的


flex-basis

这个属性会设置宽度和高度,
原文为:This property takes the same values as the width and height properties
并在flex因子分割间隔之前,指定flex items的初始大小。

.flex-item {
  -webkit-flex-basis: auto | <width>; /* Safari */
  flex-basis:         auto | <width>;
}

flex-basis会指定第四个flex items的初始大小

图片描述

默认值: auto


flex

这个属性是flex-grow,flex-shrinkflex-basis属性的缩写。

.flex-item {
  -webkit-flex: none | auto | [ <flex-grow> <flex-shrink>? || <flex-basis> ]; /* Safari */
  flex:         none | auto | [ <flex-grow> <flex-shrink>? || <flex-basis> ];
}

默认值:0 1 auto
注:w3c鼓励使用简写,而不是每个属性都分开写。


align-self

这个属性允许为单个flex items重写对齐方式。

.flex-item {
  -webkit-align-self: auto | flex-start | flex-end | center | baseline | stretch; /* Safari */
  align-self:         auto | flex-start | flex-end | center | baseline | stretch;
}

图片描述

默认值:auto
注:The value of auto for align-self computes to the value of align-items on the element’s parent, or stretch if the element has no parent.

关于flex items

  • float,clearvertical-alignflex item上都不会有作用,也不会让它脱离文档流。
FlexBox 练兵场

下面这个完善的例子,你可以随便组合各种属性以查看效果。

你也可以点击这里查看全屏模式,或者在github上看源码

本文根据@Dimitar的文章所译,整篇译文带有我们自己的理解和意思,如果有译得不好的地方或者不对之处,还请大家指点。

英文出处:A Visual Guide to CSS3 Flexbox Properties
译文出处:http://w3ctrain.com/2015/11/12/visual-guide-to-css3-flexbox-flexbox-playground/