flex 布局
Flex 布局是W3C 在2009年提出了一种新的网页布局方案,可以简便、完整、响应式地实现各种页面布局。Flex 是 Flexible Box 的缩写,意为"弹性布局",用来为盒状模型提供最大的灵活性。
想要学好 flex 布局,几个概念必须搞明白,什么是主轴、交叉轴,哪个属性是父容器属性,哪几个属性是子容器属性。 flex 布局 涉及到12个CSS属性,父容器,子容器属性各6个。使用flex布局后,float, clear, column,vertical-align 等等属性不再失效
1、flex 基本概念
1.1 两个轴
Flex 布局有一个隐式的坐标空间,水平方向有一条主轴(main-axis),垂直方向上有一条交叉轴(cross-axis);分别使用 justify-content
属性 和 align-items
属性来控制。
默认情况下,主轴的方向是从左向右的,交叉轴垂直于主轴。通过flex-direction
可以决定主轴的方向
- 交叉轴是由主轴决定的,主轴又是由flex-direction决定的。
- flex-direction属性设置在父容器上,这样子才可以生效
1.2 父子容器
<div class="box-wrap">
<div class="box">我是第1个盒子</div>
<div class="box">我是第2个盒子</div>
<div class="box">我是第3个盒子</div>
<div class="box">我是第4个盒子</div>
</div>
.box-wrap {
display: flex;
flex-direction: row;
.box {
background-color: lightcyan;
border: 1px solid lightgray;
}
}
给box-wrap
指定display: flex
,则box-wrap
就是父容器(container),box
就是子容器(item)
2、父容器属性
flex-direction – 设置主轴的方向
flex-direction
是用来设置主轴的方向,flex 支持按行排布和按列排布。按列排布时,主轴和交叉轴换了方向,但是 align-items 和 justify-content 控制的轴线不变,即 align-items
还是控制交叉轴,justify-content
控制主轴
一共可以取四个值:
flex-direction: row(默认值) | row-reverse | column | column-reverse
带有row的表示按行来排列,row-reverse表示倒着排,也就是所从右往左。带有column的表示按列来排列,column-reverse表示从下往上。
当使用 flex 按列排布,只需要设置:flex-direction: column
。此时,主轴就是垂直方向的,交叉轴就是水平方向。在水平方向上对齐变成了使用align-items
,垂直方向则用justify-content
。
justify-content – 控制主轴方向
justify-content
属性 是用来 控制主轴
Values:
justify-content: flex-start(默认) | center | flex-end | space-around | space-between | space-evenly ;
-
flex-start
:flex-start是默认值,如果是从左到右的文字阅读习惯(LTR),就是靠左对齐。 -
center
:水平方向居中 -
flex-end
:靠右对齐; -
space-between
:两端对齐,这种对齐方式是第一个和最后一个元素贴边,中间的元素平分剩余的空间: -
space-evenly
:分散对齐,所有的元素都平分空间: -
space-around
:左右两边的留白为平分空间的 1/2
align-items – 控制交叉轴方向
align-items
属性是用来控制控制垂直方向
Values:
align-items: stretch(默认) | flex-start | flex-end | space-around | space-between | space-evenly ;
-
stretch
:stretch
是align-items
的默认值,它会自动把子元素拉伸成容器的高度 -
flex-start
:子元素在交叉轴方向的起点对齐,可以看到子元素不再占满容器高度 -
center
:子元素在交叉轴方向居中对齐 -
flex-end
:子元素在交叉轴方向的终点对齐。 -
baseline
:基线对齐,如果子元素文字尺寸和行高不同,则子元素会按照文字的基线进行对齐:.flex2 { font-size: 24px; }
flex-wrap – 换行展示
flex-wrap用于控制子级项排列超出边界时是否换行展示;
values:
flex-wrap: wrap | nowrap | wrap-reverse
分别表示换行、不换行、换行并且反转行。
align-content
这个属性是定义子容器在交叉轴的排列方式,也就是对齐方式。
如果 flex 容器开启了折行,那么两行及以上的内容可以通过align-content
属性来控制各行之间在交叉轴上的排列规则,它的取值和 justify-content
基本相同,这里演示其中几个,还是使用之前三个元素的 flex 容器,每个容器宽度为 300px,超出后换行:
.flex {
display: flex;
flex-wrap: wrap;
}
.flex > * {
flex-basis: 300px;
}
flex-flow
flex-flow表示流动,即文档流,其实就是flex-direction和flex-wrap的复合写法
3、子容器属性
flex-grow – 设置扩展比例
flex-grow 这个属性用来指定 flex子元素放大比例
flex-shrink – 设置收缩比例
flex-shrink 定义了子元素的缩小比例
flex-basis – 设置基准大小
flex-basis 属性定义了在分配多余空间之前,子元素占据的主轴空间(main size)
flex – 放大,缩小,所占空间
flex 属性 flex-grow, flex-shrink 和 flex-basis的简写,默认值为0 1 auto
常用简化写法👇
- flex:1 —> flex:1 1 0%;
- flex:3 —> flex:3 1 0%;
- auto (1 1 auto) 和 none (0 0 auto)。
order – 设置排列顺序
order 属性是用来控制flex容器中flex子元素的排列顺序。
默认情况下flex子元素在flex容器的顺序是按flex子元素出现的顺序排列的。 属性值为数值,数值越小,排列越靠前,默认为0。
align-self
align-self属性允许单个项目有与其他项目不一样的对齐方式,可覆盖align-items属性。默认值为auto,表示继承父元素的align-items属性,如果没有父元素,则等同于stretch。
align-self属性 单独设置子容器如何沿交叉轴排列
- 每个子容器都可以单独定义沿交叉轴排列方式。
- 该属性的取值跟父容器中的align-items属性一致,如果两者相同的话,则以子容器
align-self
属性为主。
align-self
属性有6个值,除了auto,其他都与align-items属性完全一致。
align-self: auto | flex-start | flex-end | center | baseline | stretch;
4、flex常见布局
顶部导航
移动端TabBar
平均分配空间的栅格布局
<div class="row">
<div class="column">column1</div>
<div class="column">colum22</div>
<div class="column">colum322</div>
</div>
.row{
display:flex;
flex-wrap:wrap;
border:1px solid black;
}
.column{
list-style:none;
background:#ddd;
flex:1;
height:100px;
border:1px solid red;
}
圣杯布局
html代码:
<div class="container">
<main>main</main>
<aside>aside</aside>
<nav>nav</nav>
</div>
css代码:
.container{
display:flex;
height:100vh;
}
aside{
width:50px;
background:#ccc;
}
main{
flex-grow:1;
background:#def;
}
nav{
width:80px;
background:#ccc;
order:-1;
}
Sticky Header
还是上-中-下布局,区别是 header 固定在顶部,不会随着页面滚动。
demo 4 - Sticky Header
<body>
<header>HEADER</header>
<article>CONTENT</article>
<footer>FOOTER</footer>
</body>
body {
min-height: 100vh;
display: flex;
flex-direction: column;
padding-top: 60px;
}
header {
height: 60px;
position: fixed;
top: 0;
left: 0;
right: 0;
padding: 0;
}
article {
flex: auto;
height: 1000px;
}
Sticky Sidebar
左侧 sidebar 固定在左侧且与视窗同高,当内容超出视窗高度时,在 sidebar 内部出现滚动条。左右两侧滚动条互相独立。
demo 5 - Sticky Sidebar
<body>
<aside>
ASIDE
<p>item</p>
<p>item</p>
<!-- many items -->
<p>item</p>
</aside>
<div class="content">
<header>HEADER</header>
<article>CONTENT</article>
<footer>FOOTER</footer>
</div>
</body>复制代码
body {
height: 100vh;
display: flex;
}
aside {
flex: none;
width: 200px;
overflow-y: auto;
display: block;
}
.content {
flex: auto;
display: flex;
flex-direction: column;
overflow-y: auto;
}
.content article {
flex: auto;
}
参考:
评论区