1 CSS布局
就我个人目前写过的几个前端应用来看,css的重点主要在两个方面:
- 标签美化
- 页面布局
至于其它,比如动画效果之类的东西,实际前端项目中用的其实并不多,因为这些东西虽然可能稍微复杂一点,但其适用性却是非常广泛的。
因此只要你没有太大的定制化需求,那么直接开源库使用就行了。
比如当网页加载时可能会看到“转圈”的图标,这种图标你完全是不需要自己去写的,直接找相关的开源库复制一份即可,毕竟这种东西太通用了。
其中标签美化是基础,也就是前一章 CSS入门指南我们所学到的各种css属性,用于设置标签的颜色、大小、状态等等。
而页面布局就是本章重要介绍的内容了。
css中布局也有很多种类,比如前文提到的“定位”、“浮动”等等,其实也可以算是布局的一种。
不过本文的重点并不是它们,而是更为通用、近乎万能的flex
布局。
1.1 flex布局
flex
布局是目前最常用的布局方式,你目前所看到的这个网页,可以说超过九成的内容都是我用flex
布局写出来的,由此可见flex
布局的强大,它基本能满足你绝大部分的需求。
对于没有使用flex
的普通标签元素来说,它们是根据前文基础章节中介绍过的“显示模式”来默认布局的,也就是前面提到过的“块模式”“行内块模式”“行内模式”。
例如下面这个例子:
所以上面的渲染结果可以这样解释:
p
标签默认为块模式,所以占据第一行。img
与span
标签分别为行内块与行内模式,共同占据第二行,并且该行的高度由最高的img
所决定。
如果不使用flex
,那么正常来说你如果想要布局,那就只能调整各个元素的宽高、设置其“显示模式”,才能最终达到效果。
比如现在我想要让三个标签处于同一行,同时p
、span
标签各自占据200px
宽度在两侧,而img
标签占据中间剩余的全部宽度。
这种需求是非常常见的,比如你目前所看到的文章页面,左边的空白、右边的信息卡片就占据了固定大小,而中间的文章标签就占据了页面剩余的宽度。
这种情况下,甚至你是很难使用传统的布局方式实现的,但flex
布局却可以轻松做到这一点:
此时就发挥div
容器标签的作用了,由于它本身不包含任何东西,所以是最适合使用布局的标签。
比如这里,我希望让三个标签放到一行,那么就先将这三个标签都放到一个div
标签之中,然后再设置该div
标签为flex
,也就是上图中的1号代码。
注意,设置flex
与前面设置“显示模式”使用的都是display
,只是这里让其属性等于flex
即可。
一旦将其设置为了flex
,此时其内部的“直接子标签”会全部默认转换为“行内块模式”。
这也是为什么这里span
原本应该是行内模式,这里也能为其设置宽高的原因,同时也是p
标签为什么没有占据一行的原因。
当设置完p
、span
两个标签的宽度,就来到了第4步,设置img
属性flex-grow
,并让其值为1
,那么此时它就会占据其剩余的所有宽度,甚至此时你调整窗口的宽度,中间img
宽度也会随之发生变化。
其原理我们后面会详细解释,这里的重点是,我仅仅通过这么几句代码就实现了这样一个非常常见的布局功能,这便是flex
布局的强大之处。
1.2 快速理解
flex
之所以能够轻而易举的完成这一看似很麻烦的事情,就在于它实现了“弹性盒子”这一概念。
当然,我们并不需要知道它是怎么实现的,而只需要知道它给我们带来的效果是什么,以及如何快速的学会使用它。
经我个人对其大量使用的经验来看,你只需要明白以下两个概念就足以学会使用flex
完成各种复杂的界面布局:
- 一旦某个元素设置了
flex
布局,那么你基本就可以将其内部看做为“一行”或“一列”,该行(列)的空间将由其所有“直接子标签”占据,并且所有“直接子标签”都将被默认设置为“行内块”显示模式。 - 一旦设置了
flex
布局的元素尺寸发送变化,那么会立即影响其内部的“直接子标签”尺寸变化,这也算是“弹性盒子”概念基本用法的可视化。
上面的第一点从前面示例中已经可以看出一二了,一旦外层的div
标签设置为了flex
布局,那么该div
标签将变成“一行”,同时其内部p
、img
、span
三个标签都将成为“行内块”模式。
至于第二点,如果你亲手敲了上面的代码并实际试过,那么体会能更加深刻。
因为div
标签默认是块模式,其宽度默认等于父标签的宽度,由于其在最外层,实际上也就等于浏览器窗口的宽度,此时只要你调整浏览器窗口宽度,那么就等价于在调整div
标签的宽度。
其内部的img
标签此时就会实时计算父标签宽度减去p
、span
这两个标签宽度所剩余的宽度作为自己的宽度来显示。
只不过上面示例中使用的是行,这是flex
所默认的,而我们也可以调整其方向为列:
由于此时方向为“列”,而div
标签本身没有高度,它的高度完全由其最高的子标签所“撑起来”的,所以为了方便,我这里给它设置了一个400px
的高度。
而调整为列的方式就是使用第二步中的flex-direction
属性,并将其设置为column
即可。
在第三步中,由于p
标签默认带有上下外边距,为了方便大家观察,这里我将其外边距设置为了0
。
并且要注意,由于此时是“列”,所以要设置的应该是其高度,和第五步一样。
当然,你也可以设置宽度,我这里只设置影响布局的元素。
然后在第四步中要注意,前面我并没有设置它的尺寸,在某些情况下是会出问题的,所以这里我也为其设置了高度为100px
,至于flex-grow
依旧还是1
。
但从最终的效果上来看,img
高度并不是p
与span
标签一样高的100px
,具体来说是它们的两倍,即200px
,也就是整个div
标签高度400
减去p
、span
标签高度之和200px
得到的结果,这便是flex-grow
的作用所在。
1.3 flex-grow
就我个人经验来看,flex-grow
属性是非常常用的,所以就作为第一个flex
布局效果讲解。
正如其名字grow
,意为“生长”,它的作用其实比我们上面的用法要复杂一些。
因为前面提到过,一个flex
布局的盒子你大多数情况下都是可以直接将其看成“一行”或“一列”的,以“行”举例,如果盒子的宽度为400px
,而其“直接子标签”的宽度之和只有200px
,此时就会出现空出200px
的情况。
列与行的使用方法完全一样,只是换了一个方向,后文全部以“行”举例。