前端之旅:圣杯布局和双飞翼布局

圣杯布局和双飞翼布局在前面的步骤都是一样的,只是最后的步骤有点区别,且看

  1. html结构

    1
    2
    3
    4
    5
    6
    7
    8
    9
    <div id="page">
    <div id="header">header</div>
    <div id="content">
    <div class="main">main</div>
    <div class="left">left</div>
    <div class="right">right</div>
    </div>
    <div id="footer">footer</div>
    </div>

    这里的重点在content区域,由于遵循主要内容main优先渲染,所以放在三列布局的前面

  2. 基础样式

    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
    26
    27
    28
    29
    30
       body {
    margin: 0;
    }
    #header {
    height: 30px;
    background-color: #ddd;
    }
    #content {
    color: #fff;
    }
    #footer {
    height: 30px;
    background-color: #ddd;
    }

    .main {
    min-height: 100px;
    width: 100%;
    background-color: red;
    }
    .left {
    min-height: 100px;
    width: 190px;
    background-color: green;
    }
    .right {
    min-height: 100px;
    width: 190px;
    background-color: blue;
    }

    我们给了点基本样式,其中重点header和footer可以忽略不计,我们重点看三列布局的区域

    另外两列都按照流的方式正常流入了页面,不过并不是我们期望的效果

  3. 添加浮动
    给三列布局的样式分别添加浮动float: left;,并且在footer样式上清除浮动clear: both;,效果如下:

    可以看出,由于main区域的宽度是100%,所以还是把另外两列撑下来了

  4. 使用负边距
    使用负边距可以让另外两列和main区域处于同一水平位置,我们给left和right分别添加负边距

    1
    2
    3
    4
    5
    6
    .left {
    marin-left: -100%;
    }
    .right {
    margin-left: -190px;
    }

    给 left -100%的边距是为了让它缩进一行,回到上一行并且完全靠在左边位置,而right的负边距是自身的宽度,也就是等left离开后,它会完全靠在左边,在缩进自身宽度的负边距,就回到上一行,并且完全靠右。效果如下:

    perfect!!!但是,遗憾的是,虽然这两个回去了,main非常霸道,他居然没给人家让位置,所以另外两个小兄弟就以牙还牙的坐到main的身上,所以,现在看起来,main的左右都被遮住了。
    其实按照我们正常布局逻辑的话,左中右三列布局很容易就实现了,但是现在main优先的结构导致了更复杂的实现。

    接下来也就是圣杯布局和双飞翼布局的分水岭了

  5. 圣杯布局
    圣杯布局的思想是,既然main被困在下面出不来,那么我们是否可以给content区内边距,把他挤到中间可见区域来。
    然后我们给了content一个padding。

    1
    2
    3
    #content {
    padding: 0 190px;
    }


    但是left和right似乎不领情,仍然狠狠压着main,原因是left和right都被content包裹着,所以content有什么动静他们都一清二楚,在content的苦苦劝说下,left和right才答应挪出一点位置给main:

    1
    2
    3
    4
    5
    6
    7
    8
       .left {
    position: relative;
    left: -190px;/*left左移*/
    }
    .right {
    position: relative;
    right: -190px; /*right右移*/
    }


    现在已经达到我们期望的方式了,下面是我们的整个圣杯布局的css:

    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
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
       body {
    margin: 0;
    }
    #header {
    height: 30px;
    background-color: #ddd;
    }
    #content {
    color: #fff;

    padding: 0 190px;
    }
    #footer {
    clear: both;
    height: 30px;
    background-color: #ddd;
    }
    .main {
    float: left;
    min-height: 100px;
    width: 100%;
    background-color: red;
    }
    .left {
    float: left;
    min-height: 100px;
    width: 190px;
    margin-left: -100%;
    background-color: green;

    position: relative;
    left: -190px;
    }
    .right {
    float: left;
    min-height: 100px;
    width: 190px;
    margin-left: -190px;
    background-color: blue;

    position: relative;
    right: -190px;
    }

    那么下面来看,面对同样的问题,双飞翼布局是怎么处理的?

  6. 双飞翼布局

    我们随图片可以看到问题重现,main区域被遮盖了,淘宝的玉伯大侠提出了处理起来更简单的双飞翼布局的方案。
    双飞翼布局的思路是,首先要增加一点html,在原main中嵌入一个div包裹原来main包裹的内容,然后给内嵌的div一个左右边距,就达到目的了,现在html看起来是这样:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    <div id="page">
    <div id="header">header</div>
    <div id="content">
    <div class="main">
    <div class="in-main">main</div>
    </div>
    <div class="left">left</div>
    <div class="right">right</div>
    </div>
    <div id="footer">footer</div>
    </div>

    回到第5步实现圣杯布局之前的css,是这样:

    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
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
       body {
    margin: 0;
    }
    #header {
    height: 30px;
    background-color: #ddd;
    }
    #content {
    color: #fff;
    }
    #footer {
    clear: both;
    height: 30px;
    background-color: #ddd;
    }
    .main {
    float: left;
    min-height: 100px;
    width: 100%;
    background-color: red;
    }
    .left {
    float: left;
    min-height: 100px;
    width: 190px;
    margin-left: -100%;
    background-color: green;
    }
    .right {
    float: left;
    min-height: 100px;
    width: 190px;
    margin-left: -190px;
    background-color: blue;
    }

    现在我们只需要在此基础上给新增的in-main增加一行样式足矣:

    1
    2
    3
       .in-main {
    margin: 0 190px;
    }

    现在看看我们的效果,如图:

    也很完美的解决了问题,而且使用了更少的样式,而且从上面可以很容易的看出这两种布局的区别。

avatar

神无

舍悟离迷,六尘不改。