三栏布局:我有五种方法给你安排!

362 阅读5分钟

引言:

何为三栏布局?主体内容优先加载,左右固定宽度,中间自适应。简单来说就是让中间的主体内容优先呈列到我们的眼前,左右部分固定宽度,就如我们掘金的首页一般呈现的页面布局结构:

image.png

有时候的千言万语不如一张图片来得直接,类似这样的页面布局结构。

正文:

布局的效果图:

image.png

1. 圣杯布局:

这种布局的特点是两侧边栏和中间内容区在同一水平线上,并且在窗口大小变化时,布局能够保持美观和功能性。

先放上主体内容,在page 容器中放上三个子容器,这里要实现主体优先呈现的效果的话,就将主体内容的标签放在首位。

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

给上一个基本样式,看看该如何实现其他基本的效果:

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <style>
        * {
            margin: 0;
            padding: 0;

        }

        .page {
            height: 200px;
            padding: 0 200px;
        }

        .left,
        .right {
            height: 200px;
            width: 200px;
            background-color: #8efb97d6;
        }

        

        .content {
            width: 100%;
            height: 200px;
            background-color: pink;
        }
        
    </style>
</head>

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

</html>

image.png

左右两边留有内边距,此时该如何将两个广告位覆盖上去?

相对于自身文档流移动位置

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

image.png

移到父容器位置的-200px位置,并且要相对于page容器-100%的位置。所以,对于right部位该如何移动?效果也是相同的,只需要相对于右边移动-200px的位置即可。

附上完整代码:

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <style>
        * {
            margin: 0;
            padding: 0;

        }

        .page {
            height: 200px;
            padding: 0 200px;
        }

        .left,
        .right {
            height: 200px;
            width: 200px;
            background-color: #8efb97d6;
        }

        .page div {
            float: left;
        }

        .content {
            width: 100%;
            height: 200px;
            background-color: pink;
        }
        .left{
            margin-left: -200px;
            position: relative;
            left: -100%;
        }
        .right{
            margin-left: -200px;
            position: relative;
            right: -200px;
            
        }
    </style>
</head>

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

</html>

image.png

2.双飞翼布局

基本框架同上,需要改变的样式:

.page > div{
            float: left;
        }
.inner{
            margin: 0 200px;
            height: 100%;
        }

让page先浮动,让inner容器移出两个200px的边距,最后左右移动相应距离即可。

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <style>
        * {
            margin: 0;
            padding: 0;

        }
        .page {
            height: 200px;
        }
        .left,
        .right {
            height: 200px;
            width: 200px;
            background-color: #8efb97d6;
        }
        .page > div{
            float: left;
        }
        .content{
            width: 100%;
            height: 200px;
            background-color: #dd1414;
        }
        .inner{
            margin: 0 200px;
            height: 100%;
        }
        .left{
            margin-left: -100%;
        }
        .right{
            margin-left: -200px;
        }
    </style>
</head>
<body>
    <div class="page">
        <div class="content">
            <div class="inner">主体内容</div>
        </div>
        <div class="left">广告位</div>
        <div class="right">广告位</div>
    </div>
</body>
</html>

3. flex布局

将主体内容放在前面加载,但是通过order属性将left位置移到最前方。

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <style>
        *{
            margin: 0;padding: 0;
        }
        .page{
            height: 200px;
            display: flex;
        }
        .left, .right{
            width: 200px;
            background: rgb(81, 226, 81);
            /* flex-shrink: 0;
            flex-grow: 1; */
            order: 2;
        }
        .content{
            background: rgb(234, 41, 41);
             /* flex-shrink: 0;
            flex-grow: 1;*/
            flex: 1;
            order: 1;
        }
        .left{
            order: 0
        }
        .right{
            order: 2
        }
    </style>
</head>
<body>
    <div class="page">
        <div class="left">广告位</div>
        <div class="content">主体内容</div>
        <div class="right">广告位</div>
    </div>
</body>
</html>
  • flex: 1; 在.content类上,这个属性是flex-growflex-shrinkflex-basis的简写。在这里,它告诉.content元素占据剩余空间(flex-grow: 1;),不缩小(flex-shrink: 0;,虽然默认值就是0),并且没有基础大小(flex-basis: 0;,默认值是0%,意味着根据内容大小确定)。
  • order: 1; 在.content类上,这个属性定义了Flex项目的排列顺序。Flex项目默认的order值是0,order: 1;使得内容区域在DOM顺序中排在侧边栏之后。
  • order: 0; 在.left类上,这个属性使得左侧边栏在DOM顺序中排在最前面。
  • order: 2; 在.right类上,这个属性使得右侧边栏在DOM顺序中排在最后面。
  • width: 200px; 在.left.right类上,这个属性设置了侧边栏的宽度。
  • flex-shrink: 0; 和 flex-grow: 1; 虽然在您的代码中被注释掉了,但这些属性分别控制Flex项目在空间不足时的缩小能力(flex-shrink)和在空间充足时的增长能力(flex-grow)。

最后也能够实现效果:

image.png

4.table 布局

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <style>
        * {
            margin: 0;
            padding: 0;
        }

        .page {
            width: 100vw;
            height: 200px;
            display: table;
            table-layout: fixed;

        }
        .page > div{
            display: table-cell;
        }
        .left,
        .right {
            height: 200px;
            width: 200px;
            background: rgb(81, 226, 81);

        }

        .content {
            width: 100%;
            height: 200px;
            background-color: #c7f121;
        }
    </style>
</head>

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

</html>

把相应的宽高设置好。

  • 给page设置display: table;,设置后该元素就会作为一个容器,就像 <table> 标签一样

  • 再给page设置 table-layout: fixed;,设置后列宽由表格的首个单元格决定

  • 给page下的所有div设置 display: table-cell;,设置后该元素的表现行为设置为类似表格单元格,所有的div容器变成单元格排成一行了,left和right宽度为200px,content为100%,就会占满剩下的宽度,就实现了想要的效果。

5. grid布局

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <style>
        * {
            margin: 0;
            padding: 0;
        }

        .page {
            width: 100vw;
            height: 200px;
            display: grid;
            grid-template-columns: 200px auto 200px;
            
        }


        .left,
        .right {
            height: 200px;
            background: rgb(81, 226, 81);

        }
        .content {
            height: 200px;
            background-color: #c7f121;
        }
    </style>
</head>

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

</html>

宽度不要,基本框架保持不变。主要实现方法是在page上:

page {
            width: 100vw;
            height: 200px;
            display: grid;
            grid-template-columns: 200px auto 200px;
            
        }

image.png

让宽度占满,分别给两个广告位的赋予200 px 的边距,在通过 display: grid;让主体内容优先。

image.png

这是基于table框架上的,方法不够优雅,但是也能实现相同的效果。

总结:

三栏布局是页面动态规划的精美体现,侧边栏和内容区域将自动排列在同一水平线上,并且当窗口大小变化时,布局能够保持美观和功能性。这是一个现代的、响应式的设计方法,适用于创建复杂的多栏布局。大家可以自行屡屡不同之处在哪里。