在我之前的博客网页整体布局完全剖析—剖完你不进来看一下么?中总结单列、两列、三列固宽与变宽布局,我还以为已经囊括了所有经典的网页布局方法了呢,当然除了CSS3的弹性盒模型没有涉及到,现在看来确实是自己孤陋寡闻了,以前在看资料的时候无意中看过圣杯布局和双飞翼布局这样的名词,只不过当时基础是在太差直接忽略了(当然现在也是在打基础,但是好歹相对几个月前已经有了质的改变)。今天总结时再次看到这两个布局方法,当然再也不能错过了。

圣杯布局与双飞翼布局针对的都是三列左右栏固定中间栏边框自适应的网页布局(想象一下圣杯是主体是加上两个耳朵;鸟儿是身体加上一对翅膀),圣杯布局是Kevin Cornell在2006年提出的一个布局模型概念,在国内最早是由淘宝UED的工程师(传说是玉伯)改进并传播开来,在中国也有叫法是双飞翼布局,它的布局要求有几点:

  • 三列布局,中间宽度自适应,两边定宽;

  • 中间栏要在浏览器中优先展示渲染;

  • 允许任意列的高度最高;

下面我们看看具体的实现方法。

一、圣杯布局

HTML结构

1
2
3
4
5
6
7
<div class="header">header</div>
<div class="container">
    <div class="main">main</div>
    <div class="left">left</div>
    <div class="right">right</div>
</div>
<div class="footer">footer</div>

因为需要中间栏优先展示渲染,所以中间的main在HTML的结构中却是最靠前的。在实际的网站中这样做的好处就是用户能够先看到网页正文信息,一般网页两边的导航信息和说明信息我们认为优先级没有正文重要。

1.设置一下基本样式

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
*{margin: 0;padding: 0;}
body{min-width: 700px;}
.header,.footer{
   border: 1px solid #333;
   background: #aaa;
   text-align: center;
}
.left,.main,.right{
   min-height: 130px;
}
.container{
  border:2px solid yellow;
}
.left{
   width:200px;
   background:red;
}
.right{
   width:220px;
   background:green;
}
.main{
   background:blue;
}

为了高度保持一致给left middle right都加上min-height:130px

2.将主体部分的三个子元素都设置左浮动

1
2
3
.left,.main,.right{
    float: left;
}

此时的页面显示如图所示,Shen Me Gui没关系,事情会变得好起来的

我们看一下上面的效果比较明显的两个问题,一是footer跑到上面去了,二是container容器高度塌陷了,这是典型的“清除浮动和闭合浮动”问题。

3.解决浮动问题

1
2
3
4
5
6
7
.container{
   border: 2px solid yellow;
   overflow: hidden;
}
.footer{
   clear: both;
}

给container加上overflow:hidden触发BFC闭合浮动,给footer加上clear属性清除浮动。

我们发现footer移到了下面,并且container的高度塌陷也修复了。

4.设置main宽度为width:100%,让其单独占满一行

1
2
3
4
.main{
    width: 100%;
    background: blue;
}

5.设置left和right负的外边距

我们的目标是让left、main、right依次并排,但是上图中left和right都是位于下一行,这里的技巧就是使用负的margin-left:

1
2
3
4
5
6
7
8
9
10
.left{
    margin-left: -100%;
    width: 200px;
    background: red;
}
.right{
    margin-left: -220px;
    width: 220px;
    background: green;
}

负的margin-left会让元素沿文档流向左移动,如果负的数值比较大就会一直移动到上一行。关于负的margin的应用也是博大精深,这里肯定是不能详细介绍了。
设置left部分的margin-left为-100%,就会使left向左移动一整个行的宽度,由于left左边是父元素的边框,所以left继续跳到上一行左移,一直移动到上一行的开头,并覆盖了main部分(仔细观察下图,你会发现main里面的字“main”不见了,因为被left遮住了),left上移过后,right就会处于上一行的开头位置,这是再设置right部分margin-left为负的宽度,right就会左移到上一行的末尾。

6.修复覆盖问题

第五步我们说过设置left和right负的外边距覆盖了main部分的内容,现在想办法修复这个问题,首先给container的左右加上一个内边距,分别为left和right的宽度。

1
2
3
4
5
.container{
   border: 2px solid yellow;
   padding:0 220px 0 200px;
   overflow: hidden;
}

由于left、main、right三个部分都被container包裹着,所以给其添加内边距,三个子元素会往中间挤。貌似还是没有修复问题,别着急,我们已经在container的左右两边留下了相应宽度的留白,只要把left和right分别移动到这两个留白就可以了。可以使用相对定位移动left和right部分,

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
.left,.main,.right{
   position: relative;
   float: left;
   min-height: 130px;
}
.left{
   margin-left: -100%;
   left: -200px;
   width: 200px;
   background: red;
}
.right{
   margin-left: -220px;
   right: -220px;
   width: 220px;
   background: green;
}

