flex
2009年,W3C 提出了一种新的方案----Flex 布局,可以简便、完整、响应式地实现各种页面布局。目前,它已经得到了所有浏览器的支持,这意味着,现在就能很安全地使用这项功能
Flex 是 Flexible Box 的缩写,意为"弹性布局",用来为盒状模型提供最大的灵活性
练习html
基于以下html来开始学习,运行该html后,布局样式为1至9从上而下排列,每个的宽度都为100px
<div class="flex-practise">
<div class="item">1</div>
<div class="item">2</div>
<div class="item">3</div>
<div class="item">4</div>
<div class="item">5</div>
<div class="item">6</div>
<div class="item">7</div>
<div class="item">8</div>
<div class="item">9</div>
</div>
<style>
body{
}
.flex-practise {
width: 300px;
height: 300px;
background-color: #eeeeee;
/* 此处的下方编写css */
/* 此处的上方编写css */
}
.item {
width: 33.33%;
height: 33.33%;
color: #ffffff;
display: flex;
justify-content: center;
align-items: center;
font-size: 30px;
background-color: #000000;
border: 1px solid #fff;
box-sizing: border-box;
border-radius: 15px;
}
</style>
<div class="flex-practise">
<div class="item">1</div>
<div class="item">2</div>
<div class="item">3</div>
<div class="item">4</div>
<div class="item">5</div>
<div class="item">6</div>
<div class="item">7</div>
<div class="item">8</div>
<div class="item">9</div>
</div>
<style>
body{
}
.flex-practise {
width: 300px;
height: 300px;
background-color: #eeeeee;
/* 此处的下方编写css */
/* 此处的上方编写css */
}
.item {
width: 33.33%;
height: 33.33%;
color: #ffffff;
display: flex;
justify-content: center;
align-items: center;
font-size: 30px;
background-color: #000000;
border: 1px solid #fff;
box-sizing: border-box;
border-radius: 15px;
}
</style>

display: flex
采用flex布局的元素,又称为flex容器(flex container),它的每个子元素自动成为容器成员,又称为flex项目(flex item),简称项目
实际开发中,flex布局常用于使所有独占一行的块级子元素(基本上是div),变为一行显示
示例代码如下,布局样式变为1至9从左到由排列,且宽度等比缩放
.flex-practise {
width: 300px;
height: 300px;
/* 此处的下方编写css */
display:flex;
/* 此处的上方编写css */
}
.flex-practise {
width: 300px;
height: 300px;
/* 此处的下方编写css */
display:flex;
/* 此处的上方编写css */
}

可是我们明明已经设置子元素的宽度为33.33%,从而我们可以得出了一个结论:
flex布局下的所有项目(子元素)默认排在一行,所有项目(子元素)的宽度之和超过父元素也不换行,而是按比例缩小所有项目(子元素)宽度,这其实是项目(子元素)的flex-shrink属性默认为1的缘故,下面的章节会学习该属性
flex容器六大属性
flex-directionflex-wrapflex-flowjustify-contentalign-itemsalign-content
flex-direction
flex-direction属性决定子元素的排列方向
row(默认):所有项目(子元素)从左到右排列row-reverse:所有项目(子元素)从右到左排列column:所有(项目子元素)从上到下排列column-reverse:所有项目(子元素)从下到上排列
示例代码如下,布局样式变为9至1从左到右排列,且宽度等比缩放
.flex-practise {
width: 300px;
height: 300px;
/* 此处的下方编写css */
display:flex;
flex-direction: row-reverse;
/* 此处的上方编写css */
}
.flex-practise {
width: 300px;
height: 300px;
/* 此处的下方编写css */
display:flex;
flex-direction: row-reverse;
/* 此处的上方编写css */
}

flex-wrap
之前我们知道了:flex布局下的所有项目(子元素)默认排在一行,所有项目(子元素)的宽度之和超过父元素也不换行,而是按比例缩小所有项目(子元素)宽度
如果希望所有项目(子元素)的宽度之和超过父元素后换行,需要设置flex-wrap
nowrap(默认):不换行wrap:换行wrap-reverse:换行,项目(子元素)从下到上排列,即第一行在最下方,第二行在第一行上方
示例代码如下,布局样式变为3*3,且从右到左排列
.flex-practise {
width: 300px;
height: 300px;
/* 此处的下方编写css */
display: flex;
flex-direction: row-reverse;
flex-wrap: wrap;
/* 此处的上方编写css */
}
.flex-practise {
width: 300px;
height: 300px;
/* 此处的下方编写css */
display: flex;
flex-direction: row-reverse;
flex-wrap: wrap;
/* 此处的上方编写css */
}

