目录
align-self: 覆盖container align-items 属性
最近在开发过程中遇到了一个Flex布局引起的问题,所以在记录该问题的时候,顺便就系统的学习下Flex布局的知识点,并且在后续的开发中也会将遇到的有关Flex布局的问题添加在后面。
PS:如果熟悉Flex的知识点,可以直接点击目录中的“那些Flex布局的坑”直接跳转到相关位置。
Flex知识点
Flex布局是弹性布局,分为外部容器和内部item,通过在外部容器上display: flex属性可以实现弹性布局。
Flex布局的原理:通过给父元素设置display:flex属性,来控制子元素的位置和排列方式。
flex布局的相关介绍
flex布局对其他样式属性的影响
当父元素设置为flex布局之后,子元素的float、clear、vertical-aligin属性都会失效
flex布局的外曾容器相关的属性
flex-direction设置flex布局的主轴方向
(copy菜鸟教程中的一张图片)
flex布局分为主轴(main axis)和侧轴(cross axis),默认水平方向为主轴方向。
flex-direction: row;默认方向,主轴为水平方向,起点在左端。
flex-direction: row-reverse;主轴为水平方向,起点在右端。
flex-direction: column;主轴为垂直方向,起点在上沿。
flex-direction: column-reverse;主轴为垂直方向,起点在下沿。
<template>
<div class="flex-wrap">
<div class="container-1 container">
<div class="item">1</div>
<div class="item">2</div>
<div class="item">3</div>
</div>
<div class="container-2 container">
<div class="item">1</div>
<div class="item">2</div>
<div class="item">3</div>
</div>
<div class="container-3 container">
<div class="item">1</div>
<div class="item">2</div>
<div class="item">3</div>
</div>
<div class="container-4 container">
<div class="item">1</div>
<div class="item">2</div>
<div class="item">3</div>
</div>
<div class="container-5 container">
<div class="item">1</div>
<div class="item">2</div>
<div class="item">3</div>
</div>
</div>
</template>
<script>
export default {
name: "FlexeDemo",
};
</script>
<style scoped>
.flex-wrap {
width: 500px;
height: 500px;
border: 1px solid gainsboro;
}
.container {
margin: 2px;
border: 1px solid blue;
display: flex;
}
.container-1 {
/* 默认方向 */
}
.container-2 {
flex-direction: row;
}
.container-3 {
flex-direction: row-reverse;
}
.container-4 {
flex-direction: column;
}
.container-5 {
flex-direction: column-reverse;
}
.item {
margin: 5px;
border: 1px solid gray;
width: 20px;
height: 20px;
}
</style>
效果图:
flex-wrap控制item换行
flex-wrap: nowrap;不换行,也是默认值
flex-wrap: wrap;换行,从上往下换行,即第一行在最上面
flex-wrap: wrap-reverse;换行,从下往上换行,第一行在最下面
<div class="container-6 container">
<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>
<div class="container-7 container">
<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>
<div class="container-8 container">
<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>
<div class="container-9 container">
<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>
.container-6 {
/* 默认 */
}
.container-7 {
flex-wrap: nowrap;
}
.container-8 {
flex-wrap: wrap;
}
.container-9 {
flex-wrap: wrap-reverse;
}
flex-flow结合属性
flex-flow属性是flex-direction和flex-wrap属性的结合
flex-flow: <flex-direction> <flex-wrap>;
justify-content设置主轴方向的对齐方式
flex-start(默认值):左对齐
flex-end:右对齐
center: 居中
space-between:两端对齐,项目之间的间隔都相等。
space-around:分散对齐,每个项目两侧的间隔相等。所以,项目之间的间隔比项目与边框的间隔大一倍。
justify-content: space-evenly;平均分配,空白空间平均分配
.container-1 {
/* 默认对齐方式 */
}
.container-2 {
justify-content: flex-start;
}
.container-3 {
justify-content: flex-end;
}
.container-4 {
justify-content: center;
}
.container-5 {
justify-content: space-between;
}
.container-6 {
justify-content: space-around;
}
.container-7 {
justify-content: space-evenly;
}
ps:示例只写了水平方向为主轴的情况。
align-items设置侧轴的对齐方式
flex-start:侧轴的起点对齐。
flex-end:侧轴的终点对齐。
center:侧轴的中点对齐。
baseline: 项目的第一行文字的基线对齐。
stretch(默认值)伸展:如果项目未设置高度或设为auto,将占满整个容器的高度。
<div class="container-10 container2">
<div class="item">
<div class="item-1">1</div>
</div>
<div class="item">
<div class="item-2">1</div>
</div>
<div class="item">
<div class="item-3">1</div>
</div>
</div>
<div class="container-11 container2">
<div class="item">
<div class="item-1">1</div>
</div>
<div class="item">
<div class="item-2">1</div>
</div>
<div class="item">
<div class="item-3">1</div>
</div>
</div>
<div class="container-12 container2">
<div class="item">
<div class="item-1">1</div>
</div>
<div class="item">
<div class="item-2">1</div>
</div>
<div class="item">
<div class="item-3">1</div>
</div>
</div>
<div class="container-13 container2">
<div class="item">
<div class="item-1">1</div>
</div>
<div class="item">
<div class="item-2">1</div>
</div>
<div class="item">
<div class="item-3">1</div>
</div>
</div>
<div class="container-14 container2">
<div class="item">
<div class="item-1">1</div>
</div>
<div class="item">
<div class="item-2">1</div>
</div>
<div class="item">
<div class="item-3">1</div>
</div>
</div>
<div class="container-15 container2">
<div class="item">
<div class="item-1">1</div>
</div>
<div class="item">
<div class="item-2">1</div>
</div>
<div class="item">
<div class="item-3">1</div>
</div>
</div>
.container-10 {
/* 默认值 */
}
.container-11 {
align-items: flex-start;
}
.container-12 {
align-items: flex-end;
}
.container-13 {
align-items: center;
}
.container-14 {
align-items: baseline;
}
.container-15 {
align-items: stretch;
}
.container2 {
height: 100px;
margin: 2px;
border: 1px solid blue;
display: flex;
}
.item-1 {
height: 30px;
}
.item-2 {
height: 50px;
}
.item-3 {
height: 30px;
}
ps:示例只写了水平方向为主轴的情况。
align-content多行item的对齐方式
flex-start:与侧轴的起点对齐。
flex-end:与侧轴的终点对齐。
center:与侧轴的中点对齐。
space-between:与侧轴两端对齐,轴线之间的间隔平均分布。
space-around:item在侧轴平分剩余空间。每根轴线两侧的间隔都相等。所以,轴线之间的间隔比轴线与边框的间隔大一倍。
stretch(默认值):轴线占满整个交叉轴,item高度平分父元素高度。
<template>
<div class="flex-wrap">
<div class="container container-1">
<div class="item-wrap">1</div>
<div class="item-wrap">1</div>
<div class="item-wrap">1</div>
<div class="item-wrap">1</div>
</div>
<div class="container container-2">
<div class="item-wrap">1</div>
<div class="item-wrap">1</div>
<div class="item-wrap">1</div>
<div class="item-wrap">1</div>
</div>
<div class="container container-3">
<div class="item-wrap">1</div>
<div class="item-wrap">1</div>
<div class="item-wrap">1</div>
<div class="item-wrap">1</div>
</div>
<div class="container container-4">
<div class="item-wrap">1</div>
<div class="item-wrap">1</div>
<div class="item-wrap">1</div>
<div class="item-wrap">1</div>
</div>
<div class="container container-5">
<div class="item-wrap">1</div>
<div class="item-wrap">1</div>
<div class="item-wrap">1</div>
<div class="item-wrap">1</div>
</div>
<div class="container container-6">
<div class="item-wrap">1</div>
<div class="item-wrap">1</div>
<div class="item-wrap">1</div>
<div class="item-wrap">1</div>
</div>
<div class="container container-7">
<div class="item-wrap">1</div>
<div class="item-wrap">1</div>
<div class="item-wrap">1</div>
<div class="item-wrap">1</div>
</div>
</div>
</template>
<script>
export default {
name: "FlexeDemo",
};
</script>
<style scoped>
.container {
width: 300px;
height: 200px;
border: 1px solid red;
display: flex;
flex-wrap: wrap;
margin: 10px;
}
.container-1 {
/* 默认 */
}
.container-2 {
align-content: flex-start;
}
.container-3 {
align-content: flex-end;
}
.container-4 {
align-content: center;
}
.container-5 {
align-content: space-around;
}
.container-6 {
align-content: space-between;
}
.container-7 {
align-content: stretch;
}
.item-wrap {
margin: 10px;
border: 1px solid gray;
width: 100px;
height: 50px;
}
</style>
flex布局的内部item相关的属性
flex-grow属性
flex-grow属性决定了items如何扩展,可以是任意的非负数字(正小数,正整数,0),默认值为0。注意:flex-grow属性需要父容器主轴上有剩余空间时才会生效。另外,flex-grow的效果分为两种情况。
1、items的flex-grow总和sum大于1。设父容器在主轴方向剩余的空间为size。这时每个item扩展的尺寸为size*flow-grow/sum。也就是说将剩余空间平均分为sum份,每个item扩展空间为flow-grow份。
2、items的flex-grow总和sum小于1。设父容器在主轴方向剩余的空间为size。这时每个item扩展的尺寸为size*flow-grow。也就是每个item扩展空间为剩余空间的flow-grow倍,其中flow-grow为小数。
<template>
<div class="flex-wrap">
<h4>不设置flex-grow属性</h4>
<div class="container">
<div class="item-wrap">1</div>
<div class="item-wrap">2</div>
<div class="item-wrap">3</div>
</div>
<h4>flex-grow总和大于1</h4>
<div class="container">
<div class="item-wrap item-1">1</div>
<div class="item-wrap item-2">2</div>
<div class="item-wrap item-3">3</div>
</div>
<h4>flex-grow总和小于1</h4>
<div class="container">
<div class="item-wrap item-4">1</div>
<div class="item-wrap item-5">2</div>
<div class="item-wrap item-6">3</div>
</div>
</div>
</template>
<script>
export default {
name: "FlexeDemo",
};
</script>
<style scoped>
.container {
width: 500px;
height: 100px;
border: 1px solid red;
display: flex;
flex-wrap: wrap;
margin: 10px;
}
.item-wrap {
border: 1px solid gray;
width: 100px;
height: 50px;
}
.item-1 {
flex-grow: 2;
}
.item-2 {
flex-grow: 2;
}
.item-3 {
flex-grow: 1;
}
.item-4 {
flex-grow: 0.2;
}
.item-5 {
flex-grow: 0.2;
}
.item-6 {
flex-grow: 0.1;
}
</style>
ps:items扩展后的最终size不能超过max-width/max-height。
pflex-shrinik: 缩小
flex-shrinik属性决定了items如何收缩,可以是任意的非负数字(正小数,正整数,0),默认值1。注意:flex-shrinik属性需要父容器主轴上空间不足时才会生效。另外,flex-shrinik的效果也分为两种情况。
1、items的flex-shrinik总和sum大于1。设items超出父容器的尺寸为size。这时每个item收缩的尺寸为size*flow-shrinik/sum。也就是说将超出的空间平均分为sum份,每个item收缩空间为flow-shrinik份。
2、items的flex-shrinik总和sum小于1。设items超出父容器的尺寸为size。这时每个item收缩的尺寸为size*flow-shrinik。也就是每个item收缩空间为超出空间的flow-shrinik倍,其中flow-shrinik为小数。
最后一例子的解释:因为收缩比例分别为0.2 0.2 0.1,超出空间为200,所以收缩尺寸分别为40 40 20,所以总共收缩了100,也就是说收缩之后还是超出了父容器的尺寸,所以会突出来一块。
flex-basis: 有效宽度
flex-basis用来设置item在主轴方向上的占据的空间。flex-basis的值为auto(默认值),具体的宽度数值。
<template>
<div class="flex-wrap">
<h4>不设置flex-basis属性</h4>
<div class="container">
<div class="item-wrap">1</div>
<div class="item-wrap">2</div>
<div class="item-wrap">3</div>
</div>
<h4>item总宽度小于父容器时设置flex-basis</h4>
<div class="container">
<div class="item-wrap item-1">1</div>
<div class="item-wrap item-2">2</div>
<div class="item-wrap item-3">3</div>
</div>
<h4>item总宽度大于父容器时设置flex-basis</h4>
<div class="container">
<div class="item-wrap item-4">1</div>
<div class="item-wrap item-5">2</div>
<div class="item-wrap item-6">3</div>
<div class="item-wrap item-6">4</div>
<div class="item-wrap item-6">5</div>
</div>
</div>
</template>
<script>
export default {
name: "FlexeDemo",
};
</script>
<style scoped>
.container {
width: 500px;
height: 100px;
border: 1px solid red;
display: flex;
margin: 10px;
}
.item-wrap {
border: 1px solid gray;
width: 100px;
height: 50px;
}
.item-1 {
flex-basis: 200px;
}
.item-4 {
flex-basis: 200px;
}
</style>
可以看到设置了flex-basis属性之后,在父容器空间充足时,会展示flex-basis属性设置的宽度。在父容器空间不足时,会按照flex-basis的值和其他item一块进行压缩。
flex属性
flex属性是flex-grow||flex-shrink||flex-basis的简写,flex属性可以指定1个,2个或者3个。
1、flex属性设置一个值的情况:值必须满足以下情况中的一个
(1)一个无单位的数,会被当做flex-grow处理
(2)一个有效的宽度(或者高度)值,会被当做flex-basis处理
(3)关键字none,auto或者initial
2、flex属性设置两个值的情况:第一个值必须为一个无单位的数值 ,并且会被当做flex-grow处理,第二个值必须满足以下情况中的一种
(1)一个无单位的数,会被当做flex-shrink处理
(2)一个有效的宽度,会被当做flex-basis的值
3、flex属性设置三个值的情况
第一个值必须为一个无单位的数值,被当做flex-grow处理。
第二个值必须为一个无单位数,会被当做flex-shrink处理。
第三个值必须为一个有效的宽度值,会被当做flex-basis处理。
align-self: 覆盖container align-items 属性
align-self属性是设置在item元素上的,可以覆盖父元素设置的align-items属性
<template>
<div class="flex-wrap">
<h4>不设置align-self属性</h4>
<div class="container">
<div class="item-wrap item-1">1</div>
<div class="item-wrap item-2">2</div>
<div class="item-wrap item-3">3</div>
</div>
<h4>为某个item设置align-self属性</h4>
<div class="container">
<div class="item-wrap item-1">1</div>
<div class="item-wrap item-2">2</div>
<div class="item-wrap item-3 item-sleft-wrap">3</div>
</div>
</div>
</template>
<script>
export default {
name: "FlexeDemo",
};
</script>
<style scoped>
.container {
width: 400px;
height: 200px;
border: 1px solid red;
display: flex;
flex-wrap: wrap;
margin: 10px;
align-items: center;
}
.item-wrap {
margin: 10px;
border: 1px solid gray;
width: 100px;
height: 50px;
}
.item-1 {
height: 30px;
}
.item-2 {
height: 100px;
}
.item-3 {
height: 70px;
}
.item-sleft-wrap {
align-self: flex-end;
}
</style>
可以看到设置了align-self属性的item就不在遵循父容器align-items属性设置的对齐规则,只遵循item本身的对齐规则。
order 排序
order是给item进行排序的,默认值为0,数值越小越靠前。
<template>
<div class="flex-wrap">
<h2>不设置order属性</h2>
<div class="container">
<div class="item-wrap">1</div>
<div class="item-wrap">2</div>
<div class="item-wrap">3</div>
</div>
<h2>设置order属性</h2>
<div class="container">
<div class="item-wrap item-1">1</div>
<div class="item-wrap item-2">2</div>
<div class="item-wrap item-3">3</div>
</div>
</div>
</template>
<script>
export default {
name: "FlexeDemo",
};
</script>
<style scoped>
.container {
width: 400px;
height: 100px;
border: 1px solid red;
display: flex;
flex-wrap: wrap;
margin: 10px;
}
.item-wrap {
margin: 10px;
border: 1px solid gray;
width: 100px;
height: 50px;
}
.item-1 {
order: 10;
}
.item-2 {
order: 3;
}
.item-3 {
order: 7;
}
</style>
那些Flex布局的坑
flex:1失效
描述:当子元素设置超出不换行时,若子元素宽度大于父元素的宽度时,flex:1失效
<template>
<div class="flex-wrap">
<div class="item-wrap1">
<p class="p-wrap">
弹性布局弹性布局弹性布局弹性布局弹性布局弹性布局弹性布局弹性布局弹性布局弹性布局弹性布局
</p>
</div>
<div class="item-wrap2">
<p class="p-wrap">子元素子元素子元素子元素子元素</p>
</div>
</div>
</template>
<script>
export default {
name: "FlexeDemo",
};
</script>
<style scoped>
.flex-wrap {
width: 500px;
border: 1px solid red;
display: flex;
}
.item-wrap1 {
flex: 1;
background-color: aqua;
}
.item-wrap2 {
flex: 1;
background-color: blueviolet;
}
.p-wrap {
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
</style>
解决方法:
给子元素添加width:0的属性
.item-wrap1 {
flex: 1;
width: 0;
background-color: aqua;
}
.item-wrap2 {
flex: 1;
width: 0;
background-color: blueviolet;
}
ps:如何主轴是垂直方向,就需要设置height。