当前位置: 首页 > Web前端 > CSS

JavaScript五十问——CSS中Grid与FlexBox的比较(上)

时间:2023-03-31 01:30:21 CSS

前言春节假期有幸阅读了张新旭的两篇关于Flex和Grid的文章(见参考资料),收获颇丰;在开发过程中,经常使用Flex布局,很少使用Float和inline-box方式;这次春假学习了Grid,深深感受到了Grid的易用性和便捷性。借此机会总结一下Grid和Flex的使用。BrowserSupportFlexBrowserSupportGrid浏览器支持可见一斑。与Grid相比,Flex在PC端和移动端都得到了很好的支持,而Grid对移动端的支持还差强人意。FlexBox在弹性布局中,有两个概念需要牢记:容器和元素。在html标签中声明样式:display:flex或display:inline-flex声明了一个flex容器,这个容器中的元素就是flex元素。flex所有的样式属性分为容器属性和元素属性两大类,它们都作用于flex元素,但是flex容器中声明的属性支配着所有flex元素的整体显示和排列,而flex的属性elements代表单个元素的排列。接下来按照上面脑图的思路,依次介绍flex的属性。声明:老师下面的所有元素都遵循以下HTML结构和基本样式1

2
3
4
...容器属性flex-directionflex-direction,顾名思义就是控制flex的整体布局方向元素的属性,包含四个属性:1.row//默认从左到右2.row-reverse//从右到左3.column//从上到下4.column-reverse//从下到上1、flex-direction:row2.flex-direction:row-reverse3.flex-direction:column4.flex-direction:column-reverse以上四张图分别是在容器(.container)上设置flex-direction得到的效果四个属性。flex-wrapflex-wrap是控制元素是换行显示还是单行显示。它有三个属性1.no-wrap//默认不换行2.wrap//换行3.wrap-reverse//换行倒序为了更明显的看区别,我特地加了一个难看的边框。在容器属性中添加flex-wrap,分别设置三个wrap属性1.flex-wrap:no-wrap2.flex-wrap:wrap3.flex-wrap:wrap-reverse这里需要注意no-wrap属性:如果容器元素设置了最小宽度,且元素最小宽度之和>父容器宽度,则显示内容溢出。如果容器元素没有最小宽度或者最小宽度之和<父容器的宽度,则容器元素收缩并填充父元素。上面的no-wrap例子中,没有设置子元素的最小宽度,读者可以自行添加验证。设置wrap-reverse属性后,我们可以看到其换行结果在行的维度上与wrap相反。读者可以尝试将flex-direction设置为column或者其他非默认值,然后查看不同flex-wrap值下的显示,会有不同的结果。flex-flowflex-flow是flex-direction和flex-wrap的统一写法,语法为flex-flow:<'flex-direction'>||<'flex-wrap'>justify-contentjustify-content控制flex元素的水平方向Alignment,它一共有属性:1.flex-start//默认值默认左对齐2.flex-end//右对齐3.center//中心下方以空格开头的属性是描述剩余空间的行4.space-around//剩余空间包围每个子元素5.space-between//剩余空间为只分布在子元素之间,两端元素周围没有剩余空间6.space-evenly//剩余空间均匀分布在元素两端和下面例子之间:1.flex-start2.flex-end3.center4.space-between5.space-around6.space-evenly为了更清楚的看到不同空间下多余的空间分布特征,我用红框框住每个属性下剩余的元素。不言而喻,几个属性分布是不同的。align-contentalign-content对应justify-content,表示元素在垂直方向的分布。这种分布方式只能在多行的情况下高亮显示,在单行的情况下设置该属性无效。与justify-content相比,它多了一个stretch属性,代表拉伸,默认属性。1.stretch2.flex-start3.flex-end4.space-between5.space-around6.space-evenly可以看出其排列方式与justify-content的逻辑一致,只是方向不同。由于align-items在多行的情况下控制元素的排列,所以在单行的情况下会有元素的排列。align-items控制单行情况下元素的排列。有5个属性:1.stretch默认属性,会将元素的高度拉伸到父容器的高度2.flex-start顶部对齐3.flex-end底部对齐4.baseline基线对齐5.center居中注意:以上所有展示的例子都是其他属性的默认展示。如果改变其他属性(如:flex-direction和flex-wrap)的值,会有不同的显示效果。元素属性orderorder属性可以控制flex元素的排列顺序。Flex元素会按照从小到大的顺序排列。order的默认值是0,所以如果想让一个元素在前面,只需要设置它的order值,设置成小于0的值即可。flex-growflex-grow控制元素的宽度,默认为0,当容器中有剩余空间时,flex-grow不为0的元素将按照以下规则展开:容器中只有一个元素设置了flex-grow1,flex-growvalue>=1,则此元素将填充容器的剩余空间。容器.item:first-child{order:2;flex-grow:1;}2、flex-grow在0-1之间,则当剩余空间乘以flex-grow值时,该元素将占用更多空间。.container.item:first-child{order:2;flex-grow:0.5;}.container{显示:flex;justify-content:space-around;//如果子元素的flex-grow<1,则该属性保持有效}.container.item:first-child{order:2;flex-grow:0.5;}容器中有多个元素设置了flex-grow1,所有元素的flex-grow值之和>1将占据所有剩余空间,剩余空间的比例occupied是每个元素设置的flex-grow的比例。2.所有元素的flex-grow值之和<1所占剩余空间的比例就是每个元素的felx-grow值的比例。flex-shrinkflex-shrink的属性与flex-grow的属性相反。指空间不足时元素的收缩率。默认值为1;其核心思想与grow相同,这里不再赘述,读者可以自行查看。flex-basisflex-basis定义了分配剩余空间前每个元素的默认宽度,默认为auto,即元素的宽度;当flex-basis的值不为auto时,其显示优先级高于元素的宽度。flexflex属性是以上三个属性的统称,语法为:flex:none|汽车|[<'flex-grow'><'flex-shrink'>?||<'flex-basis'>]flex翻译成中文就是Elastic,所以这个属性就是说明当空间过多或者空间不足时,各个元素是如何分布的。align-selfalign-self,顾名思义,就是确定单个元素的垂直分布状态;它在父容器中对应的属性是algin-items;它的属性值和align-items是一致的,但是多了一个默认属性auto,也就是说它和父元素的auto-items值是一样的。看一个例子:对应的css代码:.container{display:flex;align-items:center;}.container.item:nth-child(2n+1){order:2;弹性增长:2;align-self:flex-start;}我给父元素加上align-items属性让flex元素居中对齐,给子元素加上align-self属性让奇数子元素向上对齐。当有多行,但是没有设置align-content时,我们可以看到每个设置了align-self属性的子元素都会根据align-self属性显示在当前行,但是当align-content设置属性后,其align-self属性就失效了(见下图)。对应代码:.container{display:flex;对齐内容:居中;flex-wrap:wrap;}.container.item:nth-child(2n+1){order:2;弹性增长:2;align-self:flex-start;}总结这里对flex布局进行了总结,一些类似的属性没有示例,需要读者自行验证。与其他解决方案相比,flex布局更简洁、更语义化;最明显的是,它可以轻松解决我们在面试过程中经常遇到的多栏布局和垂直居中问题。事实上,仔细阅读flex。与Grid相比,它还是更加线性,即把所有的元素都看成一条线,确定这条线的方向,并垂直居中。当这一行超出父元素的范围时,我们如何处理。所以flex虽然看似属性很多,但是经过合理的理解还是很简单的。这是glex和Grid的第一部分。主要介绍flex。我们将在下一部分看到Grid的相关属性和应用。参考文献张新旭:展示给自己:flex布局教程阮一峰:Flex布局教程