Home  >  Article  >  Web Front-end  >  ? 关于「圣杯布局」_html/css_WEB-ITnose

? 关于「圣杯布局」_html/css_WEB-ITnose

WBOY
WBOYOriginal
2016-06-21 08:55:391132browse

引言

「圣杯布局」?? 尽管这是一个很古老的话题了,而且网上早就有许多相关的文章,但作为前端入门和面试的必备知识之一,还是觉得有必要温故而知新一番。尤其是在拜读了「yuanzm」的博客 《我是如何同时拿到阿里和腾讯offer的》 文章后,更感到对于任何别人的知识至少都需要花点时间自己实践一下,了解一下它的原理甚至是历史,而不应盲目引用和浮于表面。谨以此文表示感谢~

圣杯的由来

圣杯布局是讨论「三栏液态布局」的实现,它最早出自于谁或许不得而查了,但最早的完美实现是来自于 Matthew Levine 于2006年在「A LIST APART」上写的一篇文章,它主要讲述了网页中关于最佳圣杯的实现方法。

所谓液态布局是相对固态布局而言的,固态布局就是固定值不变的布局,液态就好比在容器里到了一杯水,它可以随着容器宽度的变化而自适应宽度。

在这篇文章中,作者指出了当时的一些实现方式所存在的问题,如:必须按照源顺序(在 DOM 中表现为先写 Left,然后 Middle,最后,Right)等,它将可能导致代码不够灵活,尤其是从 DOM 的载入顺序上来说,中间的内容不能被首先加载。

因此他给出一个方案,它将:

  1. 两边带有固定宽度中间可以流动(fluid);

  2. 允许中间一栏最先出现;

  3. 允许任意一栏放在最上面;

  4. 仅需一个额外的 div 标签

  5. 仅需非常简单的 CSS,带上最少的兼容性补丁

文中还提到了他的这个想法是基于「One True Layout」 和 「 Eric Meyer’s adaptation」两篇文章带来的灵感。

在这里你可以看到「圣杯布局」的最终效果: http://alistapart.com/d/holygrail/example_1.html

实现方式

接下来就言归正传,说下具体的实现思路:

首先我们需要布局的 HTML 代码如下,作者在这里为了便于表达,对标签使用了非语义化的 id ,他建议在其他任何正式项目中尽量使用语义化的 id 。例如,我们需要实现的是左侧宽度为 200px,右侧宽度为 150px,中间是流动的布局。

<div id="header">#header</div><div id="container">  <div id="center" class="column">#center</div>  <div id="left" class="column">#left</div>  <div id="right" class="column">#right</div></div><div id="footer">#footer</div>

正如他先前提到的,只是加了一层额外的 div 它的 id 是 container 。它的 CSS 内容非常简单,具体代码如下:

body {  min-width: 550px;      /* 2x LC width + RC width */}#container {  padding-left: 200px;   /* LC width */  padding-right: 150px;  /* RC width */}#container .column {  height: 200px;  position: relative;  float: left;}#center {  background-color: #e9e9e9;  width: 100%;}#left {  background-color: red;  width: 200px;          /* LC width */  right: 200px;          /* LC width */  margin-left: -100%;}#right {  background-color: blue;  width: 150px;          /* RC width */  margin-right: -150px;  /* RC width */}#footer {  clear: both;}#header, #footer {  background-color: #c9c9c9;}/*** IE6 Fix ***/* html #left {  left: 150px;           /* RC width */}

下面我们来分步观察它的实现逻辑:

第1步 建立框架

先写 header, footer 和 container 三个 div

<div id="header">#header</div><div id="container"></div><div id="footer">#footer</div>

我们将 container 的内边距设置为左右两边各自的宽度。它看起来就像这样:

第2步 加入三栏

此时我们有了基本框架,可以把三栏塞进去了。

<div id="header">#header</div><div id="container">  <div id="center" class="column">#center</div>  <div id="left" class="column">#left</div>  <div id="right" class="column">#right</div></div><div id="footer">#footer</div>

接着我们给每一栏配上合适的宽度,并将它们设为浮动。同时我们需要清除 footer 的上下环境,以免遭跟上面三栏一起浮动。

#container .column {  float: left;}#center {  width: 100%;}#left {  width: 200px;  /* LC width */}#right {  width: 150px;  /* RC width */}#footer {  clear: both;}

注意这里中间一栏的 100% 宽是基于它的父容器 container 的宽度而言的,由于 container 设置了内边距,因此中间栏看起来就处在了网页的中间,但左右两栏由于排在中间栏的后面,且因为空间不够被挤到了中间栏的下面,如下图所示:

第3步 把左侧栏放上去

中间栏已经就位,剩下的事情就是把左右两栏放上去了,接下来我们先放左侧栏。

为了详述过程,这里将分为两个小步骤。首先,我们先将它的外边距设置为 -100%,这样一来,由于浮动的关系,左侧栏就能上位,与中间栏交叠在一起,并占据了左边。而右侧栏由于左侧栏的上位,自动向前浮动到了原来左侧栏的位置。

接着我们要用到相对定位属性(relative),并设置一个与 左侧栏 等宽的偏移量:

#container .columns {  float: left;  position: relative;}#left {  width: 200px;        /* LC width */  margin-left: -100%;    right: 200px;        /* LC width */}

可以看到,它设置的 right 属性就是相对于 container 的右边线向左偏移 200px,如此一来,它就完美地跑到了 container 左内边距的位置,也就是我们希望它呆的地方,如下图所示:

第4步 把右侧栏放上去

最后,我们需要把右侧栏放上去,此时只需利用上面的原理把他放到 container 的右外边距的位置即可,我们需要再一次设置一个负外边距的值,它等于 右侧栏 的宽度:

#right {  width: 150px;          /* RC width */  margin-right: -150px;  /* RC width */}

至此,所有的栏目都就位了~

源码地址

https://jsfiddle.net/DotHide/pg47fucg/1/

Statement:
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn