赞
踩
Flex 布局,即 Flex Box(弹性布局),是一种较为灵活、强大的页面 CSS 布局方式。在深入学习 Flex 布局前,我们需要了解一些 Flex 相关的概念和术语。
Flex 布局的优点:
首先,我们需要了解一下 Flex 布局中的一些概念和术语:
在图1-1 非常清晰的展示了这些概念的相互关系。
图1-1 Flex 容器
使用 Flex 布局的元素(display: flex),称之为 Flex 容器(Flex Container),简称 "容器"。Flex 的布局发生在父容器和子容器之间,因此,元素一旦被申明为 Flex 布局后,它的所有子元素自动成为容器成员。通常,我们将容器内的成员统称为 Flex 项目(Flex item),简称 "项目"。
本文约定:"容器" 指的是 Flex 容器;"项目" 指的是 Flex 项目。
容器中默认存在两条线轴,即:主轴(main axis)、交叉轴(cross axis)。主轴与交叉轴是垂直关系,值得注意的是主轴不一定是水平方向,而是由 flex-direction 属性所决定的。
项目(flex item)默认是沿主轴方向排列的,单个项目占据主轴的空间称之为 main size,占据交叉轴的空间称之为 cross size
本小节,主要介绍一下容器属性及项目属性。通过本章节,相信你会加深对 Flex 布局理解。为了形象说明这些属性的含义,作者 Billow 尽可能在每个示例中做到图文并茂。
下表展示了容器的属性和取值。
属性 | 取值 | 说明 |
---|---|---|
display | flex | 定义一个 Flex 容器,弹性盒子 |
inline-flex | 定义一个内联元素为 Flex 容器 | |
flex-direction | row (默认) | 从左到右 |
row-reverse | 从右到左 | |
column | 从上到下 | |
column-reverse | 从下到上 | |
flex-wrap | nowrap (默认,不换行) wrap(换行) wrap-reverse(反向换行) | flex项目在一个轴线排不下情况,该如何换行。 |
flex-flow | <flex-direction> <flex-wrap> | flex-direction 与 flex-wrap 的缩写形式。 |
justify-content | flex-start(默认,左对齐) flex-end(右对齐) center(居中) space-between space-around | flex项目在主轴上的对齐方式。 |
align-items | flex-start flex-end center stretch baseline | 定义项目在交叉轴上对齐方式 |
align-content | flex-start flex-end center space-between space-around stetch | 定义多条线轴对齐方式,若只有一条线轴。 若仅有一条线轴,该属性无效。 |
- .container {
- flex-direction: row | row-reverse | column | column-reverse;
- }
flex-direction 属性,定义了在哪个方向上排列项目。flex-direction有四个取值,分别为:
取值 | 说明 |
row | 由左到右。(默认) |
row-reverse | 从右到左。 |
column | 从上到下。 |
column-reverse | 从下到上。 |
图2-1 容器定义 flex-direction 属性示例图
图2-1 完整代码:
- <!DOCTYPE html>
- <html>
- <head>
- <style>
- .flex-container-row {
- display: flex;
- flex-direction: row;
- }
-
- .flex-container-row-reverse {
- display: flex;
- flex-direction: row-reverse;
- }
-
- .flex-container-column {
- display: flex;
- flex-direction: column;
- }
-
- .flex-container-column-reverse {
- display: flex;
- flex-direction: column-reverse;
- }
-
- .flex-item {
- border:1px solid #fff;
- height:60px;
- width:60px;
- text-align:center;
- line-height:60px;
- background: #f66;
- color:white;
- }
-
- .flex-item.blue {
- border:1px solid #fff;
- background: #33f;
- }
- </style>
- </head>
-
- <body>
- <div class="flex-container-row">
- <div class="flex-item">1.刘邦</div>
- <div class="flex-item">2.吕雉</div>
- <div class="flex-item">3.项羽</div>
- <div class="flex-item">4.虞姬</div>
- </div>
-
- <div class="flex-container-row-reverse">
- <div class="flex-item blue">伯</div>
- <div class="flex-item blue">仲</div>
- <div class="flex-item blue">叔</div>
- <div class="flex-item blue">季</div>
- </div>
-
- <div class="flex-container-column">
- <div class="flex-item">金</div>
- <div class="flex-item">银</div>
- <div class="flex-item">铜</div>
- </div>
-
-
- <div class="flex-container-column-reverse">
- <div class="flex-item blue">苏洵</div>
- <div class="flex-item blue">苏轼</div>
- <div class="flex-item blue">苏辙</div>
- </div>
- </body>
-
- </html>
flex-wrap 定义了项目在轴线上的排列方式,在默认情况下,项目都排列在一条轴线上,不会换行,可以通过 flex-wrap 来定义换行的方式。
取值 | 说明 |
nowrap | 默认值,不换行 |
wrap | 项目沿着轴线方向排列,一行排不下后,换行排列。 |
wrap-reverse | 反向换行。例如:在主轴线上,第一行会在第二行的下放。 |
图2-2 容器定义 flex-wrap 示例
图2-2 完整代码:
- <!DOCTYPE html>
- <html>
- <head>
- <style>
- .flex-container-nowrap {
- display: flex;
- flex-wrap: nowrap;
- }
-
- .flex-container-wrap {
- display: flex;
- flex-wrap: wrap;
- margin-top:10px;
- }
-
- .flex-container-wrap-reverse {
- display: flex;
- flex-wrap: wrap-reverse;
- margin-top:10px;
- }
-
- .flex-item {
- border:1px solid #fff;
- height:60px;
- width:120px;
- text-align:center;
- line-height:60px;
- background: #f66;
- color:white;
- font-size:18px;
- }
-
- .flex-item.blue {
- border:1px solid #fff;
- background: #33f;
- }
-
- .flex-item.gray {
- border:1px solid #fff;
- background: #666;
- }
-
- .flex-item.circle {
- border-radius: 10%;
- }
-
- h3 {
- color: #666;
- }
- </style>
- </head>
-
- <body>
- <h3>nowrap</h3>
- <div class="flex-container-nowrap">
- <div class="flex-item">1</div>
- <div class="flex-item">2</div>
- <div class="flex-item">3</div>
- <div class="flex-item">4</div>
- <div class="flex-item">5</div>
- <div class="flex-item">6</div>
- <div class="flex-item">7</div>
- <div class="flex-item">8</div>
- </div>
-
- <h3>wrap</h3>
- <div class="flex-container-wrap">
- <div class="flex-item gray">1</div>
- <div class="flex-item gray">2</div>
- <div class="flex-item gray">3</div>
- <div class="flex-item gray">4</div>
- <div class="flex-item gray">5</div>
- <div class="flex-item gray">6</div>
- <div class="flex-item gray">7</div>
- <div class="flex-item gray">8</div>
- </div>
-
- <h3>wrap-reverse</h3>
- <div class="flex-container-wrap-reverse">
- <div class="flex-item blue circle">1</div>
- <div class="flex-item blue circle">2</div>
- <div class="flex-item blue circle">3</div>
- <div class="flex-item blue circle">4</div>
- <div class="flex-item blue circle">5</div>
- <div class="flex-item blue circle">6</div>
- <div class="flex-item blue circle">7</div>
- <div class="flex-item blue circle">8</div>
- </div>
- </body>
- </html>
值得注意的是,当我们将 flex-wrap 设置为 nowrap 后,并将每一个项目的宽度设置为 120px ,但是,但主轴宽度无法容纳所有项目后,项目的实际宽度会被收缩,在flex项目属性中,我们会详细解释。
2.1.3 flex-flow
flex-flow 是 flex-direction 与 flex-wrap 的缩写形式。
语法:flex-flow: <flex-direction> <flex-wrap>
例子:
flex-flow: row nowrap (默认值,项目沿着主轴排列,不换行。)
flex-flow: column wrap-reverse(项目沿着交叉轴排列,反向换行)
2.1.4 justify-content
justify-content 定义了项目在主轴上的对齐方式。共有5个取值,如下表所示。
取值 | 说明 |
flex-start | 左对齐 |
flex-end | 右对齐 |
center | 居中 |
space-between | 两端对齐,项目间隔相等 |
space-around | 项目间隔相等,两端也有间隔。 |
图2-3 容器定义 justify-content 示例
下图很好的解释了 space-between 与 space-around 的区别,space-between 会使项目两端对齐,并且项目之间的间距相同。space-around 同样会是的项目间距相同,不同之处是与两端也会有间距。
可以看出 space-around 项目与项目之间的距离是两端间距的2倍。你可以理解为:margin-left、margn-right 设置了相同的值。
图2-4 space-between 与 space-around 的区别
图2-3完整代码:
- <!DOCTYPE html>
- <html>
- <head>
- <style>
-
- body {
- padding:0;
- margin:0;
- }
-
- .flex-container-flex-start {
- display: flex;
- justify-content: flex-start;
- }
-
- .flex-container-flex-end {
- display: flex;
- justify-content: flex-end;
- }
-
- .flex-container-center {
- display: flex;
- justify-content: center;
-
- }
-
- .flex-container-space-between {
- display: flex;
- justify-content: space-between;
- }
-
- .flex-container-space-around {
- display: flex;
- justify-content: space-around;
- }
-
- .flex-item {
- border:1px solid #fff;
- height:60px;
- width:120px;
- text-align:center;
- line-height:60px;
- background: #f66;
- color:white;
- font-size:18px;
- }
-
- .flex-item.blue { background: #33f; }
- .flex-item.gray { background: #666; }
- .flex-item.purple { background: #f6f; }
- .flex-item.brown { background: #9e5b03; }
- .flex-item.circle {
- border-radius: 10%;
- }
-
- h3 {
- color: #666;
- margin-top:10p;
- border: 1px dashed #dcdcdc;
- }
- </style>
- </head>
-
- <body>
- <h3>flex-start</h3>
- <div class="flex-container-flex-start">
- <div class="flex-item">1</div>
- <div class="flex-item">2</div>
- <div class="flex-item">3</div>
- <div class="flex-item">4</div>
- <div class="flex-item">5</div>
- <div class="flex-item">6</div>
- </div>
-
- <h3>flex-end</h3>
- <div class="flex-container-flex-end">
- <div class="flex-item gray">1</div>
- <div class="flex-item gray">2</div>
- <div class="flex-item gray">3</div>
- <div class="flex-item gray">4</div>
- <div class="flex-item gray">5</div>
- <div class="flex-item gray">6</div>
- </div>
-
- <h3>center</h3>
- <div class="flex-container-center">
- <div class="flex-item blue">1</div>
- <div class="flex-item blue">2</div>
- <div class="flex-item blue">3</div>
- <div class="flex-item blue">4</div>
- <div class="flex-item blue">5</div>
- <div class="flex-item blue">6</div>
- </div>
-
- <h3>space-between</h3>
- <div class="flex-container-space-between">
- <div class="flex-item purple">1</div>
- <div class="flex-item purple">2</div>
- <div class="flex-item purple">3</div>
- <div class="flex-item purple">4</div>
- <div class="flex-item purple">5</div>
- <div class="flex-item purple">6</div>
- </div>
- <h3>space-around</h3>
- <div class="flex-container-space-around">
- <div class="flex-item brown">1</div>
- <div class="flex-item brown">2</div>
- <div class="flex-item brown">3</div>
- <div class="flex-item brown">4</div>
- <div class="flex-item brown">5</div>
- <div class="flex-item brown">6</div>
- </div>
-
- </body>
- </html>
2.1.5 align-items
align-items 属性,定义了项目在交叉轴上的对齐方式,有5个取值。
取值 | 说明 |
flex-start | 与交叉轴的起点对齐 |
flex-end | 与交叉轴的终点对齐 |
center | 在交叉轴上居中对齐 |
baseline | 以项目中第一行文字基线对齐 |
stretch | 在未设置高度情况下,将占满容器的高度 |
2.1.6 align-content
align-content 属性定义了多根主轴线在垂直方向上的对齐方式。
align-content 取值 | 说明 |
flex-start | 与交叉轴起点对齐 |
flex-end | 与交叉轴终点对齐 |
center | 在交叉轴上居中对齐 |
space-between | 与交叉轴两端对齐,轴线之间的间隔平均分布 |
space-around | 轴线之间的间隔平均分布,包括两端 |
stretch | 默认值,轴线占满交叉轴 |
项目属性 | 默认值 | 说明 |
order | 0 | 定义了项目的排列顺序。 |
flex-grow | 0 | 扩大因子,定义了项目的放大比例 |
flex-shrink | 1 | 收缩因子,定义了项目的缩小比例 |
flex-basic | auto | flex-basis属性定义了在分配多余空间之前,项目占据的主轴空间(main size)。 |
flex | 0 1 auto | flex-grow、flex-shrink、flex-basis的缩写形式 |
align-self | auto | align-self 属性允许单个项目有与其他项目不一样的对齐方式, 也就是说改属性可以覆盖父容器设置的 align-items 属性。 |
在继续讲解这些项目属性之前,我们先来了解一个非常重要的概念 — 剩余空间。
图 2-5 剩余空间
为了解释剩余空间,下面给出一个示例。如图2-5所示,我们将父容器的宽度设置为 800px,容器中3个项目宽度分别为100px、200px、300px。那么,剩余空间就是:
200px = 800px - (100px + 200px + 300px)
简言之, flex-grow、flex-shrink 和 flex-basis 都是围绕如何分配剩余空间展开的。
2.2.1 order
order 属性,定义了项目的排列顺序,数值越小越靠前。可以为0,也可以为负值。order的默认值为 0
.item { order: <integer> }
图2-6 order 属性示例
图2-6 完整代码
- <!DOCTYPE html>
- <html>
- <head>
- <style>
-
- .flex-container {
- display: flex;
- margin-top:5px;
- }
-
- .item {
- height:60px;
- width:60px;
- text-align:center;
- line-height:60px;
- background: #f66;
- color:white;
- font-size:18px;
- border-radius: 100px;
- }
-
- .item.red {background: #f66;}
- .item.blue { background: #66f; }
- .item.gray { background: #666; }
- .item.purple { background: #f6f; }
- .item.brown { background: #9e5b03; }
-
- h3 {
- color: #666;
- margin-top:10px;
- border-bottom: 1px dashed #dcdcdc;
- }
- </style>
- </head>
-
- <body>
- <h3>order</h3>
- <div class="flex-container">
- <div style="order:0" class="item red" >一</div>
- <div style="order:1" class="item blue">二</div>
- <div style="order:2" class="item gray" >三</div>
- <div style="order:3" class="item purple">四</div>
- <div style="order:4" class="item brown" >五</div>
- </div>
-
- <div class="flex-container">
- <div style="order:4" class="item red" >一</div>
- <div style="order:3" class="item blue">二</div>
- <div style="order:2" class="item gray" >三</div>
- <div style="order:1" class="item purple">四</div>
- <div style="order:0" class="item brown" >五</div>
- </div>
- </body>
- </html>
2.2.2 flex-grow
扩大因子,定义项目的放大比例 。
.item { flex-grow: <number> }
2.2.3 flex-shrink
收缩因子,定义了项目的缩小比例。
.item { flex-shrink: <number> }
图 2-7 flex-grow 与 flex-shrink 的使用
图2-7 完整代码
- <!DOCTYPE html>
- <html>
- <head>
- <style>
-
- .flex-container {
- display: flex;
- margin-top:1px;
- }
-
- .item {
- height:60px;
- width:60px;
- text-align:center;
- line-height:60px;
- background: #f66;
- color:white;
- font-size:18px;
- }
-
- .item.red {background: #f66;}
- .item.blue { background: #66f; }
- .item.gray { background: #666; }
- .item.purple { background: #f6f; }
- .item.brown { background: #9e5b03; }
-
- h3 {
- color: #666;
- margin-top:10px;
- border-bottom: 1px dashed #dcdcdc;
- }
- </style>
- </head>
-
- <body>
-
- <h3>flex-grow</h3>
- <div class="flex-container">
- <div style="flex-grow:0" class="item blue">0</div>
- <div style="flex-grow:1" class="item red" >1</div>
- <div style="flex-grow:2" class="item blue">2</div>
- <div style="flex-grow:3" class="item red" >3</div>
- <div style="flex-grow:4" class="item blue">4</div>
- <div style="flex-grow:5" class="item red" >5</div>
- </div>
- <div class="flex-container">
- <div style="flex-grow:0" class="item blue">0</div>
- <div style="flex-grow:1" class="item red" >1</div>
- <div style="flex-grow:0" class="item blue">0</div>
- </div>
-
- <h3>flex-shrink</h3>
- <div class="flex-container" style="width:600px;border:1px dotted #dcdcdc;">
- <div style="flex-shrink:0;width:100px;" class="item blue">100</div>
- <div style="flex-shrink:1;width:100px;" class="item red" >100</div>
- <div style="flex-shrink:2;width:100px;" class="item blue">100</div>
- </div>
-
- <div class="flex-container" style="width:600px;border:1px dotted #dcdcdc;">
- <div style="flex-shrink:0;width:300px;" class="item blue">300</div>
- <div style="flex-shrink:1;width:300px;" class="item red" >300</div>
- <div style="flex-shrink:1;width:300px;" class="item blue">300</div>
- </div>
-
- <div class="flex-container" style="width:600px;border:1px dotted #dcdcdc;">
- <div style="flex-shrink:0;width:300px;" class="item blue">300</div>
- <div style="flex-shrink:1;width:300px;" class="item red" >300</div>
- <div style="flex-shrink:5;width:300px;" class="item blue">300</div>
- </div>
- </body>
- </html>
2.2.4 flex-basis
flex-basis 属性定义了在分配多余空间之前,项目占据主轴空间。默认值为:auto,即项目本来大小。
理解这段话的重点两个字就是 "之前"。
我们将3个 item 宽度分别设置为 100px、200px、300px,并且将第3个项目的 flex-basis 设置为 400px。可以看出,效果如下图第2行所示。
图2-8 加了 flex-basis 后的剩余空间
图2-8 完整代码:
- <!DOCTYPE html>
- <html>
- <head>
- <style>
-
- .flex-container {
- display: flex;
- width: 800px;
- border: 1px solid red;
- margin-top:5px;
- }
-
- .item {
- width:60px;
- text-align:center;
- line-height:60px;
- color:white;
- font-size:18px;
- border:1px solid #fff;
-
- }
-
- .item.red {background: #f66;}
- .item.blue { background: #66f; }
- .item.gray { background: #666; }
- </style>
- </head>
-
- <body>
- <div class="flex-container">
- <div class="item red" style="width:100px">100px</div>
- <div class="item blue" style="width:200px">200px</div>
- <div class="item gray" style="width:300px;">300px</div>
- </div>
-
- <div class="flex-container">
- <div class="item red" style="width:100px">100px</div>
- <div class="item blue" style="width:200px">200px</div>
- <div class="item gray" style="width:300px;flex-basis:400px;">300px/400px</div>
- </div>
- </body>
- </html>
2.2.5 flex
flex 为 flex-grow、flex-shrink、flex-basis 的缩写形式。
flex: none | [ <'flex-grow'> <'flex-shrink'>? || <'flex-basis'> ]
默认值为: 0 1 auto
另外,改属性有两个快捷值:
flex: auto 相当于 flex: 1 1 auto
flex: none 相当于 flex: 0 0 auto
2.2.6 align-self
align-self 属性允许单个项目有与其他项目不一样的对齐方式。也就是说改属性可以覆盖父容器设置的 align-items 属性。
取值 | 说明 |
auto | 继承父元素的 align-items 属性 |
flex-start | 与交叉轴的起点对齐 |
flex-end | 与交叉轴的终点对齐 |
center | 在交叉轴上居中对齐 |
baseline | 以项目中第一行文字基线对齐 |
stretch | 在未设置高度情况下,将占满容器的高度 |
为了加深对 Flex 布局的理解,下面给出几个综合性的例子。
在古代,在竹简写字一般都是从右向左、从上向下的顺序。下面我们用 Flex 布局来实现这样的例子。实现从右到左,从上到下书写春联。
图3-1 春联
图3-1 春联完整代码
- <!DOCTYPE html>
- <html>
- <head>
- <style>
-
- /*定义一个Flex容器*/
- #container {
- display: flex;
- flex-direction:column;
- flex-wrap: wrap-reverse;
- align-content: flex-start;
- height: 700px;
- font-family: LiSu;
- background: #f33;
- }
-
- /*每一个字的样式*/
- .word {
- height: 100px;
- width: 100px;
- line-height: 100px;
- font-size: 50px;
- text-align:center;
- background: #f33;
- border-left: 1px solid white;
- color:black;
- }
- </style>
- </head>
-
- <body>
- <div id="container"></div>
- </body>
-
- <script>
- var innerHtml = "";
- var p = "一年好运随春到"
- + "四季彩云滚滚来"
- + "一年四季春常在"
- + "万紫千红永开花";
-
- for(var i = 0;i < p.length;i++) {
- innerHtml += "<div class='word'>" + p.charAt(i) + "</div>";
- }
- document.getElementById("container").innerHTML = innerHtml;
-
- </script>
- </html>
与 Flex 布局相关的显式代码仅4行:
- #container {
- display: flex; /*定义一个Flex容器*/
- flex-direction:column; /*每个项目(每个字)的顺序为从上到下。*/
- flex-wrap: wrap-reverse; /*反向换行,即:第二行在第一行的左面。*/
- align-content: flex-start; /*多条轴线,靠右对其。*/
- height: 700px;
- font-family: LiSu;
- background: #f33;
- }
当然,我们也可以用 flex-flow 实现:
- #container {
- display: flex; /*定义一个Flex容器*/
- /* flex-direction:column; */ /*每个项目(每个字)的顺序为从上到下。*/
- /* flex-wrap: wrap-reverse; */ /*反向换行,即:第二行在第一行的左面。*/
- flex-flow: column wrap-reverse;
- align-content: flex-start; /*多条轴线,靠右对其。*/
- height: 700px;
- font-family: LiSu;
- background: #f33;
- }
手工码字,虽然已经检查多遍,难免有不足之处,发现有错误之处,请多多指教。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。