flex布局踩过的坑
虽然我对flex的基本用法已经比较了解,但是在使用过程中还是会经常遇到些大大小小的问题。这篇博客在对flex的基本概念做一个简单的回顾后,将重点记录我在使用flex时踩过的一些坑,这篇博客也会一直更新。
本文结构:flex布局基本概念flex containerflex item踩过的坑flex container的高度问题flex-direction与justify-content、align-items的对应关系一、flex布局基本概念首先要了解flex的两个最基本的概念,容器(flex container)和项目(flex item),flex container包含flex item。通过对flex container和flex item进行flex布局,可实现多种多样的布局效果。
1、flex containerflex container为容器,主要对各个flex item的排列方向、排列顺序、对齐方式进行设置。
flex item为项目,主要对item本身的一些特性进行设置。
其实这是一个很简单的东西,只是我经常忘记给flex container设置高度,导致使用align-items属性的时候,总是得不到我想要的结果。现在我举一个“用户头像”的例子,当鼠标悬浮到用户头像上时,在用户头像的正中间出现“编辑”两个字,代码如下:
// html<body> <div class='97ff-647b-6633-dc21 user'></div></body>
// css.user{ margin-top:40px; height:200px; width:200px; background-image: url('http://opjc44vzf.bkt.clouddn.com/17-5-6/32601215-file_1494081396100_da5d.jpg'); background-size:200px 200px; border-radius:50%; box-shadow:0px 0px 6px 1px rgba(0,0,0,0.3) inset; overflow:hidden;}.user:hover::after{ content:'编辑'; color:#ffffff; font-size:30px; font-weight:bold; cursor:pointer; display:flex; justify-content:center; align-items:center;}
结果:
我们把鼠标悬浮在头像上:
咦?为什么蓝色的两个字“编辑”没有在头像的正中间呢?你有没有看出什么问题?我设置了align-items:center
,那不就是让它在竖直方向居中么?为什么在竖直方向没有居中?
其实它在竖直方向已经居中了,不信?我们给这个flex container设置一个灰色背景,来看看这个flex container到底在哪里:
.user:hover::after{ background:#ddd;}
结果:
看到flex container的背景了吗?
在上面这段代码中,由于没有给flex container设置高度,flex container自动计算高度,就会出现这种情况。
我们现在给这个flex container设置一个高度:
.user:hover::after{ height:inherit;}
结果:
再把flex container的背景去掉:
其实这是一个很简单的东西,写代码的时候注意一下,把flex container的高度加上就行了,不要像我一样神经大条... [ 允悲 ]
2、flex-direction与justify-content、align-items的对应关系上图来自阮一峰老师的“Flex 布局教程:语法篇”,网上也大致都是类似的图解,所以我就理所当然地以为,横着的方向就是主轴,竖着的那条就是侧轴;从左到右是主轴的方向,从上到下是侧轴的方向。可是很快,在使用justify-content、align-items时就出现了问题。通过查阅资料才发现,主轴、侧轴的位置和方向都是与flex-direction的设置有关!我们知道,flex-direction有以下几种取值:row/row-reverse/column/column-reverse。当flex-direction取值不同时,主轴和侧轴的位置、方向都是不同的。接下来,我们设置flex container的justify-content:flex-start
、align-items:flex-end
,改变flex-direction的值来看结果。
这是最常见并且默认的一种。在这种情况下,主轴和侧轴也是以最常见的方式排列。justify-content和align-items的各属性值对应的位置如下图所示。
举例:
<body> <div class='647b-6633-dc21-8468 parent'> <div class='6633-dc21-8468-6b81 child'></div> </div></body>
.parent{ width:300px; height:300px; background:#ddd; display:flex; justify-content:flex-start; align-items:flex-end; flex-direction:row;}.child{ width:100px; height:100px; background:pink;}
结果:
结果符合我们的预期。粉色div在justify-content的“flex-start”位置上,也在align-items的“flex-end”的位置上。
2) flex-direction:row-reverse在这种情况下,主轴方向相反,侧轴方向不变。justify-content和align-items的各属性值对应的位置如下图所示。
修改1)中的代码:
.parent{ flex-direction:row-reverse;}
结果:
我们看到,粉色div在justify-content的“flex-start”位置上,也在align-items的“flex-end”的位置上。
3)flex-direction:column在这种情况下,主轴与侧轴的方向交换。justify-content和align-items的各属性值对应的位置如下图所示。
修改1)中的代码:
.parent{ flex-direction:column;}
结果:
我们看到,粉色div在justify-content的“flex-start”位置上,也在align-items的“flex-end”的位置上。
4) flex-direction:column-reverse在这种情况下,主轴与侧轴的方向又发生了变化。justify-content和align-items的各属性值对应的位置如下图所示。
修改1)中的代码:
.parent{ flex-direction:column-reverse;}
结果:
我们看到,粉色div在justify-content的“flex-start”位置上,也在align-items的“flex-end”的位置上。
总结:主轴、侧轴的位置和方向根据flex-direction的不同而不同,并由此导致了justify-content和align-items的位置变化。在使用时一定要注意!!
使用flex遇到的坑就先记录到这里了,以后的坑以后再过来填。听说flex在移动端坑比较多,哈哈,但是我到现在还没遇到,看来还是要好好研究一下咯。
最后,给大家安利一个学习flex的小游戏Flexbox Froggy,可以加深对flex的认识,挺有趣的。
由于个人水平有限,博客错误之处,烦请指正!
前言
本篇文章进行学习css中的一个重点应用,布局样式为flex布局,相信你学习了解过display属性,position属性,float属性,但今天只学习新东西就是flex布局。
flex布局是什么
flex是flexible box的缩写,意思是弹性布局,代码样式如下:
.box { display: flex;}
Flexbox Layout模块是提供一个更有效的方式来布置,对齐和item之间在一个容器中分配的控件,即使它们的大小是未知的,或者是动态的,所以单词命名flex(弹性工作制的)
flex布局可以使容器更改其item的宽度,高度,以便最好地填充可用空间,或者收缩它们来防止溢出。flexbox布局使用比较合适应用程序的组件和小规模布局上。
在webkit内核的浏览器中,要加上-webkit前缀哦,代码格式如下:
.box { display: -webkit-flex; display: flex;}
当设置flex布局之后,子元素(item)的float,clear,vertical-align属性会失效。
学习前要先了解概念
flex container flex items
设置flex布局的元素为flex容器(flex container),简称为容器。它的所有子元素都是容器的成员,flex项目(flex item),简称为项目。那么请查看如下图,解析flex布局背后的主要思想。
如图可以看出,main axis是从main-start到main-end,交叉轴cross axis从cross-start到cross-end。
容器默认有两根轴的,水平的主轴main axis和垂直的交叉轴cross axis,从main-start到main-end叫(main start)主轴;从cross axis从cross-start到cross-end叫(cross axis)交叉轴
单个项目占据的主轴空间叫main size,占据的交叉轴空间叫cross size
container弹性容器:
.container { display: flex;}
items弹性项目:
容器的属性
flex-directionflex-wrapflex-flowjustify-contentalign-itemsalign-content
flex-direction属性决定的是主轴的方向,即是项目的排列方向
.box { flex-direction: row | row-reverse | column | column-reverse;}.flex-container { -webkit-flex-direction: row; /_ Safari _/ flex-direction: row;}.flex-container { -webkit-flex-direction: row-reverse; /_ Safari _/ flex-direction: row-reverse;}.flex-container { -webkit-flex-direction: column; /_ Safari _/ flex-direction: column;}.flex-container { -webkit-flex-direction: column-reverse; /_ Safari _/ flex-direction: column-reverse;}
其使用flex-direction的box格式如下:
// 水平.box { flex-direction: row; }// 水平倒置.box { flex-direction: row-reverse; }// 垂直.box { flex-direction: column ; }// 垂直倒置.box { flex-direction: column-reverse; }
.box { width: 400upx; height: 300upx; background-color: #007AFF; margin: 10upx;}.item { width: 80upx; height: 80upx; background-color: #1CBBB4; border: 1upx solid #FFFFFF;}
row:flex容器的主轴与当前写入模式的内联轴具有相同的方向。主开始方向和主结束方向分别相当于当前写入模式的开始方向和结束方向。
.box-row { display: flex; flex-direction: row;}
row-reverse: 与'row'相同,只是主开始方向和主结束方向交换了。
.box-row-reverse { display: flex; flex-direction: row-reverse;}
column: flex容器的主轴与当前写入模式的块轴方向相同。主开始方向和主结束方向分别相当于当前书写模式的前/头和后/脚方向。
.box-column { display: flex; flex-direction: column;}
column-reverse: 与'column'相同,只是主开始方向和主结束方向交换了。
.box-column-reverse { display: flex; flex-direction: column-reverse;}
flex-wrap属性:根据伸缩容器中的可用空间,指定伸缩项是否换行以及它们换行到多行或多列的方向。
.box{ flex-wrap: nowrap | wrap | wrap-reverse;}.flex-container { -webkit-flex-wrap: nowrap; /_ Safari _/ flex-wrap: nowrap;}.flex-container { -webkit-flex-wrap: wrap; /_ Safari _/ flex-wrap: wrap;}.flex-container { -webkit-flex-wrap: wrap-reverse; /_ Safari _/ flex-wrap: wrap-reverse;}
flex-wrap: nowrap: 不换行。(所有弹性项目都将在一行上)
.box-flex-wrap-nowrap { display: flex; flex-wrap: nowrap;}
flex-wrap: wrap: 换行,第一行在上方。(弹性项目将从上到下缠绕在多行上)
.box-flex-wrap-wrap { display: flex; flex-wrap: wrap;}
wrap-reverse: 换行,第一行在下方。(弹性项目将从下到上缠绕在多行上)
.box-flex-wrap-wrap-reverse { display: flex; flex-wrap: wrap-reverse;}
flex-flow属性是flex-direction属性和flex-wrap属性的简写形式,默认值为row nowrap。
.box { flex-flow: <flex-direction> || <flex-wrap>;}.container { flex-flow: column wrap;}
.box-flex-flow-1 { display: flex; flex-flow: auto; // flex-flow: row nowrap;}
.box-flex-flow-2 { display: flex; flex-flow: row wrap;}
justify-content属性:指定在解析了任意灵活长度和自动边距后,伸缩项如何沿伸缩容器的主轴对齐。(定义了项目在主轴上的对齐方式)
.box { justify-content: flex-start | flex-end | center | space-between | space-around;}
flex-start
初始值。伸缩项目被打包在行首。第一个伸缩项的起始边被放置在伸缩容器的开始处。下一个伸缩项的起始边与第一个伸缩项的结束边按布局轴方向依次放置。所有沿布局轴保留的空间都放置在布局轴的末端。
.box-flex-justify-content-1 { display: flex; justify-content: flex-start;}
如图效果:
flex-end
弹性物品被打包到行尾。第一个伸缩项的结束边缘被放置在伸缩容器的末端。下一个伸缩项目的结束边缘与第一个伸缩项目的开始边缘按布局轴方向依次放置。沿布局轴剩下的所有空间都放置在布局轴的起点。
.box-flex-justify-content-2 { display: flex; justify-content: flex-end;}
如图效果:
center
弹性物品被打包在线的中间。flex项目在直线上放置冲洗彼此对齐线的中心,与等量的main-start边缘之间的空白行和第一项之间的线,主要目的的边缘线,最后一项。(如果剩余的空闲空间是负的,伸缩项将在两个方向上相等地溢出。)
.box-flex-justify-content-3 { display: flex; justify-content: center;}
如图效果:
space-between
弹性项目均匀地分布在这条线上。如果剩余的自由空间是负的,或者一行上只有一个flex项目,这个值与' flex-start '相同。否则,main-start保证的第一flex项目线的边缘放置充裕的main-start边缘线,最后一个flex项的主要目的利润边缘线放置充裕的主要目的边缘线,和其余的flex项目的分布之间的间距与任何两个相邻物品是一样的。
.box-flex-justify-content-4 { display: flex; justify-content: space-between;}
如图效果:
space-around
弹性项目均匀地分布在线中,在两端有一半大小的空间。如果剩余的自由空间是负的,或者一行上只有一个伸缩项,这个值与' center '相同。否则,行上的伸缩项的分布使行上任意两个相邻伸缩项之间的间距相同,并且第一个/最后一个伸缩项与伸缩容器边缘之间的间距为伸缩项之间间距的一半。
.box-flex-justify-content-5 { display: flex; justify-content: space-around;}
如图效果:
space-evenly:分配项目,以使任意两个项目之间的间距(以及到边缘的间距)相等。
align-items属性:指定伸缩容器中伸缩项的对齐值(垂直于由伸缩方向属性定义的布局轴)。
.box { align-items: flex-start | flex-end | center | baseline | stretch;}
修改item样式如图:
.item1 { width: 100upx; height: 120upx;}.item2 { width: 100upx; height: 130upx;}.item3 { width: 100upx; height: 140upx;}
flex-start:交叉轴的起点对齐。
.box-flex-align-items-1 { display: flex; align-items: flex-start;}
flex-end:交叉轴的终点对齐。
.box-flex-align-items-2 { display: flex; align-items: flex-end;}
center:交叉轴的中点对齐。
.box-flex-align-items-3 { display: flex; align-items: center;}
baseline: 项目的第一行文字的基线对齐。
修改item,以第一行文字的基线对齐,想如图效果,itme3-text顶部没有剩余空间,就被强迫这样了。如果有空间,以第一个为标准对齐,第一个item文本底线对齐。
.item1-text { padding: 5upx; width: 120upx; height: 120upx;}.item2-text { width: 120upx; height: 130upx;}.item3-text { padding: 15upx; width: 120upx; height: 140upx;}
.box-flex-align-items-4 { display: flex; align-items: baseline;}
stretch(默认值):如果项目未设置高度或设为auto,将占满整个容器的高度。
修改item,没有定义高度,如果有高度还是按照原来的高度呈现。
.item-noheight { width: 100upx; border: 1upx solid #FFFFFF;}
.box-flex-align-items-5 { display: flex; align-items: stretch;}
align-content属性:指定当与flex-direction属性定义的轴垂直的轴上有额外空间时,flex项目的行如何在flex容器内对齐。
align-content属性定义了多根轴线(多行)的对齐方式。如果项目只有一根轴线,该属性不起作用。
.box { align-content: flex-start | flex-end | center | space-between | space-around | stretch;}
flex-start:交叉轴的起点对齐
flex-end:与交叉轴的终点对齐
center:与交叉轴的中点对齐
space-between:与交叉轴两端对齐,轴线之间的间隔平均分布
space-around:每根轴线两侧的间隔都相等,轴线之间的间隔比轴线与边框的间隔大一倍
stretch:轴线占满整个交叉轴
项目的属性
orderflex-growflex-shrinkflex-basisflexalign-selforder属性定义项目的排序时,数值越小,排列越靠前,默认为0
.item { order: <integer>;}
flex-grow属性定义项目的放大比例,默认为0,如果还有存在剩余空间,也不会放大
如果所有项目的flex-grow属性都为1,那么它们将等分剩余的空间,如果一个项目的flex-grow属性为2,其他项目都为1,那么前者占据的剩余空间将比其他项目多一倍。
.item { flex-grow: <number>; /* default 0 */}
flex-shrink属性定义了项目的缩小的比例,默认为1,如果空间不足,该项目将缩小
如果所有项目的flex-shrink属性都为1,当空间不足时,都将等比例缩小,如果一个项目的flex-shrink属性都为0,其他项目都为1,则空间不足时,前者不缩小,负值对该属性无效。
.item { flex-shrink: <number>; /* default 1 */}
flex-basis属性:定义了在分配多余空间之前,项目占据的主轴空间main size,浏览器根据这个属性,计算主轴是否有多余空间。它的默认值为auto,即是项目的本来的大小。
.item { flex-basis: <length> | auto; /* default auto */}
flex属性是flex-grow,flex-shrink和flex-basis的简写,默认值为 0 1 auto ,后两个属性可选。
.item { flex: none | [ <'flex-grow'> <'flex-shrink'>? || <'flex-basis'> ]}
该属性有两个快捷值:auto(1 1 auto)和none(0 0 auto)
align-self属性:允许单个项目有与其他项目不一样的对齐方式,可覆盖align-items属性,默认值为auto,表示继承父元素的align-items属性,如果没有父元素,则等同于stretch。
.item { align-self: auto | flex-start | flex-end | center | baseline | stretch;}
发表评论