近些年,随着前端技术的不断发展,前端所扮演的角色越来越重要,职责也越来越大。前端早已不仅仅做简单的内容展示页面,也不仅仅负责简单的表单交互了。日益繁杂的前端技术下,JavaScript 在我们心中占据着日益重要的地位,而相应的,很多人开始忽略了 html 和 css。
JavaScript 固然重要,但是回过头来想,作为一名前端工作者,难道我们可以避免和页面打交道吗?答案是,否!
那么,假设给你一个设计稿,我们又该如何去着手呢?
本篇章主讲双栏布局和三栏布局的一些较为古老及实用的原理及实现。说它古老主要也是因为我们不会涉及 flex 这一类魔法一般的布局方式,虽然我也知道用 flex 就能轻松实现很多布局。
做这个文章,一方面也是自己做个学习记录,当做温习一番。另一方面,也希望能够帮助看到这篇文章的新手一些启发,开启更加深入的探索之路。
双栏布局非常常见,往往是以一个定宽栏和一个自适应的栏并排展示存在。比如:
实现双栏布局也很简单,接下来介绍简单的 float + margin 实现方法。
假设左边栏固定,右边栏自适应。
html 内容结构
左边
右边
内容内容内容
css 规则
.left {
float: left;
width: 200px;
background-color: gray;
height: 400px;
}
.right {
margin-left: 210px;
background-color: lightgray;
height: 200px;
}
效果
Emmm...双栏实现了,但是下面的其他内容怎么跑上去了?答案是我们使用了浮动。
浮动会导致元素脱离原来普通的文档流。元素可以向左或者向右浮动,直到接触到包含框或者其他框为止。在原来文档流中,体现的就是好像在原来位置被删除了似的。
因此,以上浮动导致了父元素高度塌陷,其他内容块会自动排版上去。解决的办法有:
css clear: both;
2) BFC(Block Formatting Context),块级格式化上下文。BFC 规定了内部的块级元素的布局方式。使用 BFC 可以用来包含浮动元素。常见的做法是为父元素添加:
css overflow: hidden;
消除浮动的其中一个方式就是创建 BFC。然而,创建 BFC 不仅仅只有“overflow:hidden;”一种方式,事实上,我们可以通过这几种方法显示触发 BFC:
回归正题,我们的双栏布局(事实上其他涉及浮动的布局也一样)父元素高度塌陷的问题的得以解决,比如,我们只需要为 .box 元素添加样式:
overflow: hidden;
三栏布局也是我们常常会使用到的布局之一。它的特点主要是:两边定宽,中间自适应。
html 内容结构
左边
中间
右边
设置 css 规则
.box {
position: relative;
}
.left {
position: absolute;
top: 0;
left: 0;
width: 200px;
height: 200px;
background-color: gray;
}
.right {
position: absolute;
top: 0;
right: 0;
width: 200px;
height: 200px;
background-color: gray;
}
.middle {
margin-left: 210px;
margin-right: 210px;
background-color: lightgray;
height: 200px;
}
效果
html 内容结构
左边
右边
中间
设置 css 规则
.box {
overflow: hidden;
}
.left {
float: left;
background-color: gray;
width: 200px;
height: 200px;
}
.right {
float: right;
background-color: gray;
width: 200px;
height: 200px;
}
.middle {
height: 200px;
background-color: lightgray;
margin-left: 210px;
margin-right: 210px;
}
效果
当然,通过浮动实现的三栏布局有一个很明显的缺点,就是我们的代码层面上来讲 html 内容结构不正确,我们必须把.middle 元素放在最下面而不是中间位置,这是 float 所产生的的布局影响所导致的。
圣杯布局最早源于发表于 2006 年的In Search of the Holy Grail · An A List Apart Article,而双飞翼布局则是源自淘宝 UED。
圣杯布局和双飞翼布局也是两边定宽,中间自适应的三栏布局。并且中间栏要放在父元素的第一儿子位置,以优先渲染。因此,有些人会说这带来了代码层面上 html 内容结构的不正确。然而,这么做的好处就是可以让更为重要的中间部分优先渲染,从这个角度来讲,这或许是更加好的结构。
圣杯布局和双飞翼布局两者既有相似的地方,也有不同的地方,接下来来比较一下。
在此之前,先来看看可爱的负边距。
为什么要讲到负边距呢?
一方面负边距是我们常常忽略的非常好用的技巧,在我们的布局方面具有非常重要的意义;另一方面这玩意儿兼容性贼好,我们也不用怕兼容性方面的问题。
说起负边距,我们可以想到的就是 margin 在正边距时候的反方向。我们可以来看看。
html 内容结构
我是内容我是内容我是内容我是内容我是内容我是内容我是内容我是内容
我是内容我是内容我是内容我是内容
哈哈哈哈哈我是内容我是内容我是内容我是内容
我是内容我是内容我是内容我是内容我是内容我是内容我是内容我是内容
我是内容我是内容我是内容我是内容我是内容我是内容我是内容我是内容
我是另一块我是另一块我是另一块我是另一块我是另一块我是另一块我是另一块
我是另一块我是另一块我是另一块我是另一块我是另一块我是另一块我是另一块
我是另一块我是另一块我是另一块我是另一块我是另一块我是另一块我是另一块
哈哈哈哈哈哈
css 规则
.box {
margin: auto;
width: 600px;
}
.content {
margin: -20px;
background-color: lightgray;
}
.span {
margin: -10px;
}
.red {
background-color: red;
}
效果
正如上面所示,我们为.content 和.span 这两个分别代表块级元素和行辈元素的东西设置了 margin 为-20px 和-10px。布局也相应产生了变化。
我们不难看出,负值情况下
另一种情况,负值 margin 也能够影响元素的宽度,前提是该元素 width 属性为 auto 的情况下。这里也给出详细例子,比方我们给一个元素左右边距为-200px。
html 内容结构
css 规则
.box {
width: 200px;
border: 1px solid black;
margin: auto;
}
.container {
margin: 0 -200px;
background-color: lightgray;
width: auto;
height: 200px;
}
效果
当然,目前为止我们都是在普通文档流里面。
假设我们对一个元素进行绝对定位,并且给相应的负边距。
html 内容结构
绝对定位绝对定位绝对定位绝对定位绝对定位绝对定位绝对定位绝对定位
绝对定位绝对定位绝对定位绝对定位绝对定位绝对定位绝对定位绝对定位
内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容
内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容
内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容
css 规则
.box {
position: relative;
height: 200px;
margin: 200px;
border: 1px solid black;
}
.pos {
width: 200px;
height: 200px;
position: absolute;
margin: -20px;
border: 1px solid gray;
}
.pos2 {
width: 200px;
height: 200px;
position: absolute;
border: 1px solid red;
}
效果图
从效果上可以看出来,对于绝对定位而言,负边距在 top 和 left 位置上,会把元素往指定方向拉,而 right 和 bottom 方向则没什么影响,因为脱离了普通文档流,不会引起其他相邻元素变化。
tips: “绝对定位+负边距”我们也常常用来实现居中布局。
思考以下三个场景:
html 内容结构
1
2
3
1
2
6
2
css 规则
.box {
width: 800px;
height: 210px;
margin: 50px auto 10px auto;
border: 1px solid black;
}
/* 第一个demo */
.float {
float: left;
margin: -50px;
width: 200px;
height: 200px;
}
.float1 {
background-color: gray;
}
.float2 {
background-color: yellow;
}
.float3 {
background-color: red;
margin: 0;
}
/* 第二格demo */
.float4 {
background-color: gray;
float: left;
width: 200px;
height: 200px;
margin-left: -200px;
}
.float5 {
background-color: lightgray;
width: 200px;
height: 200px;
float: left;
}
/* 第三个demo */
.row {
width: 100%;
height: 200px;
background-color: lightgray;
float: left;
}
.float6 {
background-color: gray;
float: left;
width: 200px;
height: 200px;
margin-left: -200px;
}
效果
可以看出:
因此,我们也可以看出,负边距对浮动的元素具有和普通文档流中同样类似的效果。并且,在后边的元素也可以通过负边距实现覆盖前边元素。
在布局中,我们就常常使用到“float + 负边距”的魔力。
html 内容结构
中间
左边
右边
css 规则
.box {
overflow: hidden;
padding: 0 210px;
}
.middle {
float: left;
width: 100%;
height: 200px;
background-color: lightgray;
}
.left {
float: left;
width: 200px;
height: 200px;
background-color: gray;
margin-left: -100%;
position: relative;
left: -210px;
}
.right {
float: left;
width: 200px;
height: 200px;
background-color: gray;
margin-left: -200px;
position: relative;
right: -210px;
}
效果
html 内容结构
中间
左边
右边
css 规则
.box {
overflow: hidden;
}
.middle {
float: left;
width: 100%;
}
.middle .content {
margin: 0 210px;
height: 200px;
background-color: lightgray;
}
.left {
float: left;
width: 200px;
height: 200px;
background-color: gray;
margin-left: -100%;
}
.right {
float: left;
width: 200px;
height: 200px;
background-color: gray;
margin-left: -200px;
}
效果
圣杯布局跟双飞翼布局的实现上,在前部分是一样的。同样都是左右栏定宽,中间栏自适应。采用浮动和负边距使左右栏与中间栏并排。不同之处大部分在于中间元素的的展示方式上。
圣杯布局采用父元素设置边距的方法,左右元素设置相对定位辅助。而双飞翼布局在中间采用嵌套子元素方法,通过设置子元素外边距来展示。
对比看来,双飞翼比圣杯多了一个嵌套元素,但是少了左右元素的定位。
在 flex 之前,无论是我们的单栏布局也好,双栏布局也罢,甚至更为复杂的三栏布局、垂直居中等等,我们一般都会借助浮动 (float)、定位(position)、边距(margin)来实现我们各种各样的布局样式,直到我们遇到了 flex。
flex(弹性布局)给了我们在布局方面更多的可能性,它可以更加简便、响应的布局我们的页面。我们常常可以利用它魔法一般的属性来打造我们想要的布局样式。并且,flex 现在几乎得到了所有的浏览器的支持,兼容性方面已经越来越不需要太过担忧了。
更多关于 flex 兼容性的问题可以查看can I use
然而,本篇章并不打算写 flex,仅仅讲解以往实现双栏和三栏布局的一些方式。于我而言,我更愿意用单独一个篇章来写 flex 这个主题,而不是放在这个主题来讲。并且之后我也会专门来写这个主题。
本次分享到此结束。我们下期再见!