高频的面试考题(收藏细品)——三栏布局

200 阅读6分钟

什么是三栏布局?

三栏布局是一种经典的网页布局设计,它将页面横向划分为三个垂直并列的部分:左侧栏、中间栏、以及右侧栏。这种布局方式广泛应用于需要展示多项并行内容的网页,如新闻网站、电子商务平台、博客和企业门户等。

三栏布局的作用

三栏布局通常包括两个固定宽度的侧边栏(左侧栏和右侧栏)和一个自适应宽度的中间栏。

  • 侧边栏常用于放置导航菜单、广告、快捷链接或辅助信息,
  • 中间栏则是主要的内容展示区域,其宽度会根据浏览器窗口的大小自动调整,确保内容的可读性和布局的完整性。

优点:

  1. 布局的完整,可突出中间栏的主要内容。
  2. 自适应的宽度,让其兼容性更强,用户体验感更好。
  3. 既达到了用户浏览内容的目的,也给网站预留了商业广告位。

就像掘金社区这样标准的三栏布局: image.png

还有很多其他的网站,都在使用三栏布局,可见三栏布局应用及其广泛。 image.png

如何实现三栏布局呢?

  • 准备工作: 先做好页面的整体布局,一个大盒子包含了三个小盒子分别如图所示:

    image.png

    image.png

  • 中间内容部分不设宽度让其自适应,左右侧栏定宽高(这里只是测试,当然在真正项目内,我们都是定宽不定高的)。 产生的效果如下图所示: image.png 这个很正常div盒子都是块级元素,都会占据一整行。

  • 然后接下来就是正常的想法了,让每一个块级元素变为行内块元素,这样既可以让三个盒子放到同一行,也能改变行内元素不能修改宽高的规则,简直一举两得!

    image.png image.png 但是当我们给每个div设为行内块元素时,竟然变成这样了?这是因为我们没有给中间内容栏加宽度,目前只有文字撑起的宽度。

  • 注意细节的小伙伴应该注意到了,上面初始化时被我注释掉的代码了,没错,他能够解决我们的问题。

    image.png 我们设置中间栏的宽度时给他做一个简单的css运算就好了。calc() 是一个CSS函数,用于动态计算长度、频率、角度、时间、百分比、数值等值。

    image.png

在这里,我们不得不说这个方法简单、易懂,但是它真的符合要求吗?我们知道html网页的代码是从上往下的加载的,当内容较多的时候,广告位的内容竟然比网站内容加载更快,这显然是不合理的吧?应该先加载内容,再去加载广告的。

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

其他实现三栏布局的方法

现在让我们尝试一下用其他更好、更符合场景的方法来实现三栏布局把!以下布局均为内容先加载,广告位后加载!

圣杯布局

给其加上基本样式,如下:

<style>
        *{
            margin: 0;
            padding: 0;
        }
        .page{
            height: 200px;
        }
        .left,.right{
            height: 200px;
            width: 200px;
            background-color: aqua;
        }
        .content{
            height: 200px;
            background-color: pink;
        }
</style>

它的运行结果就是这样的:

image.png 又因为,圣杯布局双飞翼布局:这两种布局模式是浮动布局的高级应用,通过负margin和padding技巧,实现了在不增加额外标记的情况下,左右固定宽度,中间自适应的效果。

圣杯布局主要是靠padding和浮动,再配合负margin-left来移动广告位的位置,所以具体实现如下:

       .page{
            padding: 0px 200px;   /*上下为0px 左右内边距为200px */ 
        }
        .page div{
            float: left;
        }
        .content{ 
            width: 100%;
        }

由于类名为page的div盒子其父元素标签是body,给它设置padding内边距时,就是相距body的距离,且刚好空出了左右两个边距可以放下广告位盒子。

又因为一开始主要内容的盒子是块级元素独占一整行,如果没有给其设置宽度:他会出现如下的效果

image.png 内容决定宽度:如果浮动元素内部的内容不足以撑开元素,且没有显式设置宽度,那么元素的宽度将会紧密包裹内容,给人一种“宽度消失”的错觉。所以我们需要给主要内容盒子设置宽度100%,效果显示如下:

image.png

这样是不是又出问题了呢,他们都没在用一行啊!其实并没有,这都是浮动带来的影响,实际上他们都是在同一行的,只不过由于page内的主要内容盒子设置宽度100%,导致page装不下了,就在下面显示了,这是浮动产生的一个特点。

image.png

image.png 然后我们加入样式:

.left{
     position: relative; 
     margin-left: -200px;
     left: -100%;
}
.right{
     /* position: relative; 
     right: -200px;
     margin-left: -200px; */
     margin-right: -200px;   /*效果和上面注释的一样*/
}

.leftposition设为relative,而其相对定位是基于自身在文档流中的初始位置来进行计算和偏移的,然后我们使用left=-100%,这个百分百的宽的就是page的宽度,如果left越大且为正数,是让盒子可以向右移动(距离左边界的距离),但是设为负值,说明盒子需要向右移动,且移动的距离为page的宽度。 image.png

双飞翼布局

  • 对于飞翼布局,它和前面的圣杯布局有点相似,但是我们的内容位置有所更改: image.png

  • 飞翼布局主要是为了外边距可以空出广告位的内容,而不会被广告位遮盖住,所以:

    image.png

    它的效果就如下所示:左右刚好空出了位置 image.png 给div加浮动,这里我们只需要给page的子元素div加浮动,所有用>符号,代表page下的div,不包括其孙子节点的元素。

.page > div{
     float: left;
}
.left{
     margin-left: -100%;
}
.right{
     margin-left: -200px;
}
  • 最终效果就像下面这样: image.png

这里还有其他的三栏布局实现方法,感兴趣的小伙伴可以去看看哦! 细品三栏布局中的弹性flex、grid、table等布局 - 掘金 (juejin.cn)