CSS 一行三列

🌙
手机阅读
本文目录结构

float 定位

<style>
    #wrap {
        width: 100%;
        height: auto;
    }

    #column {
        float: left;
        width: 60%;
    }

    #column1 {
        float: left;
        width: 30%;
    }

    #column2 {
        float: right;
        width: 30%;
    }

    #column3 {
        float: right;
        width: 40%;
    }

    .clear {
        clear: both;
    }
</style>

<div id="warp">
    <div id="column">
        <div id="column1">第一列</div>
        <div id="column2">第二列</div>
        <div class="clear"></div>
    </div>
    <div id="column3">第三列</div>
    <div class="clear"></div>
</div>

绝对定位

单行三列采用绝对定位

<style>
    #left {
        position: absolute;
        top: 0px;
        left: 0px;
        width: 120px;
        background-color: aqua;
    }

    #middle {
        margin: 0 190px;
        background-color: red;
    }

    #right {
        position: absolute;
        top: 0px;
        right: 0px;
        width: 120px;
        background-color: orange;
    }
</style>
<div id="left">111</div>
<div id="middle">222</div>
<div id="right">333</div>

CSS 顶部、底部定高,左右两侧定宽,中间自适应

<div class="body">
    <div class="header"></div>
    <div class="section">
      <div class="left"></div>
      <div class="center">111</div>
      <div class="right"></div>
    </div>
</div>

1. flex 布局

.header{
    height: 80px;
    background-color: #515A6E;
  }
  .section{
    background-color: #afc7de;
    flex: 1;
    display: flex;
  }
  .left{
    background-color: #fff;
    width: 100px;
  }
  .center{
    flex: 1;
    background-color: #F5F7F9;
  }
  .right{
    width: 100px;
    background-color: #fff;
  }

2. 定位

.body{
  height: 100%;
  position: relative;
}
.header{
  height: 80px;
  background-color: #515A6E;
}
.section{
  position: absolute;
  width: 100%;
  left: 0;
  top: 80px;
  bottom: 0;
  right: 0;
  background-color: #afc7de;
}
.left{
  position: absolute;
  left: 0;
  top: 0;
  bottom: 0;
  background-color: #fff;
  width: 100px;
}
.center{
  height: 100%;
  margin-left: 100px;
  margin-right: 100px;
  background-color: #F5F7F9;
}
.right{
  position: absolute;
  right: 0;
  top: 0;
  bottom: 0;
  width: 100px;
  background-color: #fff;
}

3. float + margin

section 在 left 和 right 元素后

.body{
  height: 100%;
  position: relative;
}
.header{
  height: 80px;
  background-color: #515A6E;
}
.section{
  position: absolute;
  width: 100%;
  left: 0;
  top: 80px;
  bottom: 0;
  right: 0;
  background-color: #afc7de;
}
.left{
  float: left;
  background-color: #fff;
  width: 100px;
  height: 100%;
}
.center{
  height: 100%;
  margin-right: 100px;
  margin-left: 100px;
  background-color: #F5F7F9;
}
.right{
  float: right;
  height: 100%;
  width: 100px;
  background-color: #fff;
}

三列布局

CSS 三列布局

比较经典有圣杯布局,以及据说是淘宝 UED(玉伯)提出的双飞翼布局。

圣杯布局

<header style="background-color: red;">头部</header>
<main style="background-color: black; position: relative; padding: 0 100px 0 90px;">
  <section style="background-color: green; height: 100px; float: left; width: 100%;">主要内容</section>
  <aside style="background-color: yellow; height: 100px; float: left; width: 90px; margin-left: -100%; position: relative; left: -90px;">左边栏</aside>
  <aside style="background-color: yellow; height: 100px; float: left; width: 100px; margin-left: -100px; position: relative; right: -100px;">右边栏</aside>
</main>
<div style="background-color: blue; clear: left;">尾部</div>

双飞翼布局

传统的双飞翼布局不是这样的, 只是我发现直接在 section 用 padding 也可以达到效果。

<header style="background-color: red;">头部</header>
<main style="background-color: black; position: relative;">
  <section style="background-color: green; height: 100px; float: left; width: 100%; padding: 0 100px 0 90px;">主要内容</section>
  <aside style="background-color: yellow; height: 100px; float: left; width: 90px; margin-left: -100%;">左边栏</aside>
  <aside style="background-color: yellow; height: 100px; float: left; width: 100px; margin-left: -100px;">右边栏</aside>
</main>
<div style="background-color: blue; clear: left;">尾部</div>

flex 布局


三列浮动中间列度自适应 XHTML:

<div id="left-three">左列</div>
<div id="center-three">中间</div>
<div id="right-three">右列</div>

CSS:

/*3列浮动中间列度自适应*/
#left-three{
        background-color: #cccccc;
        border: 2px solid #333333;
        width: 100px;
        height: 300px;
        position: absolute;
        top: 0px;
        left: 0px;
}

#right-three{
        background-color: #cccccc;
        border: 2px solid #333333;
        width: 100px;
        height: 300px;
        position: absolute;
        top: 0px;
        right: 0px;
}

