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-direction
flex-wrap
flex-flow
justify-content
align-items
align-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 */
}
项目(子元素)的六大属性
order
flex-grow
flex-shrink
flex-basis
flex
align-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>