圣杯布局和双飞翼布局

在前端布局中,事实上,圣杯布局其实和双飞翼布局是一回事。它们实现的都是三栏布局,两边的盒子宽度固定,中间盒子自适应,也就是我们常说的 固-比-固 布局。它们实现的效果是一样的,差别在于其实现的思想。

那么下面我们就来分别解析两种布局,可以在这里看 最终demo

圣杯布局

圣杯布局的出现是来自于a list part上的一篇文章 In Search of the Holy Grail,在西方,圣杯是表达“渴求之物”的意思。那么先看看他怎么实现。

首先看 html 结构

<div class="container">
    <div class="main">
        <h2>圣杯布局主内容区</h2>
    </div>
    <div class="left">左边栏内容区</div>
    <div class="right">右边栏内容区</div>
</div>

既然是让主内容区 main 自适应宽度,那么 width:100%,假设我们左、右边栏区宽度都为200px,高度是可以自适应的,在这里我们为了直观,统一设置为 300px,并分别设置不同的背景色,好实际观测。

这个时候,初步 css 样式是这样

/* ------ 圣杯布局初始化 ------ */
.container {}
.container .left {
    width: 200px;
    height: 300px;
    background: #ff8d66;
}
.container .right {
    width: 200px;
    height: 300px;
    background: #7ffe8b;
}
.container .main {
    width: 100%;
    height: 300px;
    background-color:#fcf187;

}

这个时候我们看页面实际上是竖排列 main left right 这个三个区域。接下来就要给左右边栏区域腾地方啦
我们让外层div container 的左右内间距分别等同于左右边栏的宽度:padding: 0 200px;,这个时候,依然是竖着一列,别急,我们先让他们处于同一行位置,怎么做呢,利用 浮动情况下,负边界值会导致div上移,所以将这个三个区域都增加float:left;,left区域 margin-left: -100%;(这个100%实际是main的宽度) 会叠加到 main 区域上方,right 区域margin-left: -200px(这200px是右边区域的宽度),也会叠加到 main 区上方。

此时应该是这个样子:

圣杯布局
圣杯布局

灰色区域是为left、和right 空出来归位的区域。

而我们的css应该是这样:

/* ------ 圣杯布局同行层叠状态 ------ */
.container {
    padding: 0 200px;
}
.container .left {
    width: 200px;
    height: 300px;
    background: #ff8d66;
    float: left;
    margin-left: -100%;
}
.container .right {
    width: 200px;
    height: 300px;
    background: #7ffe8b;
    float: left;
    margin-left: -200px;
}
.container .main {
    width: 100%;
    height: 300px;
    background-color:#fcf187;
    float: left;
}

圣杯布局——边栏 relative 形态

到了这里,相信你已经知道怎么解决div层叠问题了,没错就是利用 position 属性了,给左右栏和父级container 都添加 position: relative;,然后左边 left: -200px,右边left: 200px(这里也可以 right:-200px;),

这个时候就是最终版了, 别忘记了给外层 container 清除浮动。

圣杯布局
圣杯布局
/* ------ 圣杯布局区 ------ */
.container {
    padding: 0 200px;
    overflow:hidden;
    zoom:1;
    position: relative; /* 相对定位 */
}

.container .left {
    width: 200px;
    height: 300px;
    background: #ff8d66;
    float: left;
    margin-left: -100%;
    position: relative; /* 相对定位 */
    left: -200px;
}

.container .right {
    width: 200px;
    height: 300px;
    background: #7ffe8b;
    float: left;
    position: relative; /* 相对定位 */
    left: 200px;
    /*right:-200px;*/ /*这里用right偏移方式也可以实现*/
    margin-left: -200px;
}

.container .main {
    width: 100%;
    height: 300px;
    background-color:#fcf187;
    float: left;
}

圣杯布局——边栏 absolute 形态

等等,到这里还没结束,在上面div层叠状态的时候,利用 position: relative; 属性,
那么你是否想过用 position: absolute; 属性呢?事实上这里也可以这么做,相对于父级 container-2,
只要让左区域 left:0;,右区域right: 0; 即可:

/* ------ 圣杯布局区 - 形态二 ------ */
.container-2 {
    padding: 0 200px;
    overflow:hidden;
    zoom:1;
    position: relative; /* 相对定位 */
}

.container-2 .left {
    width: 200px;
    height: 300px;
    background: #ff8d66;
    position: absolute;  /* 绝对定位 */
    left:0;

}

.container-2 .right {
    width: 200px;
    height: 300px;
    background: #7ffe8b;
    position: absolute; /* 绝对定位 */
    right: 0;
}

.container-2 .main {
    width: 100%;
    height: 300px;
    background-color:#fcf187;
    position: relative;
    float:left;
}