#center-three{
        background-color: #cccccc;
        border: 2px solid #333333;
        height: 300px;
        margin-left: 104px;
        margin-right: 104px;
}

效果图:

高度自适应

对#left 对象设置了 height:100%,同时设置了 html 和 body 的 height:100%, 这是高度自适的关键。 一个对象的高度是否可以使用百分比显示,取决于对象的父级对象。

在默认状态下,浏览器并没有给 body 一个高度属性,所以需要给 body 设置了 100%,然后子级对象的 height:100% 便起作用了。 给 html 对象也进行设置 100%,是使 IE 与 Firefox 浏览器都能够实现高度自适应。 XHTML:

<div id="left-three">左列</div>

CSS:

html,body{
        margin: 0px;
        height: 100%;
}

#left{
        background-color: #cccccc;
        width: 300px;
        height: 100%;
        float: left;
}

效果图:


三列布局 关键:父级元素设置 display:flex

示例:

<style type="text/css">
*{
margin: 0;
padding: 0;
}
.parent{
width: 800px;
height: 300px;
display: flex;
}
.left{
width: 300px;
height: 100%;
background: red;
}
.middle{
width: 200px;
height: 100%;
}
.right{
flex: 1;
height: 100%;
background: blue;
}

</style>
<body>
<div class="parent">
<div class="left">左</div>
<div class="middle">中</div>
<div class="right">右</div>
</div>
</body>

页面效果:

3)float 布局 (float+margin) 兼容性好 但是要注意清楚浮动(clear: both display:block)

  • 两列布局——左侧定宽,右侧自适应 关键: 左侧设置 float:left 右侧:margin-left: leftWidth 示例:
<style>
*{
margin: 0;
padding: 0;
}

.parent{
width:800px;
height:200px;
}
.left{
width:200px;
height:100%;
float:left;
background-color:red;
}
.right{
height:100%;
margin-left:200px;
background-color:blue;
}
</style>
<body>
<div class="parent">
<div class="left">左</div>
<div class="left">右</div>
</div>
</body>

页面效果:

  • 三列布局 关键: 左侧设置 float:left 右侧设置 float:right 中间:margin-left: leftWidth;margin-right:rightWidth 示例:
<style type="text/css">
*{
margin: 0;
padding: 0;
}
.parent{
width: 800px;
height: 200px;
}
.left{
width: 200px;
height: 100%;
background-color: red;
float: left;
}


.right{
float: right;
width: 200px;
background-color: blue;
height: 100%;
}

.middle{
margin-left: 200px;
margin-right: 200px;
}
</style>

<body>
<div class="parent">
<div class="left">左</div>
<div class="right">右</div>
<div class="middle">中</div>

</div>
</body>

页面效果:

注意:float 特点:尽量靠上,尽量靠左(右),所以右侧浮动 div 要先写,中间 div 后写

4)inline-block 布局——不存在清除浮动问题 适用与定宽的布局

<style type="text/css">

.parent{
font-size: 0;
width: 800px;
height: 200px;
}
.left{
font-size: 14px;
width: 300px;
height: 200px;
display: inline-block;
background-color: red;
}
.right{
font-size: 14px;
width: 500px;
height: 200px;
display: inline-block;
background-color: blue;
}
</style>
<div class="parent">
<div class="left">左</div>
<div class="right">右</div>
</div>

页面效果:

注意: 想要父级元素的宽度等于两个子元素宽度之和,需要设置父级元素的 font-size:0 否则两个子元素不会再一行展示 同时,需要设置两个子元素的 font-size: 14px; 否则子元素内的文字不会展示! 想象成文字,注意间隙的处理!!! 间隙存在于两个 div 间的空白:

5)响应式布局 让前台页面可以再不同的设备,不同大小的屏幕上正常展示,一般都是指处理屏幕大小问题 首先设置 viewport 利用 rem 1rem=html.font-size

<meta name="viewport" content="width=device-width,initial-scale=1.0">

利用 media query

@media (max-width: 640px){
.left{
display: none;
}
}

三。Q&A

  1. position: absolute 和 fixed 的区别: 前者是相对于最近的 relative/absolute 元素 后者是相对于屏幕 (viewport) 2) display:inline-block 间隙的原因 原因: 空白字符间距 解决:清除空白字符或者消灭间距

—中间不留空白

<div>
</div></div>
</div>

—将空白字符注释

<div>
</div><!--
--><div></div>

—消灭间距

font-size: 0

  1. 如何清除浮动以及原因

浮动的元素不占用父元素的空间,有可能会超出父元素进而对其他元素产生影响,所以要清除父元素浮动 方法:

让盒子负责自己的布局:

overflow: hidden(auto)

在元素后面加上:

::after{clear: both}
  1. 如何适配移动端页面
- viewport
- rem/viewport/media query
- 设计上: 隐藏 折行 自适应

左中右布局

浮动方式

方法跟左右布局一样,宽度设置小于 50,中间再放一个盒子即可。

flex 方式

如果是三个同样宽度的,子元素设置 flex:1;即可,不同宽度的就设置具体 px

绝对定位方式

左边元素:position: absolute; left: 0; 右边元素:position: absolute; right:0;

中间元素:position: absolute;left: 左边盒子宽度;right: 右边盒子宽度;



2.几种布局方式
1)table布局
当年主流的布局方式,第一种是通过table tr td布局
示例:
<style type="text/css">
table{
width: 800px;
height: 300px;
border-collapse: collapse;
}
.left{
background-color: red;

}
.right{
background-color: blue;
}
</style>
<body>
<table>
<tr>
<td class="left">左</td>
<td class="right">右</td>
</tr>
</table>
</body>


页面效果: 文字自动垂直居中,很方便 同样可以设置左右的width






第二种是类比表格的table class
示例:

<style type="text/css">
.table{
display: table;
width: 800px;
height: 300px;
/*border-collapse: collapse;*/

}
.tb_row{
display: table-row;
}

.tb_cell{
display: table-cell;
vertical-align: middle;
}


.left{
background-color: red;
}
.right{
background-color: blue;
}
table
</style>
<body>
<div class="table">
<div class="tb_row">
<div class="left tb_cell">左</div>
<div class="right tb_cell">右</div>
</div>
</div>
</body>


页面效果: 跟表格布局一样






2)flexbox布局

- 两列布局
**关键:父级元素设置display:flex**

示例:
<style type="text/css">
*{
margin: 0;
padding: 0;
}
.parent{
width: 800px;
height: 300px;
display: flex;
}
.left{
width: 300px;
height: 100%;
background: red;
}
.right{
flex: 1;
height: 100%;
background: blue;
}

</style>

<body>
<div class="parent">
<div class="left">左</div>
<div class="right">右</div>
</div>
</body>


页面效果:






- 三列布局
**关键:父级元素设置display:flex**

示例:
<style type="text/css">
*{
margin: 0;
padding: 0;
}
.parent{
width: 800px;
height: 300px;
display: flex;
}
.left{
width: 300px;
height: 100%;
background: red;
}
.middle{
width: 200px;
height: 100%;
}
.right{
flex: 1;
height: 100%;
background: blue;
}

</style>
<body>
<div class="parent">
<div class="left">左</div>
<div class="middle">中</div>
<div class="right">右</div>
</div>
</body>



页面效果:






3)float布局 (float+margin)
兼容性好 但是要注意清楚浮动(clear: both display:block)

- 两列布局——左侧定宽,右侧自适应
**关键:**
*左侧设置float:left
右侧:margin-left: leftWidth*
示例:
<style>
*{
margin: 0;
padding: 0;
}

.parent{
width:800px;
height:200px;
}
.left{
width:200px;
height:100%;
float:left;
background-color:red;
}
.right{
height:100%;
margin-left:200px;
background-color:blue;
}
</style>
<body>
<div class="parent">
<div class="left">左</div>
<div class="left">右</div>
</div>
</body>



页面效果:







- 三列布局
**关键:**
*左侧设置float:left
右侧设置float:right
中间:margin-left: leftWidth;margin-right:rightWidth*
示例:
<style type="text/css">
*{
margin: 0;
padding: 0;
}
.parent{
width: 800px;
height: 200px;
}
.left{
width: 200px;
height: 100%;
background-color: red;
float: left;
}


.right{
float: right;
width: 200px;
background-color: blue;
height: 100%;
}

.middle{
margin-lef

XXXXXX

<style>
#header{width:100%;height:auto;}
#wrap{width:100%;height:auto;}
#column{float:left;width:60%;}
#column1{float:left;width:30%;}
#column2{float:right;width:30%;}
#column3{float:right;width:40%;}
.clear{clear:both;}
#footer{width:100%;height:auto;}
</style>
<!--以下引用上边的CSS定义-->
<divid="header">顶部行</div>
<divid="warp">
<divid="column">
<divid="column1">第一列</div>
<divid="column2">第二列</div>
<divclass="clear"></div>
</div>
<divid="column3">第三列</div>
<divclass="clear"></div>
</div>
<divid="footer">底部行</div>

CSS 左侧和右侧定宽,中间自适应

<div class="box">
    <div class="left"></div>
    <div class="center-fix">
        <div class="center">Hello, world</div>
    </div>
    <div class="right"></div>
</div>

CSS:

.box { overflow: hidden; }
.left {
    float: left;
    width: 100px;
    height: 100px;
    margin-right: -100px;
    background: #888;
}
.center-fix {
    float: left;
    width: 100%;
}
.center {
    height: 100px;
    margin-left: 100px;
    margin-right: 100px;
    background: #36C;
}
.right {
    float: left;
    width: 100px;
    height: 100px;
    margin-left: -100px;
    background: #888;
}

我们经常会看到这样的页面,左侧(或者右侧)为固定的导航或者菜单栏,另一侧将会随着浏览器的缩放而自适应改变其大小。这种布局结构可用于顶层布局结构亦可用于某个局部功能块,常见于各种 web 系统(OA 系统,ERP 系统)等。

上述的场景即是我们所说的宽度自适应。常见的有两列布局或者三列布局(甚至是多列布局)。

这里我们用三列布局来作示例,即左右两列固定,中间一列宽度自适应。

这个其实很好实现,左侧列左浮动,右侧列右浮动,中间列不浮动即可。代码如下,

<head>
<style>
    body,div {
        margin: 0;
        padding: 0;
    }
    div {
        background-color: #f00;
        height: 200px;
    }
    .left {
        float: left;
        background-color: #00f;
        width: 100px;
    }
    .right {
        float: right;
        background-color: #0f0;
        width: 100px;
    }
    .center {
        background-color: #333;
        margin: 0 100px;
        width: auto;
    }
</style>
</head>
<body>
    <div class="left">left</div>
    <div class="right">right</div>
    <div class="center">center</div>
</body>

CSS 左侧、中侧定宽,右侧自适应

<div class="box">
    <div class="left"></div>
    <div class="center"></div>
    <div class="right-fix"></div>
        <div class="right">Hello, world</div>
    </div>
</div>

CSS 部分:

.box { overflow: hidden; }
.left {
    float: left;
    width: 100px;
    height: 100px;
    background: #888;
}
.center {
    float: left;
    width: 100px;
    height: 100px;
    margin-right: -200px;
    background: #36C;
}
.right-fix {
    float: left;
    width: 100%;
}
.right {
    height: 100px;
    margin-left: 200px;
    background: #F60;
}

5、总结

对于这种有一列自适应,而其他列固定的布局,是有套路的。使用 float+margin 实现的一般方式为:

  • 1)在书写 HTML 的时候,对于需要自适应的那一列,应该包裹一层<div class="fix"></div>层,这样子可以使得修复 IE6 下显示的 BUG
  • 2)对于固定的列,都使用 float: left 来向左居中,而自适应的那一列,本身不写 float: left,fix 层才需要写 float: left
  • 3)计算自适应列距离最左边界的宽度 A,距离最右边界的宽度 B。fix 层设置:width: 100%; float: left; margin-left: -Apx; margin-right: -Bpx
  • 4)fix 层中包裹的列,设置:margin-left: Apx; margin-right: Bpx
  • 5)父容器做清除浮动处理,可以用 overflow: hidden

2,多列定宽,一列自适应 image.png

float + overflow

.left,.center {
    float: left;
    width: 100px;
    margin-right: 20px;
}
.right {
    overflow: hidden;
}

table

.parent{
    width: 100%;
    display: table;
    table-layout: fixed;
}
.left,.center,.right{
    display: table-cell;
}
.right{
    width: 100px;
    padding-right: 20px;
}

flex

.parent{
    display: flex;
}
.left,.center{
    width: 100px;
    padding-right: 20px;
}
.right{
    flex: 1;
}

CSS 双飞翼布局

常用的三列布局之一,左列右列宽度固定,中列宽度自适应。

demo 地址:http://codepen.io/zld13455/pen/wzzwLa

//html部分
<div class="main-container">
    <div class="main">main</div>
</div>
<div class="left">left</div>
<div class="right">right</div>
//css部分
.main-container {
    float: left;
    width: 100%;
    height: 500px;
}
.main {
    height: 500px;
    background-color: aqua;
    margin-left: 200px;
    margin-right: 200px;
}
.left {
    float: left;
    width: 200px;
    height: 500px;
    margin-left: -100%;
    background-color: red;
}
.right {
    float: left;
    width: 200px;
    height: 500px;
    margin-left: -200px;
    background-color: blue;
}

三栏布局实现的是中间自适应宽度,两边固定宽度的布局,中间栏要放在文档流前面,以实现优先渲染。圣杯布局、双飞翼布局都是三栏布局的效果只是实现的方式不一样。

    <div id="container">
        <div id="main" class="col">
            <div id="main-wrap">
                #main
            </div>
        </div>
        <div id="left" class="col">
        #left
        </div>
        <div id="right" class="col">
        #right
        </div>
    </div>

    <style type="text/css">
        body {min-width: 550px;}
        .col {float: left;}

        #main {width: 100%;height: 400px;background-color: #ccc;}

        #main-wrap {margin: 0 190px 0 190px;}

        #left {width: 190px;height: 400px;margin-left: -100%;background-color: #0000FF;}

        #right {width: 190px;height: 400px;margin-left: -190px;background-color: #FF0000;}

    </style>

双飞翼的实现就比较简单了,为 main 添加子元素 main-wrap 并设置 pading。与圣杯布局一样,一开始三个 col 都设置 float: left, 为了把 left 和 right 定位到左右部分,采用负边距,left 部分 margin-left: -100%,right 部分 margin-right: -190px。


双飞翼布局(中间自适应,左右列固定宽度)

html:

    <div class="main">
    <div class="cont"></div>
    </div>
    <div class="left"></div>
    <div class="right"></div>

css:

       .main {
	    float: left;
	    width: 100%;
	    height: 500px;
	}
	.cont {
	    height: 500px;
	    background-color: aqua;
	    margin-left: 300px;
	    margin-right: 300px;
	}
	.left {
	    float: left;
	    width: 300px;
	    height: 500px;
	    margin-left: -100%;
	    background-color: pink;
	}
	.right {
	    float: left;
	    width: 300px;
	    height: 500px;
	    margin-left: -300px;
	    background-color: yellow;
	}