flex-flow
flex-flow属性是flex-direction属性和flex-wrap属性的简写形式
默认值为row nowrap,即所有项目(子元素)从左到右排列且不换行
示例代码如下,布局样式变为3*3,且从右到左排列,同上方等价
.flex-practise {
width: 300px;
height: 300px;
/* 此处的下方编写css */
display: flex;
flex-flow: row-reverse wrap;
/* 此处的上方编写css */
}
.flex-practise {
width: 300px;
height: 300px;
/* 此处的下方编写css */
display: flex;
flex-flow: row-reverse wrap;
/* 此处的上方编写css */
}
justify-content
所有项目(子元素)在设置flex布局的父元素(flex容器)中横向的位置(所有项目(子元素)的宽度之和只占父元素(flex容器)宽度一部分的情况下)
flex-start(默认):居左flex-end:居右center: 居中space-between:两端对齐,子元素之间的间隔都相等space-around:子元素两侧的间隔相等。所以最左边和最右边子元素离边的间隔只有子元素之间间隔的一半
为了看到效果,修改item的width为20%
.item {
width: 20%;
...
}
.item {
width: 20%;
...
}
示例代码如下,布局样式变为在横向上居中排列
.flex-practise {
width: 300px;
height: 300px;
background-color: #eeeeee;
/* 此处的下方编写css */
display: flex;
flex-wrap: wrap;
justify-content: center;
/* 此处的上方编写css */
}
.flex-practise {
width: 300px;
height: 300px;
background-color: #eeeeee;
/* 此处的下方编写css */
display: flex;
flex-wrap: wrap;
justify-content: center;
/* 此处的上方编写css */
}

同时对justify-content和flex-direction设置,示例代码如下,
justify-content: flex-end;由居右变成居左,可见justify-content受flex-direction影响
.flex-practise {
width: 300px;
height: 300px;
background-color: #eeeeee;
/* 此处的下方编写css */
display: flex;
flex-flow: row-reverse wrap;
justify-content: flex-end;
/* 此处的上方编写css */
}
.flex-practise {
width: 300px;
height: 300px;
background-color: #eeeeee;
/* 此处的下方编写css */
display: flex;
flex-flow: row-reverse wrap;
justify-content: flex-end;
/* 此处的上方编写css */
}

align-items
子元素在父元素中纵向的位置(子元素的高度只占父元素高度一部分的情况下)
主要用于单行子元素,但多行也有效果
单行效果如下
flex-start::居上flex-end:居下center:居中baseline: 子元素的第一行文字的基线对齐stretch(默认):如果子元素未设置高度或设为auto,将占满整个容器的高度
多行效果如下
flex-start::每行下方间隔相等flex-end:每行上方间隔相等center:每行上下间隔相等,所以最上边行和最下边行离边的间隔只有每行间隔的一半baseline: 子元素的每一行文字的基线对齐stretch(默认):每行下方间隔一样
父元素没有固定高度,且没有设置align-items,即align-items值为stretch(默认),则父元素高度由最高子元素决定
父元素设置align-items:center后,子元素的高度,由自身内容决定,此时再为子元素设置高度100%是没有作用的
这一点常见于设置表格样式
单行情况,示例代码与样式如下
.flex-practise {
width: 300px;
height: 300px;
background-color: #eeeeee;
/* 此处的下方编写css */
display: flex;
align-items: flex-end;
/* 此处的上方编写css */
}
.flex-practise {
width: 300px;
height: 300px;
background-color: #eeeeee;
/* 此处的下方编写css */
display: flex;
align-items: flex-end;
/* 此处的上方编写css */
}

多行情况,示例代码与样式如下,每行上方间隔相等
.flex-practise {
width: 300px;
height: 300px;
background-color: #eeeeee;
/* 此处的下方编写css */
display: flex;
align-items: flex-end;
/* 此处的上方编写css */
}
.flex-practise {
width: 300px;
height: 300px;
background-color: #eeeeee;
/* 此处的下方编写css */
display: flex;
align-items: flex-end;
/* 此处的上方编写css */
}

align-content
多行子元素在父元素中纵向的位置
如果只有一行,该属性不起作用
多行子元素情况下,同时设置align-items和align-content,只有align-content生效
flex-start:居上flex-end:居下center:居中排列space-between:上下两端对齐,每行之间的间隔相等space-around:每行上下间隔相等,所以最上边行和最下边行离边的间隔只有每行间隔的一半stretch(默认值):下方间隔相等
单行情况,示例代码如下,没有效果
.flex-practise {
width: 300px;
height: 300px;
background-color: #eeeeee;
/* 此处的下方编写css */
display: flex;
align-content: flex-end;
/* 此处的上方编写css */
}
.flex-practise {
width: 300px;
height: 300px;
background-color: #eeeeee;
/* 此处的下方编写css */
display: flex;
align-content: flex-end;
/* 此处的上方编写css */
}
多行情况,示例代码如下,样式与align-items有明显区别,是把多行子元素作为一个整体
.flex-practise {
width: 300px;
height: 300px;
background-color: #eeeeee;
/* 此处的下方编写css */
display: flex;
align-content: flex-end;
/* 此处的上方编写css */
}
.flex-practise {
width: 300px;
height: 300px;
background-color: #eeeeee;
/* 此处的下方编写css */
display: flex;
align-content: flex-end;
/* 此处的上方编写css */
}

多行子元素情况下,同时设置align-items和align-content,只有align-content生效,而单行子元素情况下,align-content直接无效,故不用再进行比较
.flex-practise {
width: 300px;
height: 300px;
background-color: #eeeeee;
/* 此处的下方编写css */
display: flex;
flex-wrap: wrap;
align-items: flex-start;
align-content: flex-end;
/* 此处的上方编写css */
}
.flex-practise {
width: 300px;
height: 300px;
background-color: #eeeeee;
/* 此处的下方编写css */
display: flex;
flex-wrap: wrap;
align-items: flex-start;
align-content: flex-end;
/* 此处的上方编写css */
}
项目(子元素)的六大属性
orderflex-growflex-shrinkflex-basisflexalign-self
order
order属性定义项目(子元素)的排列顺序。数值越小,排列越靠前,默认为0
为第九个子元素加一个nine的class
<div class="item nine">9</div>
<div class="item nine">9</div>
设置order后,样式如下变化
.nine {
order: -1;
}
.nine {
order: -1;
}

flex-grow
flex-grow属性定义项目(子元素)的放大比例,默认为0,即如果存在剩余空间,也不放大
如果所有项目(子元素)的flex-grow属性都为1,则它们将等分父元素剩余空间(如果有的话)。如果一个项目(子元素)的flex-grow属性为2,其他项目(子元素)都为1,则前者占据的剩余空间将比其他项多一倍
为项目(子元素)设置flex-grow: 1;后,样式为
.item {
flex-grow: 1;
...
}
.item {
flex-grow: 1;
...
}

flex-shrink
flex-shrink属性定义了项目(子元素)的缩小比例,默认为1,即如果空间不足,该项目(子元素)将缩小
即使为项目(子元素)设置了固定宽度,如果父元素宽度小于各项目(子元素)之和,还是会等比例缩小各项目(子元素)
所以如果不想宽度被缩小,需要设置项目(子元素)flex-shrink属性为0
flex-shrink: 0;
flex-shrink: 0;
flex-basis
flex-basis属性定义了在分配多余空间之前,项目(子元素)占据的主轴空间(main size)。浏览器根据这个属性,计算主轴是否有多余空间。
它的默认值为auto,即项目的本来大小
它可以设为跟width属性一样的值(比如100px),则项目将占据固定空间,即它不受flex-shrink:1的影响
.nine {
flex-basis: 100px;
}
.nine {
flex-basis: 100px;
}