html 结构完全一样,只是换了个container-2的样式名,当然具体样式也有点不同了,但实现效果也一样。

双飞翼布局

好,终于到比翼双飞的时刻了,最终实现的效果肯定和圣杯一样咯,那么来看html结构,

<div class="wrap">
    <div class="main">
        <div class="main-content">
            <h2>双飞翼布局主内容区</h2>
        </div>
    </div>
    <div class="left">左边栏内容区</div>
    <div class="right">右边栏内容区</div>
</div>

这里,外层div换个名字 wrap, 乍一看,和圣杯一样呗,主要是css实现方式不同。和圣杯一样,分别设置不同背景色,统一高度,方便观察。

/*---- 双飞翼布局初始化 ---*/
.wrap {}
.wrap .left {
    width: 200px;
    height: 300px;
    background: #ccc;
}
.wrap .right {
    width: 200px;
    height: 300px;
    background: #333;

}
.wrap .main {
    width: 100%;
    height: 300px;
    background-color: #666;
}

这个时候,和圣杯布局一样的预料,竖着排三行。接下来,其实和圣杯的想法一样,利用 浮动情况下,负边界值会导致div上移,所以将这个三个区域都增加float:left;,并给 wrap 清除浮动。

/*---- 双飞翼布局两行状态 ---*/
.wrap {
    zoom: 1;
    overflow: hidden;
}
.wrap .left {
    width: 200px;
    height: 300px;
    background: #ccc;
    float: left;
}
.wrap .right {
    width: 200px;
    height: 300px;
    background: #333;
    float: left;
}
.wrap .main {
    width: 100%;
    height: 300px;
    background-color: #666;
    float: left;
}
.wrap .main-content {
    background: #eee;
}

这个时候,让leftright移动到和main同行,left区域需要负100% margin-left: -100%;,这个100%其实就是中间main的宽度,right区域则只需要负他自己的宽度即可 margin-left: -200px;,现在,三个区域又处于同一行了

双飞翼布局
双飞翼布局
/*---- 双飞翼布局一行层叠状态 ---*/
.wrap {
    zoom: 1;
    overflow: hidden;
}

.wrap .left {
    width: 200px;
    height: 300px;
    background: #ccc;
    float: left;
    margin-left: -100%;
}

.wrap .right {
    width: 200px;
    height: 300px;
    background: #333;
    float: left;
    margin-left: -200px;
}

.wrap .main {
    width: 100%;
    height: 300px;
    background-color: #666;
    float: left;
}

.wrap .main-content {
    background: #eee;
}

不过,看到我们的展示图,中间区域的内容区(紫色),被左右区域给覆盖住了,那这个好办,给main-content这个区域来 padding: 0 200px;,就是左右区域的宽度,最终效果

双飞翼布局最终状态
双飞翼布局最终状态

图示可以看到,浅灰色区域就是 main-content 区域的 padding

/*---- 双飞翼布局最终状态 ---*/
.wrap {
    zoom: 1;
    overflow: hidden;
}

.wrap .left {
    width: 200px;
    height: 300px;
    background: #ccc;
    float: left;
    margin-left: -100%;
}

.wrap .right {
    width: 200px;
    height: 300px;
    background: #333;
    float: left;
    margin-left: -200px;
}

.wrap .main {
    width: 100%;
    height: 300px;
    background-color: #666;
    float: left;
}

圣杯与双飞翼的区别

通过上面的实践,其实你应该看到了,布局实现的效果都是一样,区别:

  • 圣杯的padding放在了父层,利用了float布局、position定位、margin负边距
  • 双飞翼则将 padding放在了main内层嵌套的 div上,仅用了 float布局、margin 负边距

貌似,看起来双飞翼css更简单,但多嵌套了一层 html 标签,也不好说哪个更好了,根据实际需要,灵活应用吧。

那么这种自适应宽度三栏布局的优点有哪些呢,如下:

  • 内容与布局分离,main部分自适应宽度,容易在定宽布局和流体布局中切换
  • 在浏览器上的兼容性非常好,IE5.5以上都支持
  • 三列布局位置切换起来非常方便,只要修改他们自身的margin属性就可以

好了,圣杯双飞翼布局详解,至此结束。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 199,393评论 5 467
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 83,790评论 2 376
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 146,391评论 0 330
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 53,703评论 1 270
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 62,613评论 5 359
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,003评论 1 275
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,507评论 3 390
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,158评论 0 254
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,300评论 1 294
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,256评论 2 317
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,274评论 1 328
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,984评论 3 316
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,569评论 3 303
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,662评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,899评论 1 255
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,268评论 2 345
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 41,840评论 2 339

推荐阅读更多精彩内容