面试官:如何实现三栏布局?

1,023 阅读6分钟

在实际开发过程中,其实我们经常能看到三栏布局的场景;它通常包含一个主内容区域和两个侧边栏(一个在左侧,一个在右侧),并且主内容要优先显示。那我们要怎么去实现三栏布局的效果呢?

三栏布局

无标题.png

上面就是一个经典的三栏布局,我们有哪些方法可以去实现它呢?

主要内容优先显示

因为我们要让中间部分的内容优先渲染,确保重要信息首先显示;所以HTML结构应该如下所示:

<body>
    <div class="page">
        <!-- 主要内容优先加载 -->
        <div class="content">主要内容</div>
        <div class="left">广告位</div>
        <div class="right">广告位</div>
    </div>
</body>

以下是一些常见的能够实现三栏布局的方式;

圣杯布局

在早期,实现一个响应式的三栏布局的方式,被称为圣杯布局;也是包含一个主内容区域和两个侧边栏并且左侧和右侧的宽度固定不变,中间的主内容区域宽度自适应

我们可以用使用 float 浮动和负边距实现圣杯布局

<!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>
        *{
            padding: 0;
            margin: 0;
        }
        .page{
            height: 200px;
            padding: 0 200px;
        }
        .left, .right{
            height: 200px;
            width: 200px;
            background-color: green;
        }
        .content{
            height: 200px;
            background-color: yellow;
            width: 100%;
        }
        .page div{
            float: left;
        }
        .left{
            margin-left: -200px;
            position: relative;
            left: -100%;
        }
        .right{
            /* margin-left: -200px;
            position: relative;
            right: -200px; */
            margin-right: -200px;
        }
    </style>
</head>
<body>
    <div class="page">
        <div class="content">主要内容</div>
        <div class="left">广告位</div>
        <div class="right">广告位</div>
    </div>
</body>
</html>

padding: 0 200px;

我们先给 page 容器左右两边设了200px的内边距,腾出位置让其左右两边放广告位;

无标题.png

margin-left: -200px;

接下来,我们可以通过margin-left 设为负边距 -200px 去移动广告位;

无标题1.png

我们可以想象一下,广告位本来的位置如上图所示,是因为我们设了内边距才导致广告位被挤下来了;再设置负边距的话就会让广告位显示如上效果。

left: -100%;

接下来,我们通过定位的方式 position: relative; 并且 left: -100%; 让广告位向左靠 100% 相对于父容器的宽度

left: -100%; 会相对父容器的宽度的100%,是因为当宽度没有明确设置时,默认情况下,大多数块级元素(如 <div><p> 等)的宽度会继承自其父元素的内容宽度。这是因为块级元素默认的宽度行为是 100% 的父元素宽度,除非它们被显式地设置为其他值

无标题2.png

margin-right: -200px;

对于右边的广告位,我们同样也可以用上面的方案实现;除此之外,我们还可以直接设 margin-right: -200px; 也能够实现;

image.png

以上就是一个比较经典的圣杯布局的实现方法。

双飞翼布局

双飞翼布局(Double Wing Layout) 是另一种实现三栏布局的方法,它与圣杯布局类似,但实现方式有所不同。双飞翼布局的特点是它不需要使用内边距,并且可以很好地处理内容高度不一致的情况。

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>双飞翼</title>
    <style>
        *{
            padding: 0;
            margin: 0;
        }
        .page{
            height: 200px;
        }
        .left, .right{
            width: 200px;
            height: 200px;
            background-color: green;
        }
        .content{
            height: 200px;
            background-color: pink;
            width: 100%;
        }
        .inner{
            margin: 0 200px;
            height: 100%;
        }
        .page > div{
            float: left;
        }
        .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>

margin: 0 200px;

和圣杯布局不一样,双飞翼布局使用的是外边距 margin 设置为了200px

无标题3.png

主要内容旁边两侧的 margin 部分同样是用来放广告位的。

margin-left: -100%;

