三栏布局

379 阅读3分钟

三栏布局

问题:假设容器的高度默认100px,请写出三栏布局,其中左栏、右栏的宽度各为300px,中间的宽度自适应。

方法

浮动

左侧设置左浮动,右侧设置右浮动即可,中间会自动地自适应。

绝对定位

左侧设置为绝对定位, left:0px。右侧设置为绝对定位, right:0px。中间设置为绝对定位,left 和right 都为300px,即可。中间的宽度会自适应。

使用article标签作为容器,包裹左、中、右三个部分。

Flexbox布局

flex:1即为flex-grow:1,经常用作自适应布局,将父容器设置display:flex,侧边栏大小固定后,将内容区flex:1,内容区则会自动放大占满剩余空间。

表格布局 table

设置整个容器的宽度为100%,设置三个部分均为表格,然后左边的单元格为 300px,右边的单元格为 300px,即可。中间的单元格会自适应。

网格布局 grid

设置容器为网格布局display: grid,宽度为100% 设置网格为三列,并设置每列的宽度grid-template-columns: 300px auto 300px

效果

5mDMKs.gif

代码

<!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>页面布局</title>
    <style>
        html *{
            padding: 0;
            margin: 0;
        }
        .layout article div{
            height: 100px;
        }
        .layout{
            margin-top: 20px;
        }
        /* 1.浮动 */
        /* .layout.float表示交集选择器,空格表示后代选择器 */
        .layout.float .left{
            float: left;
            width: 300px;
            background: red;
        }
        .layout.float .right{
            float: right;
            width: 300px;
            background: blue;
        }
        .layout.float .center{
            background: green;
        }
        /* 2.绝对定位 */
        .layout.absolute{
            margin-top: 100px;
        }
        .layout.absolute .left{
            position: absolute;
            left: 0;
            width: 300px;
            background: red;
        }
        /* 【重要】中间的区域,左侧定位300px,右侧定位为300px,即可完成。宽度会自适应 */
        .layout.absolute .center{
            position: absolute;
            left: 300px;
            right: 300px;
            background: green;
        }
        .layout.absolute .right{
            position: absolute;
            right: 0;
            width: 300px;
            background: blue;
        }
        /* 3.flex */
        /* 绝对布局导致脱离文档流,因此上边距300px是从方法一中还在文档流的元素开始算 */
        .layout.flex{
            margin-top: 230px;
        }
        .layout.flex .left-center-right{
            display: flex;
        }
        .layout.flex .left {
            width: 300px;
            background: red;
        }
​
        .layout.flex .center {
            flex: 1;
            background: green;
        }
​
        .layout.flex .right {
            width: 300px;
            background: blue;
        }
        /* 4.表格 */
        /* 重要:设置容器为表格布局,宽度为100% */
        .layout.table .left-center-right{
            width: 100%;
            display: table;
        }
        /* 重要:设置三个模块为表格里的单元*/
        .layout.table .left-center-right div{
            display: table-cell;
        }
        .layout.table .left{
            width: 300px;
            background: red;
        }
        .layout.table .center {
            background: green;
        }
​
        .layout.table .right {
            width: 300px;
            background: blue;
        }
        /* 5.网格 */
        /* 重要:设置容器为网格布局,宽度为100% */
        /* 设置网格为三列,并设置每列的宽度。即可。 */
        .layout.grid .left-center-right{
            display: grid;
            width: 100%;
            /* grid-template-rows: 100px; */
            grid-template-columns: 300px auto 300px;
        }
        .layout.grid .left {
            background: red;
        }
        .layout.grid .center {
            background: green;
        }
        .layout.grid .right {
            background: blue;
        }
    </style>
</head>
<body>
    <!-- 方法一:浮动 -->
    <!-- 
        元素设置浮动以后,会完全从文档流中脱离,不再占用文档流的位置,
         所以元素下边的还在文档流中的元素会自动向上移动 
    -->
    <!-- 输入 section.layout.float,即可生成 -->
    <section class="layout float">
        <!-- 用article标签包裹左、中、右三个部分 -->
        <article class="left-center-right">
            <div class="left">
                left
            </div>
            <div class="right">
                right
            </div>
            <div class="center">
                <h1>浮动</h1>
                center
            </div>
        </article>
    <!-- 方法二:绝对定位 -->
    </section>
    <section class="layout absolute">
        <article class="left-center-right">
            <div class="left">
                left
            </div>
            <div class="center">
                <h1>绝对定位</h1>
                center
            </div>
            <div class="right">
                right
            </div>
        </article>
    </section>
    <!-- 方法三:flex -->
    <section class="layout flex">
        <article class="left-center-right">
            <div class="left">
                我是 left
            </div>
            <div class="center">
                <h1>flex布局</h1>
                我是 center
            </div>
            <div class="right">
                我是 right
            </div>
        </article>
    </section>
    <!-- 方法四、表格 -->
    <section class="layout table">
        <article class="left-center-right">
            <div class="left">
                left
            </div>
            <div class="center">
                <h1>表格布局</h1>
                center
            </div>
            <div class="right">
                right
            </div>
        </article>
    </section>
    <!-- 方法五、网格 -->
    <section class="layout grid">
        <article class="left-center-right">
            <div class="left">
                left
            </div>
            <div class="center">
                <h1>网格布局</h1>
                center
            </div>
            <div class="right">
                right
            </div>
​
        </article>
    </section>
</body>
</html>

延伸

五种方法的对比

  • 五种方法的优缺点
  • 考虑中间模块的高度问题
  • 兼容性问题:实际开发中,哪个最实用?

方法1:浮动:

  • 优点:兼容性较好。
  • 缺点:浮动是脱离文档流的,如果处理不好,会带来很多问题。有些时候需要清除浮动,需要很好的处理浮动周边元素的关系。

方法:2:绝对定位

  • 优点:快捷。
  • 缺点:布局脱离文档流,意味着下面的子元素也要脱离文档流,导致这个方案的有效性是比较差的。

方法3:flex 布局

  • 优点:比较完美的解决了浮动和绝对定位的问题。在移动端比较常用
  • 缺点:兼容性比较差,不兼容IE8及以下的版本。因为这个是CSS3中新增的display的属性值。

方法4:表格布局

  • 优点:表格布局在很多场景中很实用,兼容性非常好。因为IE8不支持 flex,此时可以尝试表格布局。
  • 缺点:因为三个部分都当成了单元格来对待,此时,如果中间的部分变高了,其会部分也会被迫调整高度(即使其余部分单独设置了高度)。但是,在很多场景下,我们并不需要两侧的高度增高。

方法5:网格布局

  • CSS3中引入的布局,很好用。代码量简化了很多。

如果题目中去掉高度已知

问题:题目中,如果去掉高度已知,我们往中间的模块里塞很多内容,让中间的模块撑开。会发生什么变化?

5my7i6.gif

页面布局的变通

三栏布局

  • 左右宽度固定,中间自适应
  • 上下高度固定,中间自适应

两栏布局

  • 左宽度固定,右自适应
  • 右宽度固定,左自适应
  • 上宽度固定,下自适应
  • 下宽度固定,上自适应