至此,我们完成了三列中间自适应的布局,也就是传说中的圣杯布局。完整的代码如下:

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
44
45
46
47
48
49
50
51
52
53
54
55
56
57
<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    <title>圣杯布局</title>
    <style type="text/css">
        *{margin: 0;padding: 0;}
        body{min-width: 700px;}
        .header,
        .footer{
            border: 1px solid #333;
            background: #aaa;
            text-align: center;
        }
        .left,
        .main,
        .right{
            position: relative;
            float: left;
            min-height: 130px;
        }
        .container{
            border: 2px solid yellow;
            padding:0 220px 0 200px;
            overflow: hidden;
        }
        .left{
            margin-left: -100%;
            left: -200px;
            width: 200px;
            background: red;
        }
        .right{
            margin-left: -220px;
            right: -220px;
            width: 220px;
            background: green;
        }
        .main{
            width: 100%;
            background: blue;
        }
        .footer{
            clear: both;
        }
    </style>
</head>
<body>
    <div class="header">header</div>
    <div class="container">
        <div class="main">main</div>
        <div class="left">left</div>
        <div class="right">right</div>
    </div>
    <div class="footer">footer</div>
</body>
</html>

二、双飞翼布局

圣杯布局和双飞翼布局解决问题的方案在前一半是相同的,也就是三栏全部float浮动,但左右两栏加上负margin让其跟中间栏div并排,以形成三栏布局。不同在于解决”中间栏div内容不被遮挡“问题的思路不一样。

HTML 结构

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

双飞翼布局的前五步和圣杯布局完全相同,我们只需要修改第六步,前面是设置container的内边距以及相对定位来解决这个覆盖问题的,双飞翼布局中,为了main内容不被遮挡,在main里面添加一个子元素content来显示内容,然后设置content的margin-left和margin-right为左右两栏div留出位置。

直接贴出代码,读者可以自行参透他们的异同:

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
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    <title>圣杯布局</title>
    <style type="text/css">
        *{margin: 0;padding: 0;}
        body{min-width: 700px;}
        .header,
        .footer{
            border: 1px solid #333;
            background: #aaa;
            text-align: center;
        }
        .left,
        .main,
        .right{
            float: left;
            min-height: 130px;
        }
        .container{
            border: 2px solid yellow;
            overflow: hidden;
        }
        .left{
            margin-left: -100%;
            width: 200px;
            background: red;
        }
        .right{
            margin-left: -220px;
            width: 220px;
            background: green;
        }
        .main{
            width: 100%;
            background: blue;
        }
        .content{
            margin: 0 220px 0 200px;
        }
        .footer{
            clear: both;
        }
    </style>
</head>
<body>
    <div class="header">header</div>
    <div class="container">
        <div class="main">
            <div class="content">main</div>
        </div>
        <div class="left">left</div>
        <div class="right">right</div>
    </div>
    <div class="footer">footer</div>
</body>
</html>