双飞翼布局

div class="container">
    <div class="header">header</div>
    <div class="wrapper clearfix">
         <div class="left col">left</div>
        <div class="main col">
            <div class="main-wrap">main</div>
        </div>
        <div class="right col">right</div>
    </div>
    <div class="footer">footer</div>
</div>

.col {float: left;}
.header {height: 50px;}
.main {width: 100%;}
.main-wrap {margin: 0 100px 0 100px;height: 200px;}
.left {width: 100px; height: 200px; margin-left: -100%;}
.right {width: 100px; height: 200px; margin-left: -100px;}
.footer {height: 50px;}
.clearfix::after {content: ""; display: block; clear: both; visibility: hidden; height: 0; overflow: hidden;}

CSS 圣杯布局

常用的三列布局之一,左列右列宽度固定,中列宽度自适应。

demo 地址:http://codepen.io/zld13455/pen/JRRjoa

//html部分
<div class="container">
    <div class="main">main</div>
    <div class="left">left</div>
    <div class="right">right</div>
</div>
//css部分
.container {
    width:100%;
    height: 300px;
    padding-left: 200px;
    padding-right: 200px;
}
.main {
    float: left;
    width: 100%;
    height: 300px;
    background-color: aqua;
}
.left {
    position: relative;
    left: -200px;
    margin-left: -100%;
    float: left;
    width: 200px;
    height: 300px;
    background-color: red;
}
.right {
    position: relative;
    right: -200px;
    margin-left: -200px;
    float: left;
    width: 200px;
    height: 300px;
    background-color: blue;
}
  1. 圣杯布局
    <div id="container">
        <div id="main" class="col">
        #main
        </div>
        <div id="left" class="col">
        #left
        </div>
        <div id="right" class="col">
        #right
        </div>
    </div>
    <style type="text/css">
        body {min-width: 550px;}
        .col {position: relative;float: left;}

        #container {padding: 0 190px 0 190px;}

        #main {width: 100%;height: 400px;background-color: #ccc;}

        #left {width: 190px;height: 400px;margin-left: -100%;left: -190px;background-color: #0000FF;}

        #right {width: 190px;height: 400px;margin-left: -190px;right: -190px;background-color: #FF0000;}
    </style>

这边 col 设置了浮动,然后将 left,right 定位到左右不负采用负边距,left 部分 margin-left: -100%,right 部分 margin-right: -190px。 设置完成后,定位成功,但是 main 的内容会被遮盖,所以 container 中间设置了 padding 值。给所有 col 设置 position: relative,再分别给左右栏添加 left、right 值,使他们定位到正确位置。

布局练习

不设定 A 容器和 B 容器的宽度,使得 C 容器里面的 A 和 B 元素分栏

使用 absolute

.c {
    width: 500px;
    height: 500px;
    position: relative;
}
.a {
    width: 100%;
    height: 100%;
    background-color: red;
}
.b   {
    position: absolute;
    left:300px;
    top:0px;
    right: 0;
    height: 100%;
    background-color: blue;
}

<div class="container">
    <div class="header">header</div>
    <div class="wrapper clearfix">
        <div class="left col">left</div>
        <div class="main col">main</div>
        <div class="right col">right</div>
    </div>
    <div class="footer">footer</div>
</div>

.container {width: 500px; margin: 50px auto;}
.wrapper {padding: 0 100px 0 100px;}
.col {position: relative; float: left;}
.header,.footer {height: 50px;}
.main {width: 100%;height: 200px;}
.left {width: 100px; height: 200px; margin-left: -100%;left: -100px;}
.right {width: 100px; height: 200px; margin-left: -100px; right: -100px;}
.clearfix::after {content: ""; display: block; clear: both; visibility: hidden; height: 0; overflow: hidden;}

左中右布局

https://zhuanlan.zhihu.com/p/38206945

2.1. 用 ‘float’ 实现左中右布局

其原理与 ‘float’ 左右布局一样,且也可以用自适应。

值得注意的是 ‘middle’ 所在块与 ’left’ 所在块一样,要用 ‘float:left;’

而 ‘right’ 所在块可以用 ‘float:left’ 或 ‘float:right;’ 以及自适应。

2.2. 用 ‘position’ 实现左中右布局

原理与前面类似,值得注意的是,我们要调整一下 html 的布局,保证 ‘right’ 列 div 在 ‘middle’ 列 div 前,不然会出现第三块换行显示的情况,此问题涉及文档流

文档流:文档内元素的流动方向:内联元素从左往右,宽度不够另起一行继续;块级元素,每一块占一行,从上到下依次往下

所以同理,2.1. 中’middle’ 若用自适应,也要调整 html 与上面一样


5.1 两列定宽,一列自适应

效果图:

image.png

(1)使用float+margin

html代码:

<body>
<div id="parent">
    <div id="left">左列定宽</div>
    <div id="center">中间定宽</div>
    <div id="right">右列自适应</div>
</div>
</body>

css代码:

