前言
本系列文章主要针对了常用的几种css布局进行需求分析与要点详解,后续将不断对布局实现方案进行补充。本文主要介绍了水平居中、垂直居中和水平+垂直居中布局方案。
1.水平居中
首先分析最简单的水平居中,基本布局如下,两个div的嵌套。需要实现的是子div相对父div水平居中。
1 | <div class="parent"> |
1.1 方案一
1 | .parent{ |
这个方案十分简单,MDN中的描述是,text-align控制行内内容如何相对它的块父元素对齐。
而将子div渲染成一个inline-block盒子可以保证它在父元素中的布局受text-align且能直接修改他的宽高属性。
优点:兼容性高,实现简单。
缺点:所有行内元素都会受text-align的影响而居中;且它是一个可继承的属性,若不想影响到更深层级的元素,需要在子元素中重新设置text-align属性。
1.2 方案二
1 | .parent{ |
这个方案也很简单,当左右外边距为auto时,会自动分配父元素剩余宽度均分到左右边距中。注意:此时子元素不能是行内元素,否则margin属性是不会生效的。
优点:兼容性高,实现简单。
缺点:没有很明显的缺点,如果要说,那就是如果子元素脱离了文档流,那么margin属性会失效。
1.3 方案三(不推荐)
1 | .parent{ |
或者
1 | .parent{ |
这个方案较前面两个更为复杂,给人一种杀鸡焉用宰牛刀的感觉。强烈不推荐使用。
优点:没有明显的优点。
缺点:较复杂,使用相对布局和绝对布局反而会留下更大的隐患;transform属性兼容性不强。
1.4 方案四(flex/grid)
1 | .parent{ |
父元素使用flex(grid)布局并设置主轴上(网格行轴)元素的排列方式为居中来实现水平居中,会带来一个问题就是主轴(网格行轴)上所有子元素都会居中。
优点:实现简单。
缺点:兼容性不强。
2.垂直居中
下面分析稍微复杂一些的垂直居中,基本布局同水平居中。需要实现的是子div相对父div垂直居中。
1 | <div class="parent"> |
2.1 方案一
1 | .parent{ |
根据MDN的描述,table-cell让一个元素表现为像<td>元素一样,也就是一个单元格。然后我们使用vertical-align属性来指定单元格内元素的垂直对齐方式。(这里涨姿势了,原来vertical-align不仅能用来指定行内元素(inline)也能用来指定表格单元格(table-cell)元素的垂直对齐方式。)
优点:兼容性比较好。
缺点:为了实现垂直居中效果而把父元素变成一个单元格,从语义上来看很不友好;vertical-align属性也是具有继承性,同上text-align。
2.2 方案二
1 | .parent{ |
或者
1 | .parent{ |
类似水平居中的方案二,也是比较常见的一种实现方式。
优点:没有明显的优点。
缺点:transform兼容性不强。需要使用相对布局和绝对布局实现。
2.3 方案三 (较推荐)
1 | .parent{ |
具体解析我打算放到水平+垂直居中的方案三中去说,这里先吊个胃口。比起方案二,方案三没有了```transform``属性,兼容性更好。
优点:兼容性好。
缺点:需要使用相对布局和绝对布局实现。
2.4 方案四(flex/grid)
1 | .parent{ |
父元素使用flex(grid)布局并设置项目在其包含块中在交叉轴(块轴)上的对齐方式为居中,会带来一个问题就是交叉轴(块轴)上所有项目都会居中。
优点:实现简单。
缺点:兼容性不强。
3.水平+垂直居中
理论上,是不是把上面的水平居中和垂直居中全部排列组合一遍就可以得到NxM种方案?当然不是,这里也不浪费时间去做组合,直接给出一些可行的方案。同样,基本布局如下。需要实现的是子div相对父div水平+垂直居中。
3.1 方案一
1 | .parent{ |
该方案为水平居中方案一和垂直居中方案一的组合,也同样继承了它们的缺点和优点。同样的子元素不能是行内元素。
优点:兼容性好。
缺点:语义。
3.2 方案二
1 | .parent{ |
或者
1 | .parent{ |
该方案为水平居中方案二和垂直居中方案二的组合。
优点:能用就行。
缺点:transform兼容性不强。需要使用相对布局和绝对布局实现。
3.3 方案三(推荐)
1 | .parent{ |
这个方法并不是我原创的,而是在《CSS世界》中强烈推荐的一种方法。其核心就在于掌握格式化宽高的计算公式。
父元素的宽 = 子元素left + 子元素right + 子元素左右margin + 子元素左右border + 子元素左右padding + 子元素宽
父元素高 = 子元素top + 子元素bottom + 子元素上下margin + 子元素上下border + 子元素上下padding + 子元素高
因此,当子元素top/right/bottom/left、border、padding、宽高都确定时,margin:auto会将剩余父元素空间均分,达到居中的效果。
优点:兼容性好。
缺点:依然需要使用相对布局和绝对布局实现。
3.4 方案四(flex/grid)
1 | .parent{ |
这个方法综合了1.4和2.4,,会带来一个问题就是所有项目都会水平且垂直居中。
优点:实现简单。
缺点:兼容性不强。
后记
这些布局比较基础,但是依然有值得学习的思想。下文将对更加复杂也更加具有实际意义的几种布局进行分析。