1. 伸缩盒模型简介
· 2009年,W3C提出了一种新的盒子模型------Flexible Box(伸缩盒模型。又称:弹性盒子)。
· 它可以轻松的控制:元素分布方式、元素对齐方式、元素视觉顺序......
· 截止目前:除了在部分IE浏览器不支持,其他浏览器均已全部支持。
· 伸缩盒模型的出现,逐渐演变出了一套新的布局方案------flex布局。
PS:
1. 传统布局是指:基于传统盒状模型,主要靠:display属性+position属性+float属性。
2. flex布局目前在移动端应用比较广泛,因为传统布局不能很好的呈现在移动设备上。
2. 容器与项目
伸缩容器:开启了flex的元素,就是伸缩容器。
1. 给元素设置:display:flex或display:inline-flex,该元素就变为了伸缩容器。
2. display:inline-flex很少使用,因为可以给多个伸缩容器的父容器,也设置为伸缩容器。
3. 一个元素可以同时是:伸缩容器、伸缩项目。
伸缩项目:伸缩容器所有子元素自动成为了:伸缩项目。
1. 仅伸缩容器的子元素成为了伸缩项目,孙子元素、重孙子元素等后代不是伸缩项目。
2. 无论原来是哪种元素(块、行内块、行内),一旦成为了伸缩项目,全都会"块状化"。
<div class="outer">
<div class="inner">1</div>
<div class="inner">2</div>
<div class="inner inner3">
<div>a</div>
<div>b</div>
<div>c</div>
</div>
</div>
<!-- <div class="outer">
<div class="inner">1</div>
<div class="inner">2</div>
<div class="inner inner3">
<div>a</div>
<div>b</div>
<div>c</div>
</div>
</div> -->
body{
display: flex;
}
.outer{
width: 1000px;
/* width: 600px; */
height: 600px;
background-color: #888;
/* 将该元素变为了伸缩容器(开启了flex布局) */
display: flex;
/* display: inline-flex; */
}
.inner{
width: 200px;
height:200px;
background-color: skyblue;
border: 1px solid black;
box-sizing: border-box;
/* float:left; */
}
.inner3{
display: flex;
}
3. 主轴方向
主轴与侧轴:
主轴:伸缩项目沿着主轴排列,主轴默认是水平方向,默认方向是:从左到右(左边是起点,右边是终点)。
侧轴:与主轴垂直的就是侧轴,侧轴默认是垂直的,默认方向是:从上到下(上边是起点,下边是终点)。
主轴方向:
属性名:flex-direction
常用值如下:
1. row:主轴方向水平从左到右------默认值。
2. row-reverse:主轴方向水平从右到左。
3. column:主轴方向垂直从上到下。
4. column-reverse:主轴方向垂直从下到上。
PS:
改变了主轴的方向,侧轴方向也随之改变。
<div class="outer">
<div class="inner">1</div>
<div class="inner">2</div>
<div class="inner">3</div>
</div>
.outer{
width: 1000px;
height: 600px;
background-color: #888;
margin: 0 auto;
/* 调整主轴方向 水平从左到右,默认值*/
flex-direction: row;
/* 调整主轴方向 水平从右到左 */
flex-direction: row-reverse;
/* 调整主轴方向 垂直从上到下 */
flex-direction: column;
/* 调整主轴方向 垂直从下到上 */
flex-direction: column-reverse;
display: flex;
}
.inner{
width: 200px;
height:200px;
background-color: skyblue;
border: 1px solid black;
box-sizing: border-box;
}
4. 主轴换行方式
属性名:flex-wrap
常用值如下:
1. nowrap:默认值,不换行。
2. wrap:自动换行,伸缩容器不够自动换行。
3. wrap-reverse:反向换行。
<div class="outer">
<div class="inner">1</div>
<div class="inner">2</div>
<div class="inner">3</div>
<div class="inner">4</div>
<div class="inner">5</div>
<div class="inner">6</div>
<div class="inner">7</div>
<div class="inner">8</div>
<div class="inner">9</div>
<div class="inner">10</div>
<div class="inner">11</div>
<!-- <div class="inner">12</div>
<div class="inner">13</div>
<div class="inner">14</div>
<div class="inner">15</div>
<div class="inner">16</div> -->
</div>
.outer{
width: 1000px;
height: 600px;
background-color: #888;
margin: 0 auto;
display: flex;
/* 主轴换行方式 换行*/
flex-wrap: wrap;
/* flex-wrap: wrap-reverse;反向换行 */
/* flex-wrap: nowrap; 不换行,默认值*/
}
.inner{
width: 200px;
height:200px;
background-color: skyblue;
border: 1px solid black;
box-sizing: border-box;
}
PS:flex-flow
flex-flow是一个复合属性,复合了flex-direction和flex-wrap两个属性。值没有顺序要求。例如:flex-flow:row wrap;。
5. 主轴对齐方式
<div class="outer">
<div class="inner">1</div>
<div class="inner">2</div>
<div class="inner">3</div>
<div class="inner">4</div>
<!-- <div class="inner">5</div>
<div class="inner">6</div>
<div class="inner">7</div> -->
</div>
.outer{
width: 1000px;
height: 600px;
background-color: #888;
margin: 0 auto;
display: flex;
/* flex-wrap: wrap; */
flex-direction: row;
/* 主轴的对齐方式:主轴的起始位置*/
justify-content: flex-start;
/* 主轴的对齐方式:主轴的结束位置 */
justify-content: flex-end;
/* 主轴的对齐方式:主轴居中对齐 */
justify-content: center;
/* 主轴的对齐方式:项目均匀分布在一行中,项目与项目之间的距离,是项目距离边缘的二倍 */
justify-content: space-around;
/* 主轴的对齐方式:主轴两端对齐*/
/* 项目均匀分布在一行中,项目与项目之间的距离是相等的,项目距离边缘没有距离 */
/* 常用 */
justify-content: space-between;
/* 主轴的对齐方式:项目均匀分布在一行中*/
justify-content: space-evenly;
}
.inner{
width: 200px;
height:200px;
background-color: skyblue;
border: 1px solid black;
box-sizing: border-box;
}
6. 侧轴对齐方式
只有一行的情况:
所需属性:align-items
常用值如下:
1. flex-start:侧轴的起点对齐
2. flex-end:侧轴的终点对齐
3. center:侧轴的中点对齐
4. baseline:伸缩项目的第一行文字的基线对齐
5. stretch:如果伸缩项目未设置高度,将占满整个容器的高度。------(默认值)
<div class="outer">
<div class="inner">1x</div>
<div class="inner inner2">2x</div>
<div class="inner inner3">3x</div>
</div>
.outer{
width: 1000px;
height: 600px;
background-color: #888;
margin: 0 auto;
display: flex;
/* 侧轴对齐方式 侧轴的起始位置对齐*/
align-items: flex-start;
/* 侧轴对齐方式 侧轴的结束位置对齐*/
align-items: flex-end;
/* 侧轴对齐方式 侧轴的结束位置对齐*/
align-items: center;
/* 侧轴对齐方式 侧轴的结束位置对齐*/
align-items: baseline;
/* 侧轴对齐方式 拉伸到整个父容器(前提:伸缩项目不能给高度),默认*/
align-items: stretch;
}
.inner{
width: 200px;
height:200px;
background-color: skyblue;
border: 1px solid black;
box-sizing: border-box;
}
.inner2{
height: 300px;
font-size: 80px;
}
.inner3{
height: 100px;
}
多行的情况:
所需的属性:align-content
常用值如下:
1. flex-start:与侧轴的起点对齐
2. flex-end:与侧轴的终点对齐
3. center:与侧轴的中点对齐
4. space-between:与侧轴两端对齐,中间平均分布。
5. space-around:伸缩项目间的距离相等,比距边缘大一倍。
6. space-evenly:在侧轴上完全平分。
7. stretch:占满整个侧轴。------默认值。
<div class="outer">
<div class="inner">1</div>
<div class="inner inner2">2</div>
<div class="inner inner3">3</div>
<div class="inner">4</div>
<div class="inner">5</div>
<div class="inner">6</div>
<div class="inner">7</div>
<div class="inner">8</div>
<div class="inner">9</div>
<div class="inner">10</div>
<div class="inner">11</div>
</div>
.outer{
width: 1000px;
height: 900px;
background-color: #888;
margin: 0 auto;
display: flex;
flex-wrap: wrap;
/* 侧轴对齐方式 多行 侧轴的起始位置对齐*/
align-content: flex-start;
/* 侧轴对齐方式 多行 侧轴的结束位置对齐*/
align-content: flex-end;
/* 侧轴对齐方式 多行 侧轴的中间位置对齐*/
align-content: center;
/* 侧轴对齐方式 多行 伸缩项目之间的距离是相等的,且是边缘距离的2倍*/
align-content: space-around;
/* 侧轴对齐方式 多行 伸缩项目之间的距离是相等的,且边缘无距离*/
align-content: space-between;
/* 侧轴对齐方式 多行 伸缩项目之间的距离是相等的*/
align-content: space-evenly;
/* 侧轴对齐方式 多行 拉伸 默认值*/
align-content: stretch;
}
.inner{
width: 200px;
height:200px;
background-color: skyblue;
border: 1px solid black;
box-sizing: border-box;
}
.inner2{
height: 300px;
}
.inner3{
height: 100px;
}
元素的水平垂直居中:
<div class="outer">
<div class="inner"></div>
</div>
.outer{
width: 400px;
height: 400px;
background-color: #888;
display: flex;
/* 方案一 */
/* justify-content: center;
align-items: center; */
}
.inner{
width: 100px;
height:100px;
background-color: skyblue;
/* 方案二 */
margin: auto;
}
7. 基准的长度
flex-basis
概念:flex-basis设置的是主轴方向的基准长度,会让宽度或高度失效。
备注:主轴横向:宽度失效;主轴纵向:高度失效。
作用:浏览器根据这个属性设置的值。计算主轴上是否有多余空间,计算主轴上是否有多余空间,默认值auto,即:伸缩项目的宽或高。
<div class="outer">
<div class="inner">1</div>
<div class="inner inner2">2</div>
<div class="inner">3</div>
</div>
.outer{
width: 1000px;
height: 900px;
background-color: #888;
margin: 0 auto;
display: flex;
flex-wrap: wrap;
justify-content: flex-start;
flex-direction: column;
}
.inner{
width: 200px;
height:200px;
background-color: skyblue;
border: 1px solid black;
box-sizing: border-box;
}
.inner2{
/* 设置伸缩项目在主轴上的基准长度,若主轴是横向的,宽失效,若主轴是纵向的,高失效 */
flex-basis: 300px;
}
8. 伸缩性
flex-grow(伸)
概念:flex-grow定义伸缩项目的放大比例,默认为0,即:纵使主轴存在剩余空间,也不拉伸(放大)。
规则:1. 若所有伸缩项目的flex-grow值都为1,则:它们将等分剩余空间(如果有空间的话)。
2. 若三个伸缩项目的flex-grow值分别为1、2、3,则:分别瓜分到:1/6、2/6、3/6的空间。
<div class="outer">
<div class="inner inner1">1</div>
<div class="inner inner2">2</div>
<div class="inner inner3">3</div>
</div>
.outer{
width: 1000px;
height: 1000px;
background-color: gray;
margin: 0 auto;
display: flex;
flex-direction:row;
justify-content: flex-start;
}
.inner{
width: 200px;
height: 200px;
background-color: skyblue;
border: 1px solid black;
box-sizing: border-box;
flex-grow: 1;
}
.inner1{
flex-grow:1;
}
.inner2{
width: 300px;
flex-grow: 2;
}
.inner3{
flex-grow: 3;
}
flex-shrink(缩)
概念:flex-shrink定义了项目的压缩比例,默认为1,即:如果空间不足,该项目将会缩小。
收缩项目的计算,略微复杂一点,如:
三个收缩项目,宽度分别为:200px、300px、200px,它们的 flex-shrink值分别为:1、2、3
1. 计算分母:(200*1)+(300*2)+(200*3)=1400
2. 计算比例:200*1/1400;300*2/1400;200*3/1400
3. 计算最终收缩大小:比例值*(它们的总宽度-目前容器的宽度)
<div class="outer">
<div class="inner inner1">
<div style="width: 50px;height: 50px;background-color: green;">1</div>
</div>
<div class="inner inner2">2</div>
<div class="inner inner3">3</div>
</div>
.outer{
width: 400px;
height: 1000px;
background-color: gray;
margin: 0 auto;
display: flex;
flex-direction:row;
justify-content: flex-start;
align-content: flex-start;
/* flex-wrap: wrap; */
flex-shrink: 1;
}
.inner{
width: 200px;
height: 200px;
background-color: skyblue;
flex-grow: 1;
}
.inner1{
/* flex-grow:1; */
flex-shrink: 1;
}
.inner2{
width: 300px;
/* flex-grow: 2; */
flex-shrink: 2;
}
.inner3{
/* flex-grow: 3; */
flex-shrink: 3;
}
9. flex复合属性
flex是复合属性,复合了:flex-grow、flex-shrink、flex-basis三个属性,默认值为0 1 auto。
如果写flex:1 1 auto,可简写为:flex:auto。
如果写flex:1 1 0,可简写为:flex:1。
如果写flex:0 0 auto,可简写为:flex:none。
如果写flex:0 1 auto,可简写为:flex:0 auto------即flex初始值。
<div class="outer">
<div class="inner inner1">1</div>
<div class="inner inner2">2</div>
<div class="inner inner3">3</div>
</div>
.outer{
width: 1000px;
height: 1000px;
background-color: gray;
margin: 0 auto;
display: flex;
flex-direction:row;
justify-content: flex-start;
align-content: flex-start;
/* flex-wrap: wrap; */
/* flex-shrink: 1;
flex-grow: 1;
flex-basis:100px; */
/* 可以拉伸,可以压缩,不设置基准长度,可简写为flex:auto */
/* flex:1 1 auto; */
/* 可以拉伸,可以压缩,设置基准长度为0,可简写为flex:1 */
/* flex:1 1 0; */
/* 不可以拉伸,不可以压缩,不设置基准长度,可简写为flex:none */
/* flex:0 0 auto; */
/* 不可以拉伸,可以压缩,不设置基准长度,可简写为flex:0 auto */
/* flex:0 1 auto; */
}
.inner{
width: 200px;
height: 200px;
background-color: skyblue;
flex-grow: 1;
box-sizing: border-box;
border: 1px solid black;
}
10. 排序与单独对齐
项目排序:order属性定义项目的排列顺序,数值越小,排列月靠前,默认为0。
单独对齐:
1. 通过align-self属性,可以单独调整某个伸缩项目的对齐方式。
2. 默认值为auto,表示继承父元素的align-items属性。
<div class="outer">
<div class="inner inner1">1</div>
<div class="inner inner2">2</div>
<div class="inner inner3">3</div>
</div>
.outer{
width: 1000px;
height: 1000px;
background-color: gray;
margin: 0 auto;
display: flex;
flex-direction:row;
justify-content: flex-start;
align-content: flex-start;
flex:1;
}
.inner{
width: 200px;
height: 200px;
background-color: skyblue;
flex-grow: 1;
box-sizing: border-box;
border: 1px solid black;
}
/* .inner1{
order:3;
}
.inner2{
order:2;
}
.inner3{
order:1
} */
/* .inner2{
align-self: flex-end;
} */
</style>