成品
成品

上图是个很简单的三栏+等高布局,HTML 如下,怎么看都不是很难弄。

1
2
3
4
5
6
7
<header>Header</header>
<div>
<div class="left">Left</div>
<div class="center">Center</div>
<div class="right">Right</div>
</div>
<footer>Footer</footer>

从最基本的堆样式开始,定义字体样式,背景颜色,清除默认边距;这部分样式表没什么特殊意义,主要是为了好看。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
* {
padding: 0;
margin: 0;
color: #FFFFFF;
font-size: 1.2rem;
font-weight: bolder;
text-align: center;
}

header {
padding: 1rem;
background-color: #C2185B;
}
.left, .right {
padding: 1rem 0;
background-color: #0288D1;
}
.center {
padding: 1rem;
background-color: #03A9F4;
}
footer {
padding: 1rem;
background-color: #757575;
}

配色取自Material Design Color Palette Generator - Material Palette

默认布局
默认布局

接下来开始折腾这个三栏布局,先是 Left 自然想到 float:left;然后给 Right 设置 float:right;直觉是这样的,但是会得到这么个结果。

Right 被挤下去了
Right 被挤下去了

原因是浮动会让元素脱离普通流,浮动后面的元素,那么这个元素的框会表现得像浮动元素不存在(被覆盖),但是框的文本内容会受到浮动元素的影响(文本环绕),会移动以留出空间。

自然如此,只要把 Right 移动到 Center 前面就行了。

可能ojbk的方式
可能ojbk的方式

但是这样的文档结构是非常反直觉的;所以有了以下这种方法。

LeftCenter 打个包,整体浮动,然后 Right 紧随其后;这样逻辑上就是左中右了。

看上去没区别
看上去没区别
1
2
3
4
5
<div class="left-wrap">
<div class="left">Left</div>
<div class="center">Center</div>
</div>
<div class="right">Right</div>
1
2
3
4
5
6
7
8
9
10
11
12
13
.left-wrap{
width: 100%;
}
.left,.left-wrap {
float: left;
}
.center {
margin: 0 6em;
}
.right {
float: left;
margin-left: -6em;
}

但是增加了个壳,还有一堆样式;这么就被分为 2 部分,先是 left-wrap 内部的 2 栏,随后是 left-wrapRight 的 2 栏;只是为了防止 Center 的内容被覆盖,需要加上 margin 来空出位置。

这时候要是要求三列高度一致又该如何?这里有个骚气的操作。

原始状态
原始状态

首先元素的 background 默认生效与 padding-box 内部,所以需要的就是 padding-box 填满可见区域,但是直接 width: 100%,是无法通过 auto 获取到任何值的;所以给定一个非常大的高度即可,但是还得让他自然增长;所以用 padding 或者 border 撑开背景,再用 margin 给他反向收缩回来。

很大的 padding
很大的 padding

这时候,又发现下面的 Footer 被遮挡了,这是因为上面的 left-wrapRight 均是浮动元素,所以 Footer 被 “环绕” 了;这里我们可以使用清除浮动来让文档流恢复正常;给 Footer 加上 clear 或者上一个 div 加上 overflow: hidden;前者虽然文档流正常了,但是上面那个 Left 依然骑在头上,于是用 overflow,而 Left 多余的部分也被隐藏了。

OK
OK

到这里就完成了,源码在这

上面是双飞燕布局,通过加一个元素分离成 2 个双列布局。

圣杯布局
圣杯布局

利用以下几点:

  1. HTML 后面的元素会覆盖前面的元素
  2. margin
  3. box-sizing 修改宽度计算方式,或者外部加 padding ,然后内部用相对布局 + left/right

随后是弹性盒

flex box
flex box

直接父元素 display:flex 左右定宽,完成。

安利弹性盒布局的资料,由 FlexBox 算法强力驱动的 Weex 布局引擎

最后是 grid

Grid 布局
Grid 布局
1
2
3
4
div {
display: grid;
grid-template-columns: 6em auto 6em;
}