#parent{min-width: 310px;} /*100+10+200,防止宽度不够,子元素换行*/
#left {
    margin-right: 10px;  /*#left和#center间隔*/
    float: left;
    width: 100px;
    height: 500px;
    background-color: #f00;
}
#center{
    float: left;
    width: 200px;
    height: 500px;
    background-color: #eeff2b;
}
#right {
    margin-left: 320px;  /*等于#left和#center的宽度之和加上间隔,多出来的就是#right和#center的间隔*/
    height: 500px;
    background-color: #0f0;
}

原理:两个盒子浮动,另一个盒子计算好两个盒子的宽度、间隔之和设置一个margin值

优缺点

优点:代码简单;容易理解;兼容性好 缺点:margin或padding的值要对应好;父元素宽度不够浮动元素会换行

(2)使用float+overflow▲

html代码:

<body>
<div id="parent">
    <div id="left">左列定宽</div>
    <div id="center">中间定宽</div>
    <div id="right">右列自适应</div>
</div>
</body>

css代码:

#parent{min-width: 320px;} /*100+10+200+20,防止宽度不够,子元素换行*/
#left {
    margin-right: 10px; /*间隔*/
    float: left;
    width: 100px;
    height: 500px;
    background-color: #f00;
}
#center{
    margin-right: 10px; /*在此定义和#right的间隔*/
    float: left;
    width: 200px;
    height: 500px;
    background-color: #eeff2b;
}
#right {
    overflow: hidden;  /*触发bfc*/
    height: 500px;
    background-color: #0f0;
}

原理:两个盒子浮动,另一个盒子触发bfc达到自适应

优缺点:

优点:代码简单,容易理解,无需关注定宽的宽度,利用bfc达到自适应效果 缺点:#right设置margin-left需要大于左边两个盒子宽度、间隔之和才有效。或者直接给#center设置margin-right;父元素宽度不够,浮动元素换行

(3)使用position实现▲

html代码:

<body>
<div id="parent">
    <div id="left">左列定宽</div>
    <div id="center">中间定宽</div>
    <div id="right">右列自适应</div>
</div>
</body>

css代码:

#parent {position: relative;} /*父相*/
#left {
    position: absolute; /*子绝*/
    top: 0;
    left: 0;
    width: 100px;
    height: 500px;
    background-color: #f00;
}
#center {
    position: absolute; /*子绝*/
    left: 100px;        /*对应#left的width值*/
    top: 0;
    width: 200px;
    height: 500px;
    background-color: #eeff2b;
}
#right {
    position: absolute; /*子绝*/
    left: 300px;        /*对应#left和#center的width值之和*/
    top: 0;
    right: 0;
    height: 500px;
    background-color: #0f0;
}

原理:计算好盒子的宽度和间隔去设置位置

优缺点:

优点:容易理解;兼容性比较好;改变相对灵活 缺点:需手动计算宽度、间隔之和确定位置;

(4)使用table实现▲

html代码:

<body>
<div id="parent">
    <div id="left">左列定宽</div>
    <div id="center">中间定宽</div>
    <div id="right">右列自适应</div>
</div>
</body>

css代码:

#parent {
    width: 100%; 
    height: 520px; /*抵消上下间距10*2的高度影响*/
    margin: -10px 0;  /*抵消上下边间距10的位置影响*/
    display: table;
    /*左右两边间距无法消除,子元素改用padding设置盒子间距就没有这个问题*/
    border-spacing: 10px;  /*关键!!!设置间距*/
}
#left {
    display: table-cell;
    width: 100px;
    background-color: #f00;
}
#center {
    display: table-cell;
    width: 200px;
    background-color: #eeff2b;
}
#right {
    display: table-cell;
    background-color: #0f0;
}

原理:CSS Table以表格的形式显示

优缺点:

优点:代码简单;容易理解;适用于宽度高度未知情况;兼容性好(ie8+) 缺点:margin失效;设置间隔比较麻烦;设置tabl-cell的元素,宽度和高度的值设置百分比无效,需要给它的父元素设置display: table; 才生效;table-cell不感知margin,在父元素上设置table-row等属性,也会使其不感知height;设置float或position会对默认布局造成破坏,可以考虑为之增加一个父div定义float等属性;内容溢出时会自动撑开父元素

(5)使用flex实现

html代码:

<body>
<div id="parent">
    <div id="left">左列定宽</div>
    <div id="center">中间定宽</div>
    <div id="right">右列自适应</div>
</div>
</body>

css代码:

#parent {
    height: 500px;
    display: flex;
}
#left {
    margin-right: 10px;  /*间距*/
    width: 100px;
    background-color: #f00;
}
#center {
    margin-right: 10px;  /*间距*/
    width: 200px;
    background-color: #eeff2b;
}
#right {
    flex: 1;  /*均分#parent剩余的部分达到自适应*/
    background-color: #0f0;
}

原理:flex设置排列方式、对齐方式罢了,请查阅文末flex阅读推荐

优缺点

优点:简单灵活;功能强大 缺点:PC端兼容性不好,移动端(Android4.0+) flex务必带上兼容,写法请参考文末阅读推荐,也可以使用autoprefixer

