CSS布局 圣杯和双飞翼

圣杯布局和双飞翼布局

圣杯布局和双飞翼布局是前端工程师需要日常掌握的重要布局方式。两者的功能相同,都是为了实现一个两侧宽度固定,中间宽度自适应的三栏布局,都遵循了以下要点:

  • 两侧宽度固定,中间宽度自适应
  • 中间部分在DOM结构上优先,以便先行渲染
  • 允许三列中的任意一列成为最高列
  • 只需要使用一个额外的<div>标签

1. 圣杯布局

结构

<div class="container">
    <div class="main">中间</div>
    <div class="left">左边</div>
    <div class="right">右边</div>
</div>

样式

.container {
    /* 初始化 */
    height: 100px;
    background-color: wheat;
    /* 防止left和right遮住main */
    padding: 0 100px;
    /* 防止转行 */
    min-width: 100px;
}

.left,
.right {
    /* 初始化 */
    background-color: mediumslateblue;
    width: 100px;
    height: 100px;
    float: left;
}

.main {
    /* 初始化 */
    width: 100%;
    height: 100px;
    background-color: mediumseagreen;
    float: left;
}

.left {
    /* 回到上一行开头 */
    margin-left: -100%;
    /* 移动到父元素padding区域 */
    position: relative;
    left: -100px;
}

.right {
    /* 回到上一行结尾 */
    margin-left: -100px;
    /* 移动到父元素padding区域 */
    position: relative;
    right: -100px;
}

实现过程

  • 给main,left,right加浮动,left,right宽100px,main宽度100%;

  • 左右元素设置margin-left,到达上一行左右两端

  • main部分区域被left,right遮掉了, 设置container左右padding为100px,然后相对定位移动left,right位置
  • 设置container最小宽度100px防止窗口缩小转行

2. 双飞翼布局

结构

<div class="container">
    <div class="main">中间</div>
</div>
<div class="right">右边</div>
<div class="left">左边</div>

样式

body {
    min-width: 300px;/* 防止换行 */
}

.container {
    /* 初始化 */
    width: 100%;
    height: 100px;
    background-color: wheat;
}

.main {
    height: 100px;
    margin: 0 100px;
    background-color: mediumseagreen;
}

.left {
    /* 初始化 */
    width: 100px;
    height: 100px;
    background-color: mediumslateblue;
    /* 转到上一行 */
    margin-left: -100%;
}

.right {
    /* 初始化 */
    width: 100px;
    height: 100px;
    background-color: mediumturquoise;
    /* 转到上一行 */
    margin-left: -100px;
}

.left,
.right,
.container {
    /* 给三个盒子加浮动从而可以通过margin换行 */
    float: left;
}

实现过程

  • 设置main的左右margin(或者padding)使其内容在container中间,流出两边位置给left,right

  • 设置container,left,right的浮动

  • 设值left和right的margin使其回到上一行

  • 防止换行,设置三者的父元素min-width=left的宽度+right的宽度+container的最小宽度(假设100)=300px

通过对圣杯布局和双飞翼布局的介绍可以看出,圣杯布局在DOM结构上显得更加直观和自然,且在日常开发过程中,更容易形成这样的DOM结构(通常<aside><article>/<section>一起被嵌套在<main>中);而双飞翼布局在实现上由于不需要使用定位,所以更加简洁,且允许的页面最小宽度通常比圣杯布局更小。

其实通过思考不难发现,两者在代码实现上都额外引入了一个<div>标签,其目的都是为了既能保证中间栏产生浮动(浮动后还必须显式设置宽度),又能限制自身宽度为两侧栏留出空间。

3. 其他实现方式

若不考虑兼容性,可以使用更简单的实现方式:
flex布局

<div class="container">
    <div class="main"> 中间 </div>
    <div class="left">左边</div>
    <div class="right">右边</div>
</div>
.container {
    display: flex;
    background-color: mediumslateblue;
}
.main {
    flex: 1;
    background-color: mediumseagreen;
}
.left {
    order: -1;/* 排列顺序 */
    flex: 0 0 100px;
    background-color: mediumslateblue;
}
.right {
    flex: 0 0 100px;
    background-color: mediumslateblue;
}

calc计算

/* 省略... */
.main, .left, .right {
    float: left;
}
.main {
    margin: 0 100px;/* 左右边距 */
    width: calc(100% - 200px);/* 计算宽度 */
}

border-box

.main,
.left,
.right {
    float: left;
}
.main {
    width: 100%;
    box-sizing: border-box;
    padding: 0 100px;/* padding值从width里减 */
}
posted @ 2020-05-08 12:49  aeipyuan  阅读(130)  评论(0编辑  收藏  举报