前言

弹性盒子是一种用于按行或按列布局元素的一维布局方法 。元素可以膨胀以填充额外的空间, 收缩以适应更小的空间。 本文将解释所有的基本原理。

为什么使用弹性盒

长久以来,CSS 布局中唯一可靠且跨浏览器兼容的创建工具只有 floats 和 positioning。这两个工具大部分情况下都很好使,但是在某些方面它们具有一定的局限性,让人难以完成任务。

以下简单的布局需求是难以或不可能用这样的工具( floats 和 positioning)方便且灵活的实现的:

在父内容里面垂直居中一个块内容。
使容器的所有子项占用等量的可用宽度/高度,而不管有多少宽度/高度可用。
使多列布局中的所有列采用相同的高度,即使它们包含的内容量不同。
正如你将在后面的章节中看到的一样,弹性盒子使得很多布局任务变得更加容易。

弹性盒子简单介绍

  • 主轴(main axis)是沿着 flex 元素放置的方向延伸的轴(比如页面上的横向的行、纵向的列)。该轴的开始和结束被称为 main start 和 main end。
  • 交叉轴(cross axis)是垂直于 flex 元素放置方向的轴。该轴的开始和结束被称为 cross start 和 cross end。
  • 设置了 display: flex 的父元素(在本例中是
    )被称之为 flex 容器(flex container)。
  • 在 flex 容器中表现为柔性的盒子的元素被称之为 flex 项(flex item)(本例中是
    元素。

弹性盒子提供了 flex-direction 这样一个属性,它可以指定主轴的方向(弹性盒子子类放置的地方)— 它默认值是 row,这使得它们在按你浏览器的默认语言方向排成一排(在英语/中文浏览器中是从左到右)。

尝试将以下声明添加到 section 元素的 css 规则里:

另一种容器

采用 Flex 布局的元素,称为 Flex 容器(flex container),简称”容器”。它的所有子元素自动成为容器成员,称为 Flex 项目(flex item),简称”项目”,也叫flex元素。

起始线和终止线

之前我们一般都默认文档书写时从左到右的,但是Flex没有左右的概念,默认情况下,flex-direction的属性值为row,意思就是主轴为水平方向,起始线(也就是起点)在左边。flex-direction属性还有其他属性值,这里先不列举,后面详细说。

示例

使用Flex布局

1
2
3
.box {
display: flex;
}

行内元素也可以指定为Flex容器

1
2
3
.box {
display: inline-flex;
}

Webkit内核的浏览器

1
2
3
4
.box{
display: -webkit-flex; /* Safari */
display: flex;
}

注意,设为 Flex 布局以后,子元素的float、clear和vertical-align属性将失效。

容器的属性

可以设置下面6个属性

1
2
3
4
5
6
flex-direction
flex-wrap
flex-flow
justify-content
align-items
align-content
1
2
3
4
5
6
/* HTML */
<div class="container">
<div class="item">one</div>
<div class="item">two</div>
<div class="item">three</div>
</div>

Webkit内核的浏览器

1
2
3
4
5
6
7
8
9
10
.container {
width: 800px;
height: 400px;
margin: 100px auto;
border: 1px dashed #00f;
}
.item {
border: 1px solid #000;
text-align: center;
}
  • flex-wrap属性
    默认情况下,项目都排在一条线(又称”轴线”)上。flex-wrap属性定义,如果一条轴线排不下,如何换行。
1
2
3
4
5
6
.box{
flex-wrap: nowrap | wrap | wrap-reverse;
/* nowrap(默认): 不换行 */
/* wrap: 换行,第一行在前面 */
/* wrap-reverse: 换行,第一行在后面 */
}
1
2
3
4
.item {
width: 300px; /* 每个项目宽度为300px,总共是900px */
...
}
  • order属性
    order属性定义项目(元素)的排列顺序。数值越小,排列越靠前,默认为0。

还是先修改一下页面代码

1
2
3
4
5
6
/* HTML */
<div class="container">
<div class="item item1">one</div>
<div class="item item2">two</div>
<div class="item item3">three</div>
</div>

Webkit内核的浏览器

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
/* CSS */
.container {
width: 800px;
height: 400px;
margin: 100px auto;
border: 1px dashed #00f;
display: flex;
align-items: flex-start;
}
.item {
width: 200px;
margin: 20px 0;
border: 1px solid #000;
text-align: center;
}

增加CSS代码

1
2
3
4
5
6
7
8
9
10
11
12
/* CSS */
.item1 {
order: 3
}

.item2 {
order: 2
}

.item3 {
order: 1
}

可以看到如果只给一个元素设置flex-grow大于0的属性,那个这个元素会占据剩余空间。

如果给多个元素设置相同的flwx-grow属性,那么这些元素会平分剩余空间。

还有一种情况我没列举,给不同元素设置不同大小的flex-grow属性,这时候会根据flex-grow的大小分配不同大小的空间。

上面说的都是在容器有剩余空间的情况下,如果项目充满了容器,name设置flex-grow是没效果的。