本文中大部分内容摘自理解弹性盒:必知必会一文。
一个偶然的机会,看到理解弹性盒:必知必会一文。拜读之后,收获颇丰,做为新手,摘抄如下,为免忘却,立此flag。
如同玩游戏要感谢汉化组、看电影要感谢字幕组一样,首先必须要感谢翻译人员,感谢您的劳动,感谢您的付出。
为什么要使用Flexbox?
Flexbox的作用就是为文档中元素的布局、对齐和分配空间提供一种有效的方式。即使视口和元素的大小是动态变化的或未知的,也能很好地适应。
如何使用Flexbox?
最基本的使用
首先要记住两个关键词:
- 弹性容器(Flex Container)
指的是设置了display: flex
的父元素。 - 弹性项目(Flex Item)
指的是弹性容器内的子元素。
直说吧,要使用Flexbox或者触发它,首先要定义一个弹性容器。举个例子:
页面上是这样显示的:
然后,我们添加上flexbox
样式:
ul {display: flex;}
页面显示如下:
很神奇啊。恭喜你,上道了,你已经在使用Flexbox了。
使用弹性容器的属性,更轻松地达到目的。
将父元素设置为弹性容器后,我们就可以在弹性容器上使用下面这6个属性了:
flex-direction
flex-wrap
flex-flow
justify-content
align-items
align-content
flex-direction
flex-direction
属性就是让你决定弹性项目如何布局。要么是水平排放,要么是垂直排放,要么是在两个方向上相反排放。
它的格式如下:
ul {
flex-direction: row || column || row-reverse || column-reverse;
}
其实,水平和垂直都不是弹性盒的世界中方向的叫法。从技术上讲,它们被描述为主轴(main axis)和侧轴(cross axis)。
主轴的默认方向是水平的,从左到右。侧轴的默认方向是垂直的,从上到下。即使没有显式设置flex-direction
属性,它也会采用默认值row
。
flex-wrap
flex-wrap
属性就是控制弹性项目换行的。
它的格式如下:
ul {
flex-wrap: wrap || no-wrap || wrap-reverse;
}
flex-wrap
属性默认被设置为no-wrap
,其实就是告诉弹性容器把全部弹性项目都放在一条线上,别给老子换行。
flex-flow
flex-flow
是flex-direction
跟flex-wrap
的合体。
是的,你没有看错,它们合体了!flex-flow
是个合体的产物!!Oh My God!!!
为了照顾思想单纯的读者,我再啰嗦几句,解释一下:flex-flow
是flex-direction
和 flex-wrap
的简写属性,同时带有这两个属性的值。Look,看图:
来,做个游戏,代码如下:
- 1
- 2
- 3
- 4
- 5
页面如图所示:
然后,我们给ul
添加flex-flow
样式:
ul {
width: 120px;
display: flex;
flex-flow: row-reverse wrap-reverse;
border: 1px solid #c00;
}
之后,页面就成这样了:
做完这个示例,我的内心其实是崩溃的。之前,在一个项目里,有过实现类似这种布局的需求,当时我是用js实现的,其中还用到了
Math
来计算当前元素在哪一行、哪一列,然后设置它的偏移位置...,哎,尘满面,鬓已霜,泪千行。
justify-content
justify-content
属性类似text-align
,它的作用就是定义弹性项目如何在主轴上对齐。 注意一下,它是控制主轴方向的对齐。
它的格式如下:
ul {
justify-content: flex-start || flex-end || center || space-between || space-around
}
align-items
align-items
和justify-content
类似,也是定义弹性项目的对齐方式。唯一的区别是:它是控制侧轴方向的对齐。
它的格式如下:
ul {
align-items: flex-start || flex-end || center || stretch || baseline
}
这里要注意flex-start
和baseline
,它俩就像美猴王和六耳猕猴一般,有细微的差别,不大好分辨。
眼神,注意眼神,眼神真的很重要!
不废话了,有图有真相,才有说服力。
align-content
align-content
用于多行,它的作用是控制在多行弹性容器中的弹性项目的对齐方式。
除了没有baseline
值以外,它的取值与align-items
相同。
使用弹性项目的属性,一样更轻松地达到目的。
有了弹性容器之后,我们就可以在弹性项目上使用下面这4个属性了,来了,巴啦啦小魔仙:
order
flex-grow
flex-shrink
flex-basis
order
order
的作用就是对弹性容器内的弹性项目重新排序。
通俗地讲,就是将一个弹性项目从一个位置移动到另一个位置,就像可排序列表。
貌似是个挺普通的功能,不过,这玩意儿的厉害之处在于不影响源代码,也就是说,HTML源代码中的弹性项目的位置是不用动的。
order
属性的默认值是 0。它可以是负值,也可以是正值。弹性项目是根据order
属性的数字值,从最低到最高来重新排序的。
好了,上代码:
- 1
- 2
- 3
- 4
- 5
效果如图所示:
然后,添加order
属性:
li:nth-child(1) {order: 1;}
效果就变成这样了:
之所以这样,是因为刚才给第一个li元素设置的order为1,而其他弹性项目的order默认都是0,所以,按照由低到高的顺序,原本是第一个的li元素,却出现在了弹性容器末尾。
你看见的不一定都是真的,就像魔术一样。
flex-grow
flex-grow
的作用就是控制弹性项目在有多余空间的时候,进行伸展。
它的取值是从0到任何正值。默认情况下是0,意思是说弹性项目不会伸展以填满整个可用空间。我们可以把它的取值想像成一个开关,默认为0就是把开关关闭了。
举个例子说明一下吧,有这样的代码:
- 1
- 2
就有这样的页面:
然后,我们加一行代码,把第一个li
的开关打开:
li:nth-child(1) {flex-grow: 1;}
这样,第一个li
就把剩下的空间占满了:
然后,我们再加一行代码,把第二个li
的开关也打开:
li:nth-child(1) {flex-grow: 1;}
li:nth-child(2) {flex-grow: 5;}
结果变成了这样:
奇怪吗?
用一句话解释一下:弹性项目的宽度是根据flex-grow
值的比例来计算。上边的第一个li
和第二个li
按照1:5的比例,把空间瓜分了。
flex-shrink
flex-shrink
的作用跟flex-grow
正相反,它是控制弹性项目在有空间不足的时候,进行收缩。
跟上边的flex-grow
类似,它的取值也是从0到任何正值。但它的默认值为1,开关是打开的,就是说在必要时会收缩弹性项目。
flex-basis
flex-basis
的作用就是在用flex-grow
或者flex-shrink
属性调整弹性项目的大小,以适应容器与否之前,指定一个弹性项目的初始大小。
它的默认值是auto
,也就是根据内容的大小,自动计算宽度。其它的取值可以是百分比 || em || rem || 像素
等。
注意,如果要把flex-basis
属性设置为基于零的值,也要把单位带上。要用flex-basis: 0px
,不能只是flex-basis: 0
。
flex
又一次,flex
是个合体。
flex
简写可以让我们一次就设置好flex-grow
、flex-shrink
和flex-basis
属性。
只要合适,我建议用 flex 简写一次设置所有三个属性。
断断续续写到了这里,也该收尾了。建议在项目中使用之前,仔细读读理解弹性盒:必知必会这篇文章,里边的介绍非常详细,其中的音乐应用示例很精彩,多掌握些跟flexbox相关的知识,以备不时之需。
总之,用flexbox来进行元素的布局和控制,非常省事儿,效率很高。
用过之后,你会很有成就感。
不过,归根结底,用哪种技术并不重要,能解决问题才重要。
好了,就这样吧。