三栏布局:圣杯、双飞翼与Flex布局详解

642 阅读5分钟

前言

在掘金看了这么久的文章,你有没有好奇掘金的页面是怎么实现的。如下图所示,掘金的页面分为左侧栏、主体内容和右侧栏。

image.png

主体内容优先加载,左右两侧固定宽度,中间自适应剩余空间,这种布局就是三栏布局,今天就来介绍几种实现三栏布局的方法。

三栏布局

三栏布局的灵魂之处在于要实现中间栏的主体内容优先加载,代码从上到下执行,所以html结构应该写成如下所示:

<div class="page">
    <div class="content">主体内容</div>
    <div class="left">左侧广告位</div>
    <div class="right">右侧广告位</div>
</div>  

将主体内容放到最前面,这样就可以先加载主体内容。那在这样的情况下怎么实现三栏布局呢?

1. 圣杯布局

基础css样式

<style>
        *{
            margin: 0;
            padding: 0;
        }
        .page{
            height: 200px;
        }
        .left,.right{
            width: 200px;
            height: 200px;
            background-color: #6d9b2f;
        }
        .content{
            width: 100%;
            height: 200px;
            background-color: #d8a7a7;
        }
        .page div{
            float: left;
        }   
    </style>

在page的div中设置float: left,让它们浮动在同一行,左右两侧的广告位因为主体内容content的宽度设置了100%所以被挤到了下一行。实现的效果如下:

image.png

接着在page中添加padding: 0 200px,让左右两边各有200像素的内边距,上下则没有内边距。将预留出来的内边距给左右两侧放,添加padding属性后实现效果如下图所示。

.page{
    height: 200px;
    padding: 0 200px; /* 添加padding属性,父容器左右两边往里收200px的边距 */
}

image.png

现在的问题就是怎么将左右两侧的内容放到主体内容的两侧?先给左侧广告位设置margin-left: -200px,向左移动200像素,再相对于目前的位置向左移动父容器的宽度。左侧广告就会移到如下位置:

.left{
    margin-left: -200px; /* 基于元素当前在文档流中的实际位置来定位的 */
    position: relative;  /* 相对定位的参照物是该元素本身在正常文档流中的位置。 */
    left: -100%;   /* 向左移动父容器宽度的100% */
}

image.png

接着也给右侧广告设置margin-left: -200px,向左移动200像素,再相对于当前的位置向右移动自身的宽度200px。这样就实现了三栏布局啦:

.right{
    margin-left: -200px; /* 基于元素当前在文档流中的实际位置来定位的 */
    position: relative;
    right: -200px; /* 向右移动自身的宽度200px */
}

image.png

圣杯布局的实现原理:通过设置左右边距来留出左右两栏的空间,再添加浮动、相对定位等属性就可以实现三栏布局了。

2. 双飞翼布局

html部分在content中添加了一个子容器inner,将主体内容放到inner中。

<div class="page">
    <div class="content">
        <div class="inner">主体内容</div>
    </div>
    <div class="left">左侧广告位</div>
    <div class="right">右侧广告位</div>
</div>

双飞翼css布局, page > div 只选择 page 的直接子元素中的 div,在这个例子里不会选择到inner元素的div。实现效果图如下所示:

<style>
         *{
            margin: 0;
            padding: 0;
        }
        .page{
            height: 200px;
        }
         .left,.right{
            height: 200px;
            width: 200px;
            background-color: #7aa74d;
        }
        .content{
            width: 100%;
            height: 200px;
            background-color: #d5adad;
        }
        .page > div{
            float: left;
        }
    </style>

image.png

接着在包含主体内容的inner中添加margin属性,margin: 0 200px 使得元素在其上方和下方没有额外的空间,而在其左右两侧各有200像素的空白区域。在inner添加颜色更好看效果,效果图如下所示:

.inner{
    margin: 0 200px;  /*上下0 左右两百 */
    height: 100%; 
    background-color: #e21616;
}

image.png

最后只要将左右侧广告位覆盖在content上就实现了想要的三栏布局了。先给左侧广告位设置margin-left: -100%,向左移动父容器的宽度,再给右侧广告位设置margin-left: -200px,向左移动自身的宽度,就实现了三栏布局,如下所示:

.left{
    margin-left: -100%;
}
.right{
    margin-left: -200px; 
} 

image.png

双飞翼的实现原理:在content中添加inner子容器,让子容器流出两处空白的地方给左右两侧的内容。

3. Flex布局(最推荐)

首先在page中添加display属性display: flex,让三个子容器去到同一行,在content中设置flex-grow: 1,在父容器宽度足够的情况下,主体内容允许放大。接着用order属性将left位置移到最前方,order属性值越小,位置可以往前排。最后实现三栏布局,如下图所示:

<style>
        *{
            margin: 0;
            padding: 0;
        }
        .page{
            height: 200px;
            display: flex;
        }
        .left,.right{
            width: 200px;
            background-color: #6d9b2f;
        }
        .content{
            flex-grow: 1;
            background-color: #d8a7a7;
            order: 2;
        }
        .left{
            order: 1;
        }
        .right{
            order: 2;
        }
    </style>

image.png

这里简单介绍一下flex 属性和order属性。

flex 属性综合了三个子属性:flex-grow, flex-shrink, 和 flex-basis。其基本语法如下:

flex: <flex-grow> <flex-shrink> <flex-basis>;
  • flex-grow: 当容器有多余的空间时可以增长。如果设置为1,表示该元素会分配到多余空间。如果所有项目的flex-grow都为1,当父容器宽度足够大时,它们会默认允许放大,按相同的比例分配多余空间。如果设为0,不允许放大,则该元素不会增长,文字有多宽就会有多少宽度。

  • flex-shrink: 当容器空间不足时收缩。如果所有项目的flex-shrink都为1,则它们会等比收缩。如果某个项目的flex-shrink更大,它将收缩更多以适应容器。设为0表示该元素不愿意收缩。

  • flex-basis: 定义了在分配多余空间前,flex 项的基础大小。它可以是长度(如像素、百分比)、关键词auto(意味着考虑内容的默认大小)或content

order属性: 用于定义弹性容器中的 flex 项的排列顺序。当order为正值时,数值越大的元素越靠后,例如order:1会比order:2的元素排在前面.

flex实现原理:将主体内容放在前面加载,但是通过order属性将left位置移到最前方

总结

本文详细介绍了三种实现网页三栏布局的方法——圣杯布局、双飞翼布局和弹性布局(Flex布局)。你还有其他可以实现三栏布局的方法吗,可以评论区告诉我哦

image.png