Flex布局的背景
Flex布局是在CSS3中引入的一种新的布局模式,旨在解决传统布局模式的一些问题。
2009年,Flex 布局是W3C 提出的一种新的布局方案,可以简便、完整、响应式
地实现各种页面布局。目前,它已经得到了所有浏览器的支持,到现在2023年,Flex布局已经成为前端开发人员的必备知识了。
在Flex布局产生之前,主要采用的是基于盒模型的传统布局模式,即使用display属性的block值或inline-block值来实现布局。这种传统布局模式在实现一些复杂的布局时存在一些困难,比如垂直居中、等高布局、自适应宽度等问题。同时,这种布局模式对于不同尺寸的屏幕适应性较差。
而Flex布局则是通过一些新的属性和值来实现更加灵活的布局,可以方便地实现各种复杂的布局需求。Flex布局使用flex容器和flex项目的概念,通过设置容器和项目的属性来实现布局。Flex布局具有自适应性,可以根据容器的尺寸自动调整项目的布局,同时可以轻松实现项目的对齐、排序和间距等功能。
Flex 是 Flexible Box 的缩写,意为"弹性布局
",用来为盒状模型提供最大的灵活性。
Flex的使用
1.指定父容器为Flex属性
我们想使用flex布局,首先要先指定一个容器为Flex布局
html
<div class="box"></div>
通过display属性来进行指定
css
.box{
display: flex;
}
如果是Webkit 内核的浏览器,必须加上-webkit
前缀。
css
.box{
display: -webkit-flex; /* Safari */
}
设为 Flex 布局以后,子元素的float
、clear
和vertical-align
属性将失效。 父容器设置为Flex布局之后,然后其子元素就变成了受父元素控制的flex-item子项
2.在父容器上设置子元素的排列
我们把父元素变成flex容器之后,这个容器默认会存在两条轴,x轴和y轴,也叫水平轴和交叉轴,子元素会按照这两个轴的设定进行排列,具体怎么设定,看下面
其中有父容器可以通过设置以下6个属性,来控制子元素的排列。下面的属性都是写在父元素身上的!!!
- flex-direction
- flex-wrap
- flex-flow
- justify-content
- align-items
- align-content
2.1 flex-direction 设置主轴的
flex-direction
属性决定主轴的方向(即项目的排列方向),就是子元素默认会按照主轴的方式进行排列, 我们给父容器设置display:flex之后,然后父容器的flex-direction默认是x轴的从左到右的方向
css
.box {
display:flex;
flex-direction: row (默认值) | row-reverse | column | column-reverse;
}
row
(默认值):主轴为水平方向,起点在左端,x轴,从左到右的方向row-reverse
:主轴为水平方向,起点在右端,x轴,从右到左column
:主轴为垂直方向,起点在上沿,y轴,从下到上column-reverse
:主轴为垂直方向,起点在下沿,从上到下
注意,这个设置主轴很重要,一般的布局的话,我们使用默认的布局就行了,就是默认主轴是row
2.2 flex-wrap 控制放不下的时候,是否换行
默认情况下,项目都排在一条线(又称"轴线")上。flex-wrap
属性定义,如果一条轴线排不下,如何换行。
这个flex-warp可取以下三个值nowrap(不换行,默认) | wrap(换行) | wrap-reverse(反转换行);
lua
.box{
flex-wrap: nowrap | wrap | wrap-reverse;
}
这个值如果不去设置的话,默认就是不换行,然后所有子元素都会挤到一起,然后你就算设置了子元素的宽度,但也不会生效
,还是会挤到一行。
奥对了,flex布局的话,就只是设置父容器里面用的,父容器其他的属性都是可以正常使用的
2.2.1 flex-wrap: nowrap 不换行
先是介绍nowrap的情况,不换行的情况
可以看下面的代码,我把box盒子设置宽为400px,高为
xml
<style>
.box {
width: 400px;
height: 300px;
border: 1px solid black;
display: flex;
flex-direction: row;
flex-wrap: nowrap; //这是默认为nowarp,写不写都一样
}
.items {
width: 100px;
height: 100px;
margin: 5px;
background-color: aquamarine;
}
</style>
<body>
<div class="box">
<div class="items">
</div>
<div class="items">
</div>
<div class="items">
</div>
<div class="items">
</div>
</div>
</body>
然后上面的代码是不完整的,头部信息什么都没有,你要用的话,自己补,很简单,然后效果如下
我们用浏览器的开发者工具来查看一下,如下图,宽度很明显压缩了。
2.2.2 flex-wrap: wrap 换行
然后我们再尝试一下 flex-wrap: wrap
就可以发现它换行了,子元素宽度的也是我们设置的那个100x100
2.2.3 flex-wrap:wrap-reverse 翻转换行
然后就是 flex-wrap:wrap-reverse;
,效果如下图
一般我们在使用这个属性的时候,会将其设置为wrap换行
2.3 flex-flow复合属性
flex-flow
属性是flex-direction
属性和flex-wrap
属性的简写形式,默认值为row nowrap
css
.box {
display: flex;
flex-direction: row;
flex-wrap:wrap;
/* flex-flow: row wrap */ 先把复合属性注释掉
}
效果如下:
css
.box {
display: flex;
/* flex-direction: row;
flex-wrap:wrap; */
flex-flow: row wrap
}
效果如下,是一样的
或许会有朋友要问了,那如果两个都设置呢?
如果都设置的话,会按代码顺序进行覆盖,写在后面的属性覆盖掉前面的属性
2.4 justify-content属性 设置主轴对齐方式
我们前面通过flex-direction
来设置主轴,设置之后,会默认依次排列,然后我们现在可以通过justify-content
属性设置子元素在主轴上的对齐方式。
css
.box {
justify-content: flex-start | flex-end | center | space-between | space-around;
}
2.4.1 flex-start (默认值):左对齐
2.4.2 flex-end 右对齐
2.4.3 center 居中对齐
2.4.4 space-between 两端对齐,子元素之间的间隔都相等。
2.4.5 space-around 每个子元素两侧的间隔相等。所以,项目之间的间隔比项目与边框的间隔大一倍。
注意
使用space-between和space-around的话,会导致你设置子元素的margin和padding失效,在某些面
2.5 align-items 设置子元素在交叉轴上如何对齐。
align-items
属性定义子元素在交叉轴上如何对齐。
css
.box {
align-items: flex-start | flex-end | center | baseline | stretch;
}
它可以取以下5个值。具体的对齐方式与交叉轴(默认是y轴,从上到下)的方向有关,下面假设交叉轴从上到下。
flex-start
:交叉轴的起点对齐。flex-end
:交叉轴的终点对齐。center
:交叉轴的中点对齐。baseline
: 项目的第一行文字的基线对齐。stretch
(默认值):如果项目未设置高度或设为auto,将占满整个容器的高度。
需要注意的是,这个属性只能设置没有换行的,就是只有一条轴线!!!
如果设置了flex-wrap:wrap,然后子元素还换了行的,这个属性是无效的,反正就是不能换行,只有一条轴线
2.6 align-content属性
此属性和上面的align-items相反,是定义多个轴线的,就是必须要存在换行的现象,这个属性对单行无效!!!
sql
.box {
align-content: flex-start | flex-end | center | space-between | space-around | stretch;
}
该属性可能取6个值。
flex-start
:与交叉轴的起点对齐。flex-end
:与交叉轴的终点对齐。center
:与交叉轴的中点对齐。space-between
:与交叉轴两端对齐,轴线之间的间隔平均分布。space-around
:每根轴线两侧的间隔都相等。所以,轴线之间的间隔比轴线与边框的间隔大一倍。stretch
(默认值):轴线占满整个交叉轴。
具体效果可参考下图,其实设置的就是两条轴的位置
3.设置子元素的属性
以下6个属性可以设置在子元素上,然后进行单个元素具体的位置的设置
order
属性定义子元素的排列顺序。数值越小,排列越靠前,默认为0。flex-grow
属性定义子元素的放大比例,默认为0
,即如果存在剩余空间,也不放大。flex-shrink
属性定义了子元素的缩小比例,默认为1,即如果空间不足,该子元素将缩小。flex-basis
属性定义了在分配多余空间之前,子元素占据的主轴空间(main size)。浏览器根据这个属性,计算主轴是否有多余空间。它的默认值为auto
,即子元素的本来大小。flex
属性是flex-grow
,flex-shrink
和flex-basis
的简写,默认值为0 1 auto
。后两个属性可选。align-self
属性允许单个子元素有与其他子元素不一样的对齐方式,可覆盖align-items
属性。默认值为auto
,表示继承父元素的align-items
属性,如果没有父元素,则等同于stretch
。
3.1 order 定义子元素的排列顺序
html
<div class="box">
<div class="items">
1
</div>
<div class="items two" > //这里!!加了一个two
2
</div>
<div class="items">
3
</div>
<div class="items">
4
</div>
<div class="items">
5
</div>
</div>
css
.two{
order:-1
}
可以看到由于设置了order,然后2号盒子在1号盒子之前了, order
属性定义项目的排列顺序。数值越小,排列越靠前,默认为0。
3.2 flex-grow属性给子元素分配剩余空间
html
<div class="box1">
<div class="items" style="flex-grow: 1;">
1
</div>
<div class="items" style="flex-grow: 2;">
2
</div>
<div class="items" style="flex-grow: 1;">
3
</div>
</div>
其实我的理解是这样的,这个设置比例,不是把所有空间直接分成4份,上面的代码就是一共四份,它其实是先每个子元素先加载完他们的宽度,然后再把剩下的宽度进行四等分,然后按比例进行分。
其实如果你不给子元素设置宽度的话,那其实剩余空间就是全部空间
3.3 flex-shrink属性定义缩小比例
flex-shrink
属性定义了子元素的缩小比例,默认为1,即如果空间不足,该项目将缩小。
css
.item {
flex-shrink: <number>; /* default 1 */
}
如果所有项目的flex-shrink
属性都为1,当空间不足时,都将等比例缩小。如果一个项目的flex-shrink
属性为0,其他项目都为1,则空间不足时,前者不缩小。
3.4 align-self属性设置单个元素对齐方式
arduino
.item {
align-self: auto | flex-start | flex-end | center | baseline | stretch;
}
该属性可能取6个值,除了auto,其他都与align-items属性完全一致。
3.5子元素的flex复合属性
flex
属性是flex-grow
, flex-shrink
和 flex-basis
的简写,默认值为0 1 auto
。后两个属性可选。
css.item { flex: none | [ <'flex-grow'> <'flex-shrink'>? || <'flex-basis'> ] }
该属性有两个快捷值:auto
(1 1 auto
) 和 none (0 0 auto
)。
建议优先使用这个属性,而不是单独写三个分离的属性,因为浏览器会推算相关值。
关于Flex在其他框架中的使用
在vue中
在Vue中,可以通过使用Vue的模板语法和样式绑定来实现Flex布局。以下是使用Vue和Flex布局的示例代码:
html
<template>
<div class="container">
<div class="item">Item 1</div>
<div class="item">Item 2</div>
<div class="item">Item 3</div>
</div>
</template>
<style>
.container {
display: flex;
justify-content: space-between;
}
.item {
flex: 1;
margin: 10px;
}
</style>
在上面的代码中,我们创建了一个容器和三个子元素。通过设置容器的display
属性为flex
,我们将容器设置为Flex布局。然后,通过设置容器的justify-content
属性为space-between
,我们实现了子元素之间的等间距分布。
在子元素中,我们使用flex: 1
来设置子元素的伸缩比例,使它们平均分配剩余空间。同时,我们还设置了子元素的margin
属性来设置子元素之间的间距。
除了Vue,Flex布局也可以在其他框架中使用。只需将相应的HTML和CSS代码添加到框架的模板和样式中即可。
在react中
jsx
import React from "react";
function App() {
return (
<div className="container">
<div className="item">Item 1</div>
<div className="item">Item 2</div>
<div className="item">Item 3</div>
</div>
);
}
export default App;
css
.container {
display: flex;
justify-content: space-between;
}
.item {
flex: 1;
margin: 10px;
}
在Angular中
html
<div class="container">
<div class="item">Item 1</div>
<div class="item">Item 2</div>
<div class="item">Item 3</div>
</div>
css
.container {
display: flex;
justify-content: space-between;
}
.item {
flex: 1;
margin: 10px;
}
无论是在Vue、React、Angular还是Ember.js等框架中,Flex布局的使用方式基本相同。只需设置相关的CSS属性即可实现灵活的布局。
关于其他布局方式
除了flex布局之外,还有以下几种布局方式,其中Grid布局方式目前使用比较多
- Grid布局:Grid布局是一种二维网格布局系统,可以通过将网格划分为行和列来进行布局。它可以更灵活地控制元素的位置和大小,并支持响应式布局。
- CSS Grid布局:CSS Grid布局是一种基于网格的布局系统,可以通过将元素放置在网格中的行和列上来进行布局。它提供了更强大的布局能力,可以实现复杂的布局结构。
- Multi-column布局:Multi-column布局是一种多列布局系统,可以将文本内容分为多列进行显示。它适用于报纸、杂志等需要多列排版的场景。
- CSS Shapes布局:CSS Shapes布局是一种通过定义元素的形状来进行布局的方式。它可以实现文字环绕、不规则形状的布局效果。