(6)使用Grid实现

html代码:

<body>
<div id="parent">
    <div id="left">左列定宽</div>
    <div id="center">中间定宽</div>
    <div id="right">右列自适应</div>
</div>
</body>

css代码:

#parent {
    height: 500px;
    display: grid;
    grid-template-columns: 100px 200px auto; /*设置3列,固定第一第二列的宽度,第三列auto或者1fr*/
}
#left {
    margin-right: 10px;  /*间距*/
    background-color: #f00;
}
#center {
    margin-right: 10px;  /*间距*/
    background-color: #eeff2b;
}
#right {background-color: #0f0;}

原理:css grid布局,请查看文末的阅读推荐

优缺点

优点:灵活划分网格区域;新型布局利器,适用于页面三维布局 缺点:兼容性不好,移动端(Android5.0+)

5.2 两侧定宽,中间自适应

5.2.1 双飞翼布局方法▲

效果图:

image.png

html代码:

<body>
<div id="header"></div>
<!--中间栏需要放在前面-->
<div id="parent">
    <div id="center">
        <div id="center_inbox">中间自适应</div>
        <hr>  <!--方便观察原理-->
    </div>
    <div id="left">左列定宽</div>
    <div id="right">右列定宽</div>
</div>
<div id="footer"></div>
</body>

css代码:

#header {
    height: 60px;
    background-color: #ccc;
}
#left {
    float: left;
    width: 100px;
    height: 500px;
    margin-left: -100%; /*调整#left的位置,值等于自身宽度*/
    background-color: #f00;
    opacity: 0.5;
}
#center {
    height: 500px;
    float: left;
    width: 100%;
    background-color: #eeff2b;
}
#center_inbox{
    height: 480px;
    border: 1px solid #000;
    margin: 0 220px 0 120px;  /*关键!!!左右边界等于左右盒子的宽度,多出来的为盒子间隔*/
}
#right {
    float: left;
    width: 200px;
    height: 500px;
    margin-left: -200px;  /*使right到指定的位置,值等于自身宽度*/
    background-color: #0f0;
    opacity: 0.5;
}
#footer {
    clear: both;  /*注意清除浮动!!*/
    height: 60px;
    background-color: #ccc;
}

5.2.2 圣杯布局方法

效果图:

image.png

html代码:

<body>
<div id="header"></div>
<div id="parent">
    <!--#center需要放在前面-->
    <div id="center">中间自适应
        <hr>
    </div>
    <div id="left">左列定宽</div>
    <div id="right">右列定宽</div>
</div>
<div id="footer"></div>
</body>

css代码:

#header{
    height: 60px;
    background-color: #ccc;
}
#parent {
    height: 500px;
    padding: 0 215px 0 115px;  /*为了使#center摆正,左右padding分别等于左右盒子的宽,可以结合左右盒子相对定位的left调整间距*/
}
#left {
    margin-left: -100%;  /*使#left上去一行*/
    position: relative;
    left: -115px;  /*相对定位调整#left的位置,正值大于或等于自身宽度*/
    float: left;
    width: 100px;
    height: 500px;
    background-color: #f00;
    opacity: 0.5;
}
#center {
    float: left;
    width: 100%;  /*由于#parent的padding,达到自适应的目的*/
    height: 500px;
    box-sizing: border-box;
    border: 1px solid #000;
    background-color: #eeff2b;
}
#right {
    position: relative;
    left: 215px; /*相对定位调整#right的位置,大于或等于自身宽度*/
    width: 200px;
    height: 500px;
    margin-left: -200px;  /*使#right上去一行*/
    float: left;
    background-color: #0f0;
    opacity: 0.5;
}
#footer{
    height: 60px;
    background-color: #ccc;
}

5.2.3 使用Grid实现

效果图:

image.png

html代码:

<body>
<div id="parent">
    <div id="header"></div>
    <!--#center需要放在前面-->
    <div id="center">中间自适应
        <hr>
    </div>
    <div id="left">左列定宽</div>
    <div id="right">右列定宽</div>
    <div id="footer"></div>
</div>
</body>

css代码:

#parent {
    height: 500px;
    display: grid;
    grid-template-columns: 100px auto 200px; /*设定3列*/
    grid-template-rows: 60px auto 60px; /*设定3行*/
    /*设置网格区域分布*/
    grid-template-areas: 
        "header header header" 
        "leftside main rightside" 
        "footer footer footer";
}
#header {
    grid-area: header; /*指定在哪个网格区域*/
    background-color: #ccc;
}
#left {
    grid-area: leftside;
    background-color: #f00;
    opacity: 0.5;
}
#center {
    grid-area: main; /*指定在哪个网格区域*/
    margin: 0 15px; /*设置间隔*/
    border: 1px solid #000;
    background-color: #eeff2b;
}
#right {
    grid-area: rightside; /*指定在哪个网格区域*/
    background-color: #0f0;
    opacity: 0.5;
}
#footer {
    grid-area: footer; /*指定在哪个网格区域*/
    background-color: #ccc;
}

原理:css grid布局,请查看文末的阅读推荐

优缺点