双飞翼布局比圣杯布局多使用了1个div,少用大致4个css属性(圣杯布局container的 padding-left和padding-right这2个属性,加上左右两个div用相对布局position: relative及对应的right和left共4个属性,;而双飞翼布局子div里用margin-left和margin-right共2个属性,比圣杯布局思路更直接和简洁一点。简单说起来就是”双飞翼布局比圣杯布局多创建了一个div,但不用相对布局了。

参考

圣杯布局和双飞翼布局的作用和区别

CSS布局 -- 圣杯布局 & 双飞翼布局

CSS布局经典—圣杯布局与双飞翼布局的更多相关文章

  1. CSS圣杯布局、双飞翼布局详解

    三栏布局中,经典中的经典应该就是圣杯布局.双飞翼布局没跑了.双飞翼布局和圣杯布局其实是一样的,只不过在写法上有些不同,其布局都是左右固定宽度,中间宽度自适应. 先熟悉一下圣杯布局.双飞翼布局中的特点: ...

  2. 【CSS】 布局之圣杯布局

    在看众多大神的css布局指南时,经常看到一个布局:圣杯布局(也有称为双飞翼布局的).今天我们也来剖析一下. 其实,对于众多css布局,我们只要明确理解了3种技术,那么基本上大多数布局都难不倒我们了: ...

  3. CSS经典布局-圣杯布局、双飞翼布局

    圣杯布局的来历是2006年发在a list part上的这篇文章:In Search of the Holy Grail · An A List Apart Article圣杯是西方表达“渴求之物&q ...

  4. CSS经典布局——圣杯布局与双飞翼布局

    一.圣杯布局和双飞翼布局的目的 实现三栏布局,中间一栏最先加载和渲染 两侧内容固定,中间内容随着宽度自适应 一般用于PC网 二.圣杯布局的实现 技术要点: 设置最小宽度min-width 使用floa ...

  5. 中间自适应,左右定宽的两种经典布局 ---- 圣杯布局 VS 双飞翼布局

    一.引子 最近学了些js框架,小有充实感,又深知如此节奏的前提需得基础扎实,于是回头想将原生CSS和Javascript回顾总结一番,先从CSS起,能集中它的就在基础的布局上,便查阅了相关资料,将布局 ...

  6. CSS布局 -- 圣杯布局 & 双飞翼布局

    按照我的理解,其实圣杯布局跟双飞翼布局的实现,目的都是左右两栏固定宽度,中间部分自适应. 但在这里实现起来还是有一些区别的 [圣杯布局] 在这里,实现了左(200px) 右(220px) 宽度固定,中 ...

  7. CSS之圣杯布局与双飞翼布局

    圣杯布局 三行等高 HTML: <!DOCTYPE html><html><head>    <meta charset="utf-8"& ...

  8. CSS 圣杯布局 / 双飞翼布局的实现

    工作的越久,有些基础知识我们可能就逐渐淡忘了,今天我们来回顾一下css的圣杯布局和双飞翼布局, 这两个名词你可能不熟, 那三栏布局你肯定就非常熟悉了, 就是两边定宽, 中间自适应 的 布局 1 , 圣 ...

  9. css布局记录之双飞翼布局、圣杯布局

    双飞翼布局和圣杯布局是比较常用的布局方式,都是为了实现一行三列,并且两侧列固定宽度,中间列宽度自适应的效果:直接上代码记录下: <!DOCTYPE html> <html lang= ...

随机推荐

  1. java中Map,List与Set的区别(转)

    Set,List,Map的区别 java集合的主要分为三种类型: Set(集) List(列表) Map(映射) 要深入理解集合首先要了解下我们熟悉的数组: 数组是大小固定的,并且同一个数组只能存放类 ...

  2. Mysql中sql_mode详解

    阅读目录 简介 sql_mode常用值 session与global 简介 MySQL服务器能够工作在不同的SQL模式下,并能针对不同的客户端以不同的方式应用这些模式.这样,应用程序就能对服务器操作进 ...

  3. telnet报“Unable to connect to remote host:Connection refused”错误

    Linux下面telnet ip 端口号 报错误"Unable to connect to remote host:Connection refused"的时候,大部分是目标机的端 ...

  4. 【CentOS7之防火墙命令】

    1.CentOS7的发现带了很多行的指令和新的技术.并且在帮助的中文解释也增多了很多这意味着Linux在中国的发展越来越呈现普及.今天来介绍下CentOS7的新防火墙firewall. 更多的可查看: ...

  5. 布局TextView和EditText区别,layout_width和lay_weight区别--Android Studio

    1. TextView控件是文本表示控件,主要功能是向用户展示文本的内容,它是不可编辑的,如设置标题:EditText控件是编辑文本控件,主要功能是让用户输入文本的内容,它是可以编辑的.每一个控件都有 ...

  6. App制作

    公司官网生成app: 搜狐快站 http://zhan.sohu.com/

  7. Thinkphp 第二篇:如何将一个外部项目导入到Thimkphp环境中

    一:到这篇博文的开头,假设我们的Xmapp环境已经搭建好了,并且成功的安装了Thinkphp的环境了. 1:Xmapp安装成功截图: 2:Thinkphp安装成功截图: 二:Thinkphp中各个文件 ...

  8. angularjs 中的setTimeout(),setInterval() / $interval 和 $timeout

    $interval window.setInterval的Angular包装形式.Fn是每次延迟时间后被执行的函数. 间隔函数的返回值是一个承诺.这个承诺将在每个间隔刻度被通知,并且到达规定迭代次数后 ...

  9. 【TIP】已经上架的app在AppStore上搜不到的解决办法

    相信很多人都遇到过这个问题,天天刷iTunes connect,终于发现app已经上架了,兴奋的跑过去告诉老板,老板说好,大家都装一个吧!然后大家过来问你怎么搜不到,老板看你都是一副这个表情:   这 ...

  10. Mysql学习笔记(附一)

    关于外键约束关系下修改或者删除表的方法: http://wenku.baidu.com/link?url=RRaI160kvsdf7ibMLqxN815RvStSyenz_-ig1ONfpRfpfFp ...