CSS布局之圣杯布局和双飞翼布局

1、写在前面

圣杯布局和双飞翼布局网上有很多的文章来介绍。有的图文并茂的写的很细,看着很舒服。有的写的格式很乱,没图没真相,看着很捉急。然而这些文章里没有一篇是让自己看完后完全明白的,于是仔细了解了圣杯布局和双飞翼布局,下面对圣杯布局和双飞翼布局分别分解介绍一下,希望以后再看的时候能迅速帮助自己理解。

 

2、圣杯布局

圣杯布局主要有下面这些种(图片来自http://www.cnblogs.com/lyzg/p/5160570.html)。

文中介绍圣杯布局使用三栏式,左右两边定宽,中间主要部分根据窗口宽度自适应调整自身,如图所示。

 

接下来从最基本样式起,按步骤来介绍一下圣杯布局的实现原理。

div元素:

<div class="bd">
    <div class="main">Main</div>
    <div class="aside left">Left</div>
    <div class="aside right">Right</div>
</div>

元素中,之所以将main所在元素设置在left和right所在元素之前,是要保证网页在加载过程中首先加载网页主题内容,使其优先渲染,以免网页加载时间过长主要部分出现空白。

基本样式:

.bd {
    height: 65px;
    line-height: 65px;
    text-align: center;    
}
            
.main {
    float: left;
    width: 100%;
    height: 100%;
    background-color: #0088CC;   
}
            
.aside {
    float: left;
    height: 100%;
}
            
.left {
    width: 140px;
    background-color: #31B0D5;
}
            
.right {
    width: 180px;
    background-color: #39B3D7;
}

效果图如下:

基本样式中将main、left和right元素的float属性设置为left。接下来将left和right元素移到和Main为同一行,这里用到的是使元素上移。通过设置left元素margin-left属性为-100%使left上移一行到行首,设置right元素margin-left属性为-180px使right上移一行到行尾。代码及效果如下。

.bd {
    height: 65px;
    line-height: 65px;
    text-align: center;    
}
            
.main {
    float: left;
    width: 100%;
    height: 100%;
    background-color: #0088CC;   
}
            
.aside {
    float: left;
    height: 100%;
}
            
.left {
    width: 140px;
    margin-left: -100%;
    background-color: #31B0D5;
}
            
.right {
    width: 180px;
    margin-left: -180px;
    background-color: #39B3D7;
}

 

如上图所示,left和right元素上移之后分别盖住了main元素的左右部分,实际上main的左右部分还是存在的。

 

为了解决这个问题这里设置包裹main元素和侧边元素的父容器bd的padding-left为150px,padding-right为190px。代码及效果如下:

.bd {
    height: 65px;
    padding-left: 150px; //added
    padding-right: 190px; //added
    line-height: 65px;
    text-align: center;    
}
            
.main {
    float: left;
    width: 100%;
    height: 100%;
    background-color: #0088CC;   
}
            
.aside {
    float: left;
    height: 100%;
}
            
.left {
    width: 140px;
    margin-left: -100%;
    background-color: #31B0D5;
}
            
.right {
    width: 180px;
    margin-left: -180px;
    background-color: #39B3D7;
}

 

在对bd增加了padding-left和padding-right之后,main部分变短了,但是left和right部分也跟着移动了,并且依然遮盖住了main的左右部分。

 

这时就需要圣杯布局中关键一步,给left和right设置position为relative,并设置left元素的left属性值为-150px,设置right元素的right属性值为-190px。目的是让left和right元素分别相对自身所在位置向左和向右偏移180px和190px。代码和最终效果如下。

.bd {
    height: 65px;
    padding-left: 150px;
    padding-right: 190px;
    line-height: 65px;
    text-align: center;    
}
            
.main {
    float: left;
    width: 100%;
    height: 100%;
    background-color: #0088CC;   
}
            
.aside {
    position: relative; //added
    float: left;
    height: 100%;
}
            
.left {
    width: 140px;
    left: -150px; //added
    margin-left: -100%;
    background-color: #31B0D5;
}
            
.right {
    width: 180px;
    right: -190px; //added
    margin-left: -180px;
    background-color: #39B3D7;
}

 

这里之所以设置父容器bd的padding左右距离比实际上left和right元素的宽度多出10px是为了显示出上图中左右元素和中间main元素的小间隔,没什么多余的用处。至此,就介绍完圣杯布局了,基本原理很简单。

3、双飞翼布局

 

双飞翼布局相比圣杯布局,在main元素的外面加了一层main_out,并且同样需要保证main_out元素必须放在最前面。下面依然从最简单的代码逐步分析。

最终效果:

div元素:

<div class="bd">
    <div class="main_out">
        <div class="main">Main</div>
    </div>
    <div class="aside left">Left</div>
    <div class="aside right">Right</div>
<div>

基础样式:

.main_out, .aside {
    float: left;
    height: 65px;
    line-height: 65px;
    text-align: center; 
}
            
.main_out {
    width: 100%;    
}

.aside {
    background-color:#31B0D5;       
}
                        
.main {
    height: 100%;
    background-color:#0088CC;
}
            
.left {
    width: 140px;
}
            
.right {
    width: 180px;
}

  

上图可以看出,最原始的样式作用在div元素中得出的效果和圣杯布局最开始的效果相同,并且依然需要设置三栏float为left。

 

同样,下面也是需要将左右两个元素移到于main元素同一行,代码及移动后的效果如图。

.main_out, .aside {
    float: left;
    height: 65px;
    line-height: 65px;
    text-align: center; 
}
            
.main_out {
    width: 100%;    
}

.aside {
    background-color:#31B0D5;       
}
                        
.main {
    height: 100%;
    background-color:#0088CC;
}
            
.left {
    margin-left: -100%; //added
    width: 140px;
}
            
.right {
    margin-left: -190px; //added   
    width: 180px;
}

  

上图中实际上left、right元素遮住了main元素的左右两边,因此这里需要将main元素的两边空出来以供放置左右两边,而这里的实现正是双飞翼布局和圣杯布局不同的地方。双飞翼布局在这步做的很简单,就是将main元素的margin-left和margin-right分别设置为150px和190px,这样就可以实现main元素两边空出来放置left和right元素。

.main_out, .aside {
    float: left;
    height: 65px;
    line-height: 65px;
    text-align: center; 
}
            
.main_out {
    width: 100%;    
}

.aside {
    background-color:#31B0D5;       
}
                        
.main {
    margin-left: 150px; //added
    margin-right: 190px; //added
    height: 100%;
    background-color:#0088CC;
}
            
.left {
    margin-left: -100%;
    width: 140px;
}
            
.right {
    float: right; //added
    margin-left: -190px; 
    width: 180px;
}

 

经过上面设置main的左右margin就可以实现左右栏和中间栏的分开,样式中增加右边栏为右浮动是为了显示出右边栏和main边栏之间的空格。 

4、总结

由以上分析可以看出,圣杯布局和双飞翼布局解决问题的方案在前一半相同,main、left和right三栏均设置为浮动,左右两栏均需要设置margin-left为负值才能让其与main并排,以形成最基本的三栏布局。 

不同点在于解决中间栏被左右栏遮挡问题的思路不同:

圣杯布局:为了是中间栏不被遮挡,将main、left和right的外层包裹bd设置了padding-left和padding-right,设置左右栏的position属性为relative,并分别对应左右栏设置left和right属性,一边使左右栏分别左右移动到空出的padding空间,以此来保证部遮挡中间栏。

 

双飞翼布局:为了中间栏内容不被遮挡,将main元素放在main_out元素内,使main_out元素与left和right元素同级。接下来在main元素中使用margin-left和margin-right为左右栏留出空白位置。

 

双飞翼布局相较于圣杯布局,多了一个main_out 元素,但少用了大致4个Css属性(圣杯布局bd元素的padding-left和padding-right属性<2个>,左右栏分别使用了一个position:relative属性<2个>,及对应的left和right属性<2个>;双飞翼布局的main元素使用了margin-left和margin-right属性<2个>。6-2=4)。简单来说,双飞翼布局比圣杯布局多创建了一个div,但是没有用到相对布局,因此理解起来比圣杯布局更直接和简洁。 

5、参考

http://www.cnblogs.com/imwtr/p/4441741.html

http://www.jianshu.com/p/c3f33f4aed02/comments/1072948

http://www.cnblogs.com/lyzg/p/5160570.html

http://www.zhihu.com/question/21504052

 

 

 

原文地址:https://www.cnblogs.com/alkq1989/p/5646320.html