flex
flex属性是flex-grow, flex-shrink 和 flex-basis的简写,默认值为0 1 auto,也就是三个属性的默认值,后两个属性可选
比较常见的是flex: 1 ,其相当于1 1 0%,即等分父元素剩余空间,等比例缩小,不占据固定空间
所以flex: 1 后,即使父元素设置flex:wrap,所有项目还是处于一行,且会等比例缩小,即使为项目(子元素)设置了固定宽度,还是会缩小于设置的width,因为不仅flex-shrink为1,且 flex-basis为0%
如果使用flex属性,修改第三个参数flex-basis的值即可设置最小固定宽度,且无需再设置宽
示例代码,则等分父元素剩余空间,等比例缩小但宽度最小为父元素50%
.item {
flex: 1 1 50%;
color: #ffffff;
display: flex;
justify-content: center;
align-items: center;
font-size: 30px;
background-color: #000000;
border: 1px solid #fff;
box-sizing: border-box;
border-radius: 15px;
}
.item {
flex: 1 1 50%;
color: #ffffff;
display: flex;
justify-content: center;
align-items: center;
font-size: 30px;
background-color: #000000;
border: 1px solid #fff;
box-sizing: border-box;
border-radius: 15px;
}

flex: 1
1 1 0%
1 1 0%
flex:auto
1 1 auto
1 1 auto
align-self
align-self属性允许单个项目有与其他项目不一样的对齐方式,可覆盖align-items属性。默认值为auto,表示继承父元素的align-items属性,如果没有父元素,则等同于stretch。
- auto(默认值)
- flex-start
- flex-end
- center
- baseline
- stretch
垂直居中
非常常用的flex语法
display: flex;
align-items: center;
justify-content: center;
display: flex;
align-items: center;
justify-content: center;
多行布局
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Document</title>
</head>
<body>
<main>
<div class="flex-container">
<div class="flexbox">box1</div>
<div class="flexbox">box2</div>
<div class="flexbox">box3</div>
<div class="flexbox">box4</div>
<div class="flexbox">box5</div>
<div class="flexbox">box6</div>
</div>
</main>
<style>
* {
margin: 0;
padding: 0;
}
.flex-container {
background-color: pink;
width: 948px;
height: 624px;
}
.flex-container {
display: flex;
flex-wrap: wrap;
gap: 24px;
}
.flexbox {
width: 300px;
height: 300px;
background-color: #fff;
}
</style>
</body>
</html>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Document</title>
</head>
<body>
<main>
<div class="flex-container">
<div class="flexbox">box1</div>
<div class="flexbox">box2</div>
<div class="flexbox">box3</div>
<div class="flexbox">box4</div>
<div class="flexbox">box5</div>
<div class="flexbox">box6</div>
</div>
</main>
<style>
* {
margin: 0;
padding: 0;
}
.flex-container {
background-color: pink;
width: 948px;
height: 624px;
}
.flex-container {
display: flex;
flex-wrap: wrap;
gap: 24px;
}
.flexbox {
width: 300px;
height: 300px;
background-color: #fff;
}
</style>
</body>
</html>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Document</title>
</head>
<body>
<main>
<div class="flex-container">
<div class="flexbox">box1</div>
<div class="flexbox">box2</div>
<div class="flexbox">box3</div>
<div class="flexbox">box4</div>
<div class="flexbox">box5</div>
<div class="flexbox">box6</div>
</div>
</main>
<style>
* {
margin: 0;
padding: 0;
}
.flex-container {
background-color: pink;
width: 972px;
height: 624px;
}
.flex-container {
display: flex;
flex-wrap: wrap;
margin: -24px 0px 0px -24px;
}
.flexbox {
width: 300px;
height: 300px;
background-color: #fff;
margin: 24px 0px 0px 24px;
}
</style>
</body>
</html>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Document</title>
</head>
<body>
<main>
<div class="flex-container">
<div class="flexbox">box1</div>
<div class="flexbox">box2</div>
<div class="flexbox">box3</div>
<div class="flexbox">box4</div>
<div class="flexbox">box5</div>
<div class="flexbox">box6</div>
</div>
</main>
<style>
* {
margin: 0;
padding: 0;
}
.flex-container {
background-color: pink;
width: 972px;
height: 624px;
}
.flex-container {
display: flex;
flex-wrap: wrap;
margin: -24px 0px 0px -24px;
}
.flexbox {
width: 300px;
height: 300px;
background-color: #fff;
margin: 24px 0px 0px 24px;
}
</style>
</body>
</html>