1 传统布局与flex布局
传统布局(以之前所学的PC端布局为例)
- 兼容性好
- 布局繁琐
- 局限性,不可以在移动端很好的布局
flex弹性布局 - 操作方便简单,移动端应用广泛
- PC端浏览器支持情况较差
- IE11或更低版本,不支持或仅部分支持
建议 - 如果是PC端页面布局,采用传统布局
- 如果是移动端或者不考虑兼容性问题的PC端布局,采用flex弹性布局
2 布局原理
flex用来为盒状模型提供最大的灵活性,任何一个容器都可以指定为flex布局。
- 当为父盒子设置为flex布局之后,子元素的float、clear、vertical-align属性将失效。(不需要浮动、清除浮动、盒子垂直居中,因为flex都可以代替这些功能)
- 伸缩布局=弹性布局=伸缩盒布局=弹性盒布局=flex布局
采用flex布局的元素称为flex容器,简称容器。它所有子元素自动成为容器成员,称为flex项目,简称项目。
- 体验中div就是flex父容器
- 体验中span就是子容器flex项目
- 子容器可以横向排列也可以纵向排列
总结flex布局原理:
就是通过给父盒子添加flex属性,来控制子盒子的位置和排列方式。
3 父项常见属性
3.1 flex-direction设置主轴的方向
flex-direction属性决定主轴的方向(即项目的排列方向)
注意:主轴和侧轴是会变化的,就看flex-direction设置谁为主轴,剩下的就是侧轴,我们的子元素是根据主轴来排列的。
flex-direction的属性值:
- row(默认值从左到右)
- row-reverse(从右到左)
- column(从上到下)
- column-reverse(从下到上)
<body>
<div>
<span>1</span>
<span>2</span>
<span>3</span>
</div>
</body>
<style>
div {
/* 给父亲添加flex属性 */
display: flex;
/* 添加flex之后,行内元素也有宽高;*/
width: 500px;
height: 200px;
background-color: pink;
/* 默认沿着x轴排列 */
/* flex-direction: row; 默认值 */
flex-direction: row-reverse;
/* flex-direction: column; */
/* flex-direction: column-reverse; */
}
div span {
width: 100px;
height: 50px;
background-color: skyblue;
margin: 2px 10px;
}
</style>
- flex-direction: row;
- flex-direction: row-reverse;
- flex-direction: column;
- flex-direction: column-reverse;
3.2 justify-content设置主轴的子元素对齐方式
justify-content属性定义了项目在主轴上的对齐方式;注意:使用这个属性之前要确定好主轴是哪一个。
- flex-start:头对齐(默认值)
- flex-end:尾对齐
- center:在主轴居中对齐,如果主轴是x轴则水平居中
- space-around:平分剩余空间
- space-between:先两边贴边再平分剩余空间(重要)
<body>
<div>
<span>1</span>
<span>2</span>
<span>3</span>
<span>4</span>
</div>
</body>
<style>
div {
/* 给父亲添加flex属性 */
display: flex;
/* 添加flex之后,行内元素也有宽高;*/
width: 800px;
height: 200px;
background-color: pink;
/* 主轴默认是x轴 */
/* 1. 左对齐 */
/* justify-content: flex-start; */
/* 2. 右对齐 (子盒子顺序不变)*/
/* justify-content: flex-end; */
/* 3. 居中对齐 */
/* justify-content: center; */
/* 4. 平分剩余空间 此时对span设置的左右外边距会失效*/
/* justify-content: space-around; */
/* 5. 先两边贴边再平分所有空间 span如果设置了左右外边距,则两端盒子的外边距会保留*/
justify-content: space-between;
}
div span {
width: 100px;
height: 50px;
background-color: skyblue;
margin: 2px 10px;
}
</style>
- justify-content: flex-start;左对齐
- justify-content: flex-end; 右对齐 (子盒子顺序不变)
- justify-content: center;居中对齐
- justify-content: space-around;平分剩余空间 此时对span设置的左右外边距会失效
- justify-content: space-between;先两边贴边再平分所有空间 span如果设置了左右外边距,则两端盒子的外边距会保留
3.3 flex-wrap设置主轴的子元素是否换行
默认情况下,项目都排在一条线(轴线)上。flex-wrap属性定义,flex布局默认是不换行的。
- nowrap:默认值,不换行
- wrap:换行
<body>
<div>
<span>1</span>
<span>2</span>
<span>3</span>
<span>4</span>
<span>5</span>
</div>
</body>
<style>
div {
/* 给父亲添加flex属性 */
display: flex;
/* 添加flex之后,行内元素也有宽高;*/
width: 500px;
height: 200px;
background-color: pink;
/* flex布局中,默认的子元素是不换行的,如果装不开,会缩小子元素宽度,放到父元素里面 */
/* 1.默认值 默认不换行 */
flex-wrap: nowrap;
/* 2. 换行 */
/* flex-wrap: wrap; */
}
div span {
width: 150px;
height: 100px;
background-color: skyblue;
margin: 2px 10px;
}
</style>
- flex-wrap: nowrap;默认值 默认不换行
- flex-wrap: wrap;放不下就换行
3.4 align-items设置侧轴上的子元素对齐方式(单行)
该属性是控制子项在侧轴(默认是y轴)上的排列方式,在子项为单行的时候使用。
- flex-start:头对齐
- fllex-end:尾对齐
- center:挤在一起(垂直居中)
- stretch:拉伸
center:挤在一起(垂直居中)举例如下
<body>
<div>
<span>1</span>
<span>2</span>
<span>3</span>
</div>
</body>
<style>
div {
/* 给父亲添加flex属性 */
display: flex;
/* 添加flex之后,行内元素也有宽高;*/
width: 800px;
height: 200px;
background-color: pink;
/* 沿着主轴(x轴) 水平居中对齐 */
justify-content: center;
/* 沿着侧轴(y轴) 垂直居中 */
align-items: center;
}
div span {
width: 150px;
height: 100px;
background-color: skyblue;
color: #fff;
margin: 10px;
}
</style>
对于stretch:拉伸,举例如下
<body>
<div>
<span>1</span>
<span>2</span>
<span>3</span>
</div>
</body>
<style>
div {
/* 给父亲添加flex属性 */
display: flex;
/* 添加flex之后,行内元素也有宽高;*/
width: 800px;
height: 200px;
background-color: pink;
/* 沿着主轴(x轴) 水平居中对齐 */
justify-content: center;
/* 沿着侧轴(y轴) 拉伸 */
align-items: stretch;
}
div span {
width: 150px;
/* height: 100px; 使用stretch的时候要将子项的height取消,否则无法拉伸 */
background-color: skyblue;
color: #fff;
margin: 10px;
}
</style>
3.5 align-content设置侧轴上的子元素排列方式(多行)
align-items只适用于单行,就像让文字垂直居中line-height=height也是只适用于单行,所以出现了align-content用于设置多行。
align-content设置子项在侧轴上的排列方式,且只可以用于子项出现换行的情况(多行),在单行下是没有效果的。
- flex-start:头对齐
- flex-end:尾对齐
- center:在侧轴中间显示
- space-around:子项在侧轴平分剩余空间
- space-between:子项在侧轴先分布在两头,再平分剩余空间
- stretch:设置子项元素高度平分父元素高度(设置该属性的时候子项不可以给高度)
<body>
<div>
<span>1</span>
<span>2</span>
<span>3</span>
<span>4</span>
<span>5</span>
<span>6</span>
</div>
</body>
<style>
div {
/* 给父亲添加flex属性 */
display: flex;
/* 添加flex之后,行内元素也有宽高;*/
width: 800px;
height: 250px;
background-color: pink;
/* 换行 */
flex-wrap: wrap;
/* 因为有了换行,此时我们侧轴上控制子元素的对齐方式适用的是align-content */
/* 1.错误 两行直接空出较大距离 */
/* align-items: flex-start; */
/* 2. 正确 行与行之间隔着的仅仅是自己设定的margin */
/* align-content: flex-start; */
/* 3. 错误 */
/* align-items: center; */
/* 4. 正确 两行的盒子整体都居中了 */
/* align-content: center; */
/* 5. space-between */
/* align-content: space-between; */
/* 6. space-around */
/* align-content: space-around; */
/* 7.子项平分父盒子的高度 设置该属性的时候,子项的高度应该注释掉 */
align-content: stretch;
}
div span {
width: 150px;
/* height: 50px; */
background-color: skyblue;
color: #fff;
margin: 10px;
}
</style>
- 1 align-items: flex-start;错误 两行直接空出较大距离
- 2 align-content: flex-start;正确 行与行之间隔着的仅仅是自己设定的margin
- 3 align-items: center;错误
- 4 align-content: center;正确 两行的盒子整体都居中了
- 5 space-between
- 6 space-around
- 7 align-content: stretch;子项平分父盒子的高度 设置该属性的时候,子项的高度应该注释掉
align-items和align-content区别
- align-items适用于单行情况下,只有上对齐、下对齐、居中和拉伸
- align-content适应于换行(多行)的情况(单行情况下无效)可以设置上对其、下对齐、居中、拉伸、平均分配剩余空间等属性。
- 总结就是单行找align-items多行找align-content
- 关键看“行数”而不是flex-wrap: wrap;
3.6 flex-flow是flex-direction和flex-wrap属性的复合属性
/* 设置主轴方向 */
/* flex-direction: column; */
/* 是否换行 */
/* flex-wrap: wrap; */
/* 设置主轴方向和是否换行可以简写如下 */
flex-flow: column wrap;
4. flex布局子项常见属性
- flex子项占的份数
- align-self控制子项在自己侧轴的排列方式
- order属性定义子项的排列顺序(前后顺序)
4.1 flex属性
flex属性定义子项分配“剩余”空间,用flex来表示占有多少份数,flex默认值是1
- 利用flex来实现两侧盒子固定,中间盒子自适应
<body>
<section>
<div></div>
<div></div>
<div></div>
</section>
</body>
<style>
section {
display: flex;
width: 60%;
height: 150px;
background-color: pink;
margin: 0 auto;
}
section div:nth-child(1) {
width: 100px;
height: 150px;
background-color: red;
}
section div:nth-child(2) {
flex: 1;
background-color: green;
}
section div:nth-child(3) {
width: 100px;
height: 150px;
background-color: blue;
}
</style>
说明:1和3号盒子有宽度,它们一共占据了200px宽,那么剩余空间就是section的宽减去这200px的宽,即2号盒子将剩余空间全占了。
- 用flex实现不同盒子的固定比例占据
<body>
<p>
<span>1</span>
<span>2</span>
<span>3</span>
</p>
</body>
<style>
p {
display: flex;
width: 60%;
height: 150px;
background-color: pink;
margin: 0 auto;
}
p span {
/* border: 1px solid #000; */
flex: 1;
}
p span:nth-child(2) {
flex: 2;
background-color: skyblue;
}
</style>
三个盒子所占宽带的比例就是1:2:1
4.2 控制子项自己在侧轴上的排列方式
- 让3个子盒子沿着侧轴底侧对齐
<body>
<div>
<span>1</span>
<span>2</span>
<span>3</span>
</div>
</body>
<style>
div {
display: flex;
width: 80%;
height: 200px;
background-color: pink;
/* 1. 让3个子盒子沿着侧轴底侧对齐 */
align-items: flex-end;
}
div span {
width: 150px;
height: 60px;
background-color: skyblue;
margin-right: 5px;
}
/* div span:nth-child(3) {
align-self: flex-end;
} */
</style>
- 只让第三个盒子沿着底侧对齐
<body>
<div>
<span>1</span>
<span>2</span>
<span>3</span>
</div>
</body>
<style>
div {
display: flex;
width: 80%;
height: 200px;
background-color: pink;
/* 2. 只让第三个盒子沿着底侧对齐 */
}
div span {
width: 150px;
height: 60px;
background-color: skyblue;
margin-right: 5px;
}
/* 2. 只让第三个盒子沿着底侧对齐 */
div span:nth-child(3) {
align-self: flex-end;
}
</style>
4.3 order属性定义项目的排列顺序
数值越小,排列越靠前,默认值为0
注意:和z-index不一样
<body>
<div>
<span>1</span>
<span>2</span>
<span>3</span>
</div>
</body>
<style>
div {
display: flex;
width: 80%;
height: 200px;
background-color: pink;
}
div span {
width: 150px;
height: 60px;
background-color: skyblue;
margin-right: 5px;
}
div span:nth-child(2) {
/* order默认值是0,-1比0小,所以在前面 */
order: -1;
}
</style>