优点:灵活划分网格区域;新型布局利器,适用于页面三维布局 缺点:兼容性不好,移动端(Android5.0+)

5.2.4 其他方法

效果图:

image.png

(1)使用table实现▲

html代码:

<body>
<div id="parent">
    <div id="left">左列定宽</div>
    <div id="center">中间自适应</div>
    <div id="right">右列定宽</div>
</div>
</body>

css代码:

#parent {
    width: 100%;
    height: 500px;
    display: table;
}
#left {
    display: table-cell;
    width: 100px;
    background-color: #f00;
}
#center {
    display: table-cell;
    background-color: #eeff2b;
}
#right {
    display: table-cell;
    width: 200px;
    background-color: #0f0;
}

原理:CSS Table以表格的形式显示

优缺点:

优点:代码简单;容易理解;适用于宽度高度未知情况;兼容性好(ie8+) 缺点:margin失效;设置间隔比较麻烦;设置tabl-cell的元素,宽度和高度的值设置百分比无效,需要给它的父元素设置display: table; 才生效;table-cell不感知margin,在父元素上设置table-row等属性,也会使其不感知height;设置float或position会对默认布局造成破坏,可以考虑为之增加一个父div定义float等属性;内容溢出时会自动撑开父元素

(2)使用flex实现

html代码:

<body>
<div id="parent">
    <div id="left">左列定宽</div>
    <div id="center">中间自适应</div>
    <div id="right">右列定宽</div>
</div>
</body>

css代码:

#parent {
    height: 500px;
    display: flex;
}
#left {
    width: 100px;
    background-color: #f00;
}
#center {
    flex: 1;  /*均分#parent剩余的部分*/
    background-color: #eeff2b;
}
#right {
    width: 200px;
    background-color: #0f0;
}

原理:flex设置排列方式、对齐方式罢了,请查阅文末flex阅读推荐

优缺点

优点:简单灵活;功能强大 缺点:PC端兼容性不好,移动端(Android4.0+) flex务必带上兼容,写法请参考文末阅读推荐,也可以使用autoprefixer

(3)使用position实现▲

html代码:

<body>
<div id="parent">
    <div id="left">左列定宽</div>
    <div id="center">中间自适应</div>
    <div id="right">右列定宽</div>
</div>
</body>

css代码:

#parent {position: relative;} /*父相*/
#left {
    position: absolute; /*子绝*/
    top: 0;
    left: 0;
    width: 100px;
    height: 500px;
    background-color: #f00;
}
#center {
    height: 500px;
    margin-left: 100px; /*大于等于#left的宽度,或者给#parent添加同样大小的padding-left*/
    margin-right: 200px;  /*大于等于#right的宽度,或者给#parent添加同样大小的padding-right*/
    background-color: #eeff2b;
}
#right {
    position: absolute; /*子绝*/
    top: 0;
    right: 0;
    width: 200px;
    height: 500px;
    background-color: #0f0;
}

原理:计算好盒子的宽度和间隔去设置位置

优缺点:

优点:容易理解;代码相对其他方法较少;兼容性比较好;改变相对灵活 缺点:需手动计算宽度、间隔之和确定边距;

★本章小结:

  • 两列定宽,一列自适应布局,个人推荐方法就是两列浮动,一列触发bfc去达到自适应效果,代码较少,需要注意的就是清除浮动和margin的设置以及父元素空间是否足够;
  • 只要是三列布局,其实都可以用绝对定位去实现,理解起来不难,而且变化灵活,不太好的就是脱离文档流,导致不一定能撑起父元素高度,对于下面排布的盒子会有影响,还有需要手动计算边距的值去排布盒子;
  • 其次可以选用css table布局,代码是最少的,就是bug有点多;
  • 两侧定宽,中间自适应,就必须得说说圣杯布局和双飞翼布局,这两个是比较难理解的,然后圣杯布局有缺陷,如果浏览器无限变窄,圣杯布局将会乱套。绝对定位布局在不等高的时候也会对下面盒子排布产生影响。那么双飞翼布局似乎是最好的选择了。不管怎样,圣杯布局和双飞翼布局都是要好好学习的,这样对盒模型和浮动会有更深的理解;
  • 移动端兼容性允许的情况下能用flex就用flex,务必带上兼容,写法可参考文末阅读推荐,也可以使用Autoprefixer

AXIHE / 精选资源

浏览全部教程

面试题

学习网站

前端培训
自己甄别

前端书籍

关于朱安邦

我叫 朱安邦,阿西河的站长,在杭州。

以前是一名平面设计师,后来开始接接触前端开发,主要研究前端技术中的JS方向。

业余时间我喜欢分享和交流自己的技术,欢迎大家关注我的 Bilibili

关注我: Github / 知乎

于2021年离开前端领域,目前重心放在研究区块链上面了

我叫朱安邦,阿西河的站长

目前在杭州从事区块链周边的开发工作,机械专业,以前从事平面设计工作。

2014年底脱产在老家自学6个月的前端技术,自学期间几乎从未出过家门,最终找到了满意的前端工作。更多>

于2021年离开前端领域,目前从事区块链方面工作了