我悟了!面试常考题:三栏布局

205 阅读5分钟

三栏布局可以说是一个非常经典的布局方式,在我们的网上日常冲浪时几乎处处都存在这种布局。比如,我们使用的掘金。

image.png

我看到这玩意,闭着眼睛就想到了弹性布局flex

讲解前我们先做一下基本的准备,实现一个简单的样式。

基础代码

<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>弹性布局</title>
    <style>
        * {
            margin: 0;
            padding: 0;
        }
        .left,
        .right {
            height: 200px;
            width: 200px;
            background: rgb(68, 170, 160);
        }
        .content {
            height: 200px;
            background: rgb(233, 113, 133);
        }
    </style>
</head>

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

其中,content为何放在left的上面呢?

这是因为通常网页一般都是使内容优先加载,html的加载都是自上而下的,这样的排布才能实现优先加载的效果。

效果展示

image.png

目标样式

image.png

弹性布局flex

对于三栏布局,我认为这种方法是最简单最方便的。我们只需要给三栏的父容器添加一个.page {display: flex;} ,在使用一个order属性即可。order属性是弹性布局中用于排列顺序的属性,值越小,排列顺序越靠前,所以我们只需要让中栏内容order为1,左栏为默认0,右栏为2。

在该案例中,我们没有给中栏宽度属性,所以可以再给中栏添加flex:1属性,使其来分配剩余空间。

<style>
        * {
            margin: 0;
            padding: 0;
        }
        .page {
            display: flex;
        }
        .left,
        .right {
            height: 200px;
            width: 200px;
            background: rgb(68, 170, 160);
        }

        .content {
            height: 200px;
            background: rgb(233, 113, 133);
        }
        .content{
            flex: 1;
            order: 1;
        }
        .right{
            order: 2;
        }
    </style>

接下来给大家介绍另外几种方式实现三栏布局。

圣杯布局

圣杯布局是一种经典的三栏布局解决方案,它满足了两侧栏固定宽度、中间栏自适应宽度的需求,同时确保主要内容(中间栏)优先加载。其实现原理是利用浮动(float)和负外边距(negative margin)。

  • page设置padding属性,200px的外边距给左右两栏预留空间。
  • 所有直接子元素采用浮动布局,使它们能够水平排列。给中栏设置width: 100%使其将两个左右栏挤到下一行。
* {
            margin: 0;
            padding: 0;
        }

        .page {
            padding: 0 200px;
            /* height: 200px; */
            /* font-size: 0; */
        }

        .left,
        .right {
            height: 200px;
            width: 200px;
            background: rgb(68, 170, 160);
        }

        .content {
            height: 200px;
           /*  width: calc(100% - 400px); */
            background: rgb(233, 113, 133);
            width: 100%;

        }

        /* .page div {
             display: inline-block; 
            font-size: 20px;
        } */
        .page div{
            float: left;
        }
  • leftright分别使用绝对定位。首先,都使用margin-left: -200px,它将元素的左边外边距设为负值(在这里是-200px)。这意味着侧栏会被“移出”其正常流位置,向左移动200px。然后,分别设置left: -100%left:-200px使左右两栏到达指定位置。

实现代码及效果

双飞翼布局

双飞翼布局是圣杯布局的一种变体,它在圣杯布局基础上进行了简化,同样实现了三栏布局的需求,但通过更简洁的CSS实现。

我们来看看双飞翼的html部分代码就明白了。

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

这里给中间栏添加了一个div,根据圣杯布局的预留位置的思想,可以清晰的明白,这里是通过给inner设置外边距来给左右两栏留位置。这样的做法再结合只对.page>div做浮动,可以使左右两栏不再需要通过绝对定位来实现效果,只需要调整margin-left即可。

从下面效果图可以看出蓝色空白处是给左右两栏留的位置。

image.png

实现代码及效果

表格布局

表格布局的操作比较简单,只需要对.page>div添加display: table-cell,不过此方法不能实现中栏内容优先加载。其html部分如下:

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

display: table-cell会使其子元素就算不是table也会按照table布局排列,且根据元素的宽度自适应调整。

实现代码及效果

网格布局

网格布局同样无法实现中栏内容优先加载,但是其布局能力非常的灵活、强大。仅仅只需要对.page添加display: grid; grid-template-columns: 200px auto 200px;

display: grid会使该元素的子元素会按照网格布局来排列,而不是按照正常的文档流(block、inline等)布局。网格布局是一种二维布局系统,可以让你在行和列中组织内容,非常适合于创建复杂的网页布局。

grid-template-columns: 200px auto 200px;这行代码定义了网格容器中列的宽度。

实现代码及效果

总结

在实现三栏布局,尤其是追求主要内容优先加载、左右固定宽度、中间自适应的场景中,弹性布局(Flexbox)是较为推荐的选择,它们不仅提供了现代、高效的解决方案,而且代码简洁、易于维护。圣杯布局和双飞翼布局作为经典方案,虽在某些特定环境下仍有价值,但对于追求前沿技术和良好兼容性的项目来说,弹性布局显然是更优的选择。