当广告位的 margin-left 属性被设置成百分比时,它表示的是相对于父容器总宽度的百分比左外边距;故 margin-left: -100%; 会让广告位向左靠父容器100%的宽度。

image.png

这样,左边的广告位就放置好了。

margin-left: -200px;

同样的对于右边的广告位,我们也可以用这种做法,只需margin-left 属性设为 -200px 即可。

image.png

可以看出,双飞翼布局比圣杯布局更简便一些。

弹性布局

弹性布局是一个非常强大的布局方式,用弹性布局也可以轻松地实现三栏布局

在弹性布局中,有一个属性可以让我们非常容易就实现三栏布局并且主要内容优先加载,那就是 order

order

order 属性可以用来控制弹性项目或网格项在容器中的排序顺序;它允许你重新安排项目的顺序,而不必改变 HTML 中元素的实际顺序order 属性的默认值是 0,你可以为每个项目指定一个整数值来控制它们的排序顺序,数值越小,项目越靠前

<!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>
        *{
            padding: 0;
            margin: 0;
        }
        .page{
            height: 200px;
        }
        .left, .right{
            height: 200px;
            width: 200px;
            background-color: green;
        }
        .content{
            height: 200px;
            background-color: yellow;
            width: 100%;
        }
        .page{
            display: flex;
        }
        .content{
            flex: 1;
            order: 1;
        }
        .right{
            order: 2;
        }
    </style>
</head>
<body>
    <div class="page">
        <div class="content">主要内容</div>
        <div class="left">广告位</div>
        <div class="right">广告位</div>
    </div>
</body>
</html>

利用 order 也可以实现三栏布局。

image.png

主要内容不能优先显示

除了上面几种方法外,还有 table 表格布局和 grid 网格布局也能够实现三栏布局,但是它们的缺点就是不能让主要内容优先显示

table 布局

在 Web 开发中,table 布局是一种传统的布局方法,它使用 HTML 的表格元素 (<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>
        *{
            padding: 0;
            margin: 0;
        }
        .page{
            height: 200px;
        }
        .left, .right{
            height: 200px;
            width: 200px;
            background-color: green;
        }
        .content{
            height: 200px;
            background-color: yellow;
        }
        .page{
            display: table;
            table-layout: fixed;
            width: 100%;
        }   
        .page>div{
            display: table-cell;
        }
        .content{
            width: 100%;
        }
    </style>
</head>
<body>
    <div class="page">
        <div class="left">广告位</div>
        <div class="content">主要内容</div>
        <div class="right">广告位</div>
    </div>
</body>
</html>

display: table;

将父容器的布局方式设置为表格;

image.png

table-layout: fixed;

table-layout: fixed; :此属性设置为 fixed 时,表格的列宽是根据第一行的 <th> 或 <td> 元素确定的,或者是根据 CSS 明确设置的宽度。一旦列宽确定,所有其他行的列宽都将保持不变,即使单元格的内容超出列宽,也不会影响其他单元格的宽度。

display: table-cell;

将子容器都设为表格单元,默认是横向排布

image.png

width: 100%;

最后,要记得给父容器和主要内容部分都设置宽度为 width: 100%;

image.png

grid 网格布局

CSS 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>
        *{
            padding: 0;
            margin: 0;
        }
        .page{
            height: 200px;
        }
        .left, .right{
            height: 200px;
            width: 200px;
            background-color: green;
        }
        .content{
            height: 200px;
            background-color: yellow;
        }
        .page{
            display: grid;
            grid-template-columns: 200px auto 200px;
        }

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

display: grid;

display: grid; 是一个 CSS 属性,用于将一个元素设置为 Grid 容器,这意味着该元素将遵循 CSS Grid 布局模型。Grid 布局允许你在二维空间(行和列)中精确地控制子元素的位置和大小。

grid-template-columns: 200px auto 200px;

接下来,只需要把它设置为3列,且两边的宽度固定,中间的是自适应

image.png

非常简单的两步就可以轻松实现一个简单的三栏布局。

以上就是实现三栏布局的一些方式,觉得有用的话就点点赞吧。