界面布局 - Flexbox
前面介绍的 display 类型 block 和 inline , 属于该元素的 外部
显示类型
外部显示类型决定了元素作为一个整体 如何显示在界面上 (新开一行,还是跟随前面的元素)
接下来我们会介绍元素的内部显示类型,也就是该元素的内部子元素 怎么布局。
包括:内部子元素 为几行几列,子元素对齐,居左,局右等。
这些布局,以前主要通过CSS的 float
和 position
实现,但是它们有很多局限,很多布局实现起来很困难。
新的CSS规范推出了 grid - 网格布局
和 flexbox - 弹性盒子布局
,很多布局场景实现起来非常方便。
本章先学习 flexbox - 弹性盒子布局
(简称弹性布局)
基本概念
先看这段HTML
<head>
<style>
.wrapper{
display:flex;
gap: .5em;
flex-direction:row;
}
.wrapper > div {
border: 1px solid teal;
}
</style>
</head>
<body>
<div class="wrapper">
<div>1</div>
<div>2</div>
<div> 3
<br>3
<br>3
<br>3
</div>
<div>444</div>
<div>5</div>
<div>6</div>
<div>7</div>
<div>8888888888888</div>
<div>99999999999999999999999999999999999</div>
<div>aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa</div>
<div>bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb</div>
</div>
</body>
div.wrapper
的 display
值为 flex
,指定了
-
内部显示规则是 flexbox 布局
-
外部显示规则是 block
-
该元素本身是一个
容器
flexbox 容器 (container) 是整个布局的最外层包含元素
-
该元素的直接子元素是一个个
flex元素
gap
指定了 flex元素 的 间距
flex元素 的布局方向是由 容器的 flex-direction
定义的
flex-direction 定义的 也就是 主轴
方向
比如 flex-direction:row
表示主轴是 水平方向正向
什么是正向? 就是网页语言对应的文字书写方向,通常是从左到右
但是有的语言,比如阿拉伯文字正向就是从右到左。
主轴垂直的方向线,就是 从轴
,也有翻译为 交叉轴
的
主轴定义了 内部 flex元素 的 布局方向,
如果正向是从左到右, flex-direction:row
表示 子项元素 的布局方向是 依次从左到右
主轴由 flex-direction
定义,可以取4个值:
-
row
主轴是 横向正向(通常是从左到右)
-
row-reverse
主轴是 横向反向(通常是从右到左)
-
column
主轴是 纵向正向(通常是从上到下)
-
column-reverse
主轴是 纵向反向(通常是从下到上)
大家可以尝试一下,把上面的 flex-direction 依次改为这4个值,显示结果分别是什么
上面的HTML示例,可以发现:
如果有的 flex元素 的内容 宽度
比其它的宽, 只是这个 flex元素 自动拓宽。
但是,缺省情况下,如果有的 flex元素 的内容 高度
比其它的高,
整个行所有的 flex元素 自动扩展为同样高度。 结果就是所有的 flex元素 都保持和最高的 flex元素 一致。
如果要让各 flex元素 保持各自的高度,可以设置 align-items
对齐属性,这个后面会讲。
自动换行
上面的示例中,如果container 的宽度不足以存放 所有 flex元素 , 就会出现滚动条。
这样确保所有的 flex元素 都在一行。
如果,我们需要的效果是,超出 container 宽度后,自动换行,可以加上 flex-wrap: wrap
属性
{
.wrapper {
display: flex;
gap: .5em;
flex-direction: row;
flex-wrap: wrap
}
}
flex-direction 和 flex-wrap 属性如果需要一起指定,可以使用 flex-flow 来替代,如下
{
.wrapper {
display: flex;
gap: .5em;
flex-flow: row wrap;
}
}
flex元素 的属性
flex-basis
前面的例子中,一个 flex元素 的宽度是由其内容决定的。
如果一行放置了所有的 flex元素 还有剩余的空间,这些空间是没有使用的。
我们可以指定 flex元素 的 flex-basis
属性, 如果flex容器有剩余的空间, 这些元素可以分配剩余空间给这些 flex元素 ,最多到 flex-basis
指定的宽度。
比如
<div class="wrapper">
<div>1</div>
<div>2</div>
<div> 3
<br>3
<br>3
<br>3
</div>
<div>444</div>
<div style="flex-basis: 300px">5</div>
<div style="flex-basis: 200px">6</div>
<div style="flex-basis: 10px">777777777777777</div>
<div>8888888888888</div>
</div>
大家可以拖拽窗口的宽度,看看宽度元素宽度变化的比例。
flex-grow
我们可以通过 flex元素 的 flex-grow
属性指定,如果有剩余空间,这个元素可以分配到多少的比例。
比如
<div class="wrapper">
<div>1</div>
<div>2</div>
<div> 3
<br>3
<br>3
<br>3
</div>
<div>444</div>
<div style="flex-grow: 3">5</div>
<div style="flex-grow: 2">6</div>
<div style="flex-grow: 1">7</div>
<div>8888888888888</div>
</div>
div 5、div 6、div 7 就会分别拿走 多余空间的 3/6 、 2/6 、1/6
大家可以拖拽窗口的宽度,看看元素宽度变化的比例。
如果不设置,flex-grow
使用缺省值 0
flex-shrink
我们可以指定 flex元素 的 flex-shrink
属性,这个属性和 flex-grow
属性正好相反。
flex-shrink
指定如果 flex容器 空间 比所有 flex元素 空间总和小,这个元素空间缩减的比例。
比如
<div class="wrapper">
<div>1</div>
<div>2</div>
<div> 3
<br>3
<br>3
<br>3
</div>
<div>444</div>
<div>5</div>
<div>6</div>
<div style="flex-shrink: 1;flex-basis:300px">777777777777777</div>
<div style="flex-shrink: 3;flex-basis:300px">8888888888888</div>
</div>
大家可以拖拽窗口的宽度,看看元素宽度减小的比例。
当然,优先确保这些元素内容能够显示, flex元素 不会缩减到元素内容不够显示宽度的情况。
如果不设置,flex-shrink
使用缺省值 1
flex-grow、 flex-shrink、 flex-basis 3 个元素的指定,可以用 flex
一起指定,语法更简洁
{
flex-grow : 2;
flex-shrink: 1;
flex-basis:300px
}
等价于
{
flex : 2 1 300px
}
比如
<div class="wrapper">
<div>1</div>
<div>2</div>
<div> 3
<br>3
<br>3
<br>3
</div>
<div>444</div>
<div>5</div>
<div>6</div>
<div style="flex : 1 1 200px">777777777777777</div>
<div style="flex : 2 1 200px">8888888888888</div>
</div>
从轴对齐
下面这个示例
<head>
<style>
.wrapper{
display:flex;
gap: .5em;
flex-direction:row;
}
.wrapper > div {
border: 1px solid teal;
}
</style>
</head>
<body>
<div class="wrapper">
<div>1</div>
<div>2</div>
<div> 3
<br>3
<br>3
<br>3
</div>
<div>444</div>
<div>5</div>
<div>6</div>
</div>
</body>
缺省情况下,如果有的 flex元素 的内容 高度比其它的高, 整个行所有的 flex元素 自动扩展为同样高度。 结果就是所有的 flex元素 都保持和最高的 flex元素 一致。
这是 container元素的 align-items
这个属性决定的。
align-items
属性控制 从轴线
方向的 flex元素 的对齐。
它的缺省值为 stretch
,表示所有 flex元素 伸展到和 container 一样,
还可以把 align-items 的值设置为
-
flex-start
flex元素 和 container 的开始位置(从轴方向 起始位置)对齐
上例中就是上边对齐
-
flex-end
flex元素 和 container 的结束位置(从轴方向 结束位置)对齐
上例中就是下边对齐
-
center
flex元素 和 container 的中间位置(从轴方向 结束位置)对齐
主轴对齐
container元素的 justify-content
属性控制 主轴线
方向的 flex元素 的对齐。
比如下面的示例
<!DOCTYPE html>
<html>
<head>
<style>
.wrapper {
display: flex;
justify-content : flex-start;
gap: .5em;
border: 1px dashed red
}
.wrapper > div {
border: 1px solid teal;
}
</style>
</head>
<body>
<div class="wrapper">
<div>1</div>
<div>2</div>
<div> 3
<br>3
<br>3
<br>3
</div>
<div>444</div>
<div>5</div>
<div>6</div>
</div>
</body>
</html>
justify-content
属性的常见的取值为
-
flex-start
flex元素 和 container 的 主轴方向开始位置 对齐
上例中就是左边对齐
-
flex-end
flex元素 和 container 的 主轴方向结束位置 对齐
上例中就是右边对齐
-
center
flex元素 和 container 的 主轴方向中间位置 对齐
上例中就是中间对齐
-
space-between
flex元素 均匀分布在主轴上,它们的间距相同
第一个 flex元素 和 container 的 主轴方向开始位置 平齐
最后一个 flex元素 和 container 的 主轴方向结束位置 平齐
-
space-around
flex元素 均匀分布在主轴上,它们的间距相同
第一个 flex元素 和 container 的 主轴方向开始位置 的间距, 最后一个 flex元素 和 container 的 主轴方向结束位置 的间距 都是 flex元素 间距 的一半
-
space-evenly
flex元素 均匀分布在主轴上,它们的间距相同
第一个 flex元素 和 container 的 主轴方向开始位置 的间距, 最后一个 flex元素 和 container 的 主轴方向结束位置 的间距 都是 flex元素 间距 相同