实现三栏布局的三种方式:圣杯布局、双飞翼布局、flex布局

三栏布局的特点:两侧宽度固定、中间宽度自适应。同时,还要能够满足这两个条件:1.中间部分优先渲染 2.允许任意一列成为最高列

三栏布局最终要达到的效果如下:

image-20210603224839745

圣杯布局

圣杯布局来源:https://alistapart.com/article/holygrail

圣杯布局所有的代码如下:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <style>
        * {
            margin: 0;
            padding: 0;
        }
        body {
            min-width: 550px;
            font-size: 25px;
        }
        header, footer {
            height: 80px;
            text-align: center;
            line-height: 80px;
            background-color: #666;
        }
        main {
            overflow: hidden;
            padding-left: 200px;
            padding-right: 150px;
        }
        .column {
            float: left;
            position: relative;
            text-align: center;
            height: 500px;
            line-height: 500px;
        }
        .center {
            width: 100%;
            background-color: #d6d6d6;
        }
        .left {
            left: -200px;
            width: 200px;
            margin-left: -100%;
            background-color: #77bbdd;
        }
        .right {
            width: 150px;
            margin-right: -150px;
            background-color: #E16633;
        }
    </style>
</head>
<body>
    <header>header</header>
    <main>
        <div class="center column">center</div>
        <div class="left column">left</div>
        <div class="right column">right</div>
    </main>
    <footer>footer</footer>
</body>
</html>

下面介绍每一步的关键代码:

添加基础的结构,在 main 区域中为左栏和右栏分别腾出 200px、150px 的空间
<header>header</header>
<main></main>
<footer>footer</footer>
main {
    padding-left: 200px;
    padding-right: 150px;
}
在 main 区域插入三栏,设置左右两栏为固定宽度 200px、150px,中间宽度为 100%
<header>header</header>
<main>
    <div class="center column">center</div>
    <div class="left column">left</div>
    <div class="right column">right</div>
</main>
<footer>footer</footer>
.center {
    width: 100%;
}
.left {
    width: 200px;
}
.right {
    width: 150px;
}

现在页面布局如下:

image-20210603231938960

三栏全部设置浮动,给 main 清除浮动
.column {
    float: left;
}
main {
	overflow: hidden;
}

overflow: hidden 是为了清除子元素的浮动,main区域生成 BFC,撑开文档的高度

image-20210603232106885

调整左栏的位置

设置 margin 负值,把左栏往上移

.left {
	margin-left: -100%;
}

image-20210603232231810

设置 left: -200px 把左栏往左移200px

.column {
    position: relative;
}
.left {
	left: -200px;
}

image-20210603232744973

调整右栏的位置
.right {
	margin-right: -150px;
}

调整右栏的位置还有一种方式:

.right {
	margin-left: -150px;
	right: 150px;
}

image-20210603224839745

给body设置min-width

当浏览器窗口的大小发生变化时,可能会导致中间的宽度小于左栏的宽度。给body设置最小宽度后,可以使这三列保持原位。min-width的大小为:左栏的宽度+右栏的宽度+左栏 left 设置的宽度

body {
	min-width: 550px;
}

双飞翼布局

双飞翼布局所有的代码如下:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <style>
        * {
            margin: 0;
            padding: 0;
        }
        body {
            min-width: 550px;
            font-size: 25px;
        }
        header, footer {
            height: 80px;
            text-align: center;
            line-height: 80px;
            background-color: #666;
        }
        main {
            overflow: hidden;
        }
        .column {
            float: left;
            text-align: center;
            height: 500px;
            line-height: 500px;
        }
        .center {
            width: 100%;
            background-color: #d6d6d6;
        }
        .center > .content {
            padding-left: 200px;
            padding-right: 150px;
        }
        .left {
            width: 200px;
            margin-left: -100%;
            background-color: #77bbdd;
        }
        .right {
            width: 150px;
            margin-left: -150px;
            background-color: #E16633;
        }
    </style>
</head>
<body>
    <header>header</header>
    <main>
        <div class="center column">
            <div class="content">center</div>
        </div>
        <div class="left column">left</div>
        <div class="right column">right</div>
    </main>
    <footer>footer</footer>
</body>
</html>

双飞翼布局和圣杯布局的实现原理差不多,都是利用 margin 负值来实现的。不过双飞翼布局的 CSS 结构更简单些,不需要用到 left 等偏移属性

下面介绍每一步的关键代码:

添加基础的HTML结构
<header>header</header>
<main>
    <div class="center column">
        <div class="content">center</div>
    </div>
    <div class="left column">left</div>
    <div class="right column">right</div>
</main>
<footer>footer</footer>
分别设置三栏的宽度,给 .center 内的 .content 盒子设置 margin,来为左右两栏腾出空间
.center {
	width: 100%;
}
.center > .content {
	padding-left: 200px;
	padding-right: 150px;
}
.left {
	width: 200px;
}
.right {
	width: 150px;
}

现在页面布局如下:

image-20210604220635113

三栏全部设置浮动,给 main 清除浮动
.column {
    float: left;
}
main {
	overflow: hidden;
}

image-20210604220739507

调整左栏的位置
.left {
	margin-left: -100%;
}

image-20210604221102430

调整右栏的位置

注意:在圣杯布局里,调整右栏使用的是 margin-right: -150px

.right {
	margin-left: -150px;
}

image-20210603224839745

给body设置min-width
body {
	min-width: 550px;
}

圣杯布局和双飞翼布局的区别

  1. 双飞翼布局在主内容div外面加了一层div
  2. 圣杯布局设置的是主内容div的宽度为100%,双飞翼设置的是主内容div外面的div的宽度为100%
  3. 圣杯布局是给包裹三栏的div添加左右padding,双飞翼是给主内容div添加左右padding
  4. 双飞翼布局不需要使用偏移属性

flex布局

flex布局所有的代码如下:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <style>
        * {
            margin: 0;
            padding: 0;
        }
        body {
            font-size: 25px;
        }
        header, footer {
            height: 80px;
            text-align: center;
            line-height: 80px;
            background-color: #666;
        }
        .column {
            text-align: center;
            height: 500px;
            line-height: 500px;
        }
        main {
            display: flex;
        }
        .center {
            flex: 1;
            background-color: #d6d6d6;
        }
        .left {
            flex: 0 0 200px;
            order: -1;
            background-color: #77bbdd;
        }
        .right {
            flex: 0 0 150px;
            background-color: #E16633;
        }
    </style>
</head>
<body>
    <header>header</header>
    <main>
        <div class="center column">center</div>
        <div class="left column">left</div>
        <div class="right column">right</div>
    </main>
    <footer>footer</footer>
</body>
</html>