- 前端布局非常重要的一环就是页面框架的搭建,也是最基础的一环。在页面框架搭建之中,又有居中布局/多列布局/全局布局。本文介绍一下多列布局的一些技巧。
多列布局
定宽 + 自适应
1.使用float + overflow:
- 原理: 通过将左边子元素脱离文档流,设置右边子元素规定当内容溢出元素框时发生的事情以达到多列布局;
- 用法:先将左边子元素设置为float:left;再设置右边子元素为overflow:hidden;
- 示例:
1 2 3 4 | <div class='parent'> <div class='left'>我是内容</div> <div class='right'>我是内容</div> </div> |
1 2 3 4 5 6 7 8 | .left { float: left; width: 100px; margin-right: 20px; } .right { overflow: hidden; } |
- 优点:简单。
- 缺点:不支持IE6。
2.使用float + margin
- 原理:通过将左边子元素脱离文档流,右边子元素向右移动一定的距离,以达到视觉上的多列布局;
- 用法:左边子元素设置为float:left,再设置右边子元素margin-left;
- 示例:
1 2 3 4 | <div class='parent'> <div class='left'>我是内容</div> <div class='right'>我是内容</div> </div> |
1 2 3 4 5 6 7 | .left { float: left; width: 100px; } .right { margin-left: 120px; } |
- 优点:简单;
- 缺点:兼容性存在一定的问题,IE6下有3px的bug;right下的p清除浮动将产生bug;
3.使用float + margin (改良版)
原理:在1的基础上,通过向右边子元素添加一个父元素,再加上设置左边子元素、右边父元素属性使之产生BFC以去除bug。
示例:
1 2 3 4 5 6 7 8 | <div class='parent'> <div class='left'>我是内容</div> <div class='right-fix'> <div class='right'> 我是内容 </div> </div> </div> |
1 2 3 4 5 6 7 8 9 10 11 12 13 | .left { float: left; width: 100px; position: relative; } .right-fix { float: right; width: 100%; margin-left: -100px; } .right { margin-left: 120px; } |
4.使用table
- 原理:通过将父元素设置为表格,将左右子元素转化为类似于同一行的td,从而达到多列布局
用法:先将父元素设置为display:table;width:100%;table-layout:fixed;,再设置左右子元素display:table-cell;最后设置左子元素的width、padding-right;
示例:
1 2 3 4 5 6 7 8 | <div class='parent'> <div class='left'> 我是内容 </div> <div class='right'> 我是内容 </div> </div> |
1 2 3 4 5 6 7 8 9 10 11 12 13 | .parent { display:table; width:100%; table-layout:fixed; } .left { width: 100%; padding-right: 20px; } .right, .left { display:table-cell; } |
5.使用flex
- 原理:通过设置flex属性,从而达到多列布局
用法:先将父元素设置为display:flex;再设置左边子元素flex:1;最后设置左边子元素的width/margin-right;
示例:
1 2 3 4 5 6 7 8 | <div class='parent'> <div class='left'> 我是内容 </div> <div class='right'> 我是内容 </div> </div> |
1 2 3 4 5 6 7 8 9 10 | .parent { display:flex; } .left { width: 100; margin-right: 20px; } .right { flex:1; } |
- 优点:flex很强大;
- 缺点:兼容性和性能方面存在一定问题;
两列定宽 + 一列自适应
- 这种情况和两列定宽差不多,先将左边子元素和中间子元素设置为float:left;width;margin-right;再设置右边子元素overflow:hidden;
1 2 3 4 5 6 7 8 9 10 11 | <div class='parent'> <div class='left'> 我是左侧内容 </div> <div class='center'> 我是中间内容 </div> <div class='right'> 我是右侧内容 </div> </div> |
1 2 3 4 5 6 7 8 9 | .left, .center { float:left; width:100px; margin-right:20px; } .right { overflow:hidden; } |
不定宽 + 自适应
使用float + overflow
- 原理:类似于两列定宽;
用法:将左侧框设置为float:left、margin-right:xx,再设置右侧框overflow:hidden,最后设置左侧框的内容宽度;
示例:
1 2 3 4 5 6 7 8 | <div class='parent'> <div class='left'> 我是内容 </div> <div class='right'> 我是内容 </div> </div> |
1 2 3 4 5 6 7 8 9 10 | .left { float: left; margin-right: 20px; } .right { overflow: hidden; } .left p { width: 200px; } |
- 优点: 简单;
- 缺点: IE6下兼容性存在问题;
使用table
- 原理: 通过将父元素改变为表格,将左右框转换为类似于同一行的td以达到多列布局,设置父元素宽度100%,给左框子元素一个固定宽度从而达到自适应.
- 用法: 将父元素设置为display:table;width:100%;再设置左右侧子元素display:table-cell;最后设置左侧子元素width:0.1%;padding-right:xx;以及左侧子元素中的内容宽度width:xxx;
- 示例:
1 2 3 4 5 6 7 8 9 | <div class='parent'> <div class='left'> <p>我是left内容</p> </div> <div class='right'> <p>我是right内容</p> </div> </div> |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | .parent { display: table; width: 100%; } .left, .right { display: table-cell; } .left { width: 0.1%; padding-right: 20px; } .left p { width: 200px; } |
- 注意: IE6/7不支持;
使用flex
- 原理: 通过设置CSS3中flex属性达到多列布局,加上给左侧子元素的内容定宽,给右侧子元素设置flex达到不定宽+自适应;
- 用法: 父元素设置display:flex;右侧子元素设置flex:1;左侧子元素margin-right:00px;内容设置宽度;
- 示例:
1 2 3 4 5 6 7 8 | <div class='parent'> <div class='left'> <p>我是left内容</p> </div> <div class='right'> <p>我是right内容</p> </div> </div> |
1 2 3 4 5 6 7 8 9 10 11 12 | .parnet { display:flex; } .left { margin-right: 20px; } .right { flex: 1; } .left p { width: 200px; } |
- 优缺点: flex很强大,但是兼容性和性能都存在一些问题;
两列不定宽 + 一列自适应
- 原理: 类似于一列不定宽+一列自适应
- 用法: 左、中设置为float:left;margin-right:xxx;并设置内容宽度,右设置overflow:hidden;
- 示例:
1 2 3 4 5 6 7 8 9 10 11
<div class="parent"> <div class="left"> <p>left</p> </div> <div class="center"> <p>center</p> </div> <div class="right"> <p>right</p> </div> </div>
1 2 3 4 5 6 7 8 9 10 11 12 | .left, .center { float: left; margin-right: 20px; } .right { overflow: hidden; } .left p, .center p { width: 100px; } |
等分布局
- 公式转化:
- 总宽度 = 子元素宽度 n + 间隙宽度 (n - 1)
- 总宽度 = 子元素宽度 n + 间隙宽度 n - 间隙宽度
- 总宽度 + 间隙宽度 =( 子元素宽度 + 间隙宽度 ) * n
- 两个问题: 如何让总宽度增加间隙宽度 如何让每个子元素宽度包含间隙宽度
使用float
- 原理: 增大父元素的实际宽度,使用CSS3属性box-sizing进行辅助布局;
- 用法: 父元素margin-left:-px;子元素float:left;width:25%;padding-left:px;box-sizing:border-box;
- 示例:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42
<div class="parent"> <div class="column"><p>1</p></div> <div class="column"><p>2</p></div> <div class="column"><p>3</p></div> <div class="column"><p>4</p></div> </div> ``` ```css .parent { margin-left: -20px; } .column { float:left; width: 25%; padding-left: 20px; box-sizing: border-box; } ``` - 注意: IE6/7兼容性存在一些问题; #### 使用table - 原理: 通过增加一个父元素的修正框,增加其宽度,并将父元素转换为table,将子元素转换为table-cell进行布局; - 用法: 父元素修正框设置为margin-left:-**px;父元素display:table;width:100%;table-layout:fixed;子元素display:table-cell;padding-left:**px; - 示例; ```html <div class="parent-fix"> <div class="parent"> <div class="column"> <p>111</p> </div> <div class="column"> <p>222</p> </div> <div class="column"> <p>333</p> </div> <div class="column"> <p>444</p> </div> </div> </div>
1 2 3 4 5 6 7 8 9 10 11 12 | .parent-fix { margin-left: -20px; } .parent { display: table; width: 100%; table-layout: fixed; } .column { display: table-cell; padding-left: 20px; } |
- 优点: 结构和块数无关联;
- 缺点: 嵌套层数增加;
使用flex
- 原理: 通过设置CSS3中的flex属性达到等分布局;
- 用法: 父元素display:flex;子元素flex:1;并设置间距;
- 示例:
1 2 3 4 5 6 7 8 9 10 11 12 13 14
<div class="parent"> <div class="column"> <p>111</p> </div> <div class="column"> <p>222</p> </div> <div class="column"> <p>333</p> </div> <div class="column"> <p>444</p> </div> </div>
1 2 3 4 5 6 7 8 9 | .parent { display: flex; } .column { flex: 1; } .column+.column { margin-left: 20px; } |
- 优点: 代码量少,与块数无关;
- 缺点: 低版本浏览器兼容性存在问题;
定宽 + 自适应 + 两块高度相同
使用float
- 原理: 通过过分加大左右子框的高度,辅助超出隐藏,以达到视觉上的等高。
- 用法: 父元素overflow: hidden,左右子元素padding-bottom: 9999px、margin-bottom: -9999px,左子元素float: left、width、margin-right,右子元素overflow: hidden;
- 示例:
1 2 3 4
<div class="parent"> <div class="left">left</div> <div class="right">right</div> </div>
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | p{ background: none ; } .left,.right{ background: #444; } .parent{ overflow: hidden; } .left,.right{ padding-bottom: 9999px; margin-bottom: -9999px; } .left{ float: left; width: 100px; margin-right: 20px; } .right{ overflow: hidden; } |
- 优点: 兼容性好;
- 缺点: 伪等高,不是真正意义上的等高;
使用table
- 原理:将父框转化为tabel,将子框转化为tabel-cell布局,以达到定宽+自适应+两块高度一样高。
- 用法:父元素display:table、width:100%、table-layout:fixed,左右子元素display:table-cell,左子元素width、padding-right。
- 示例:
1 2 3 4
<div class="parent"> <div class="left">left</div> <div class="right">.right</div> </div>
1 2 3 4 5 6 7 8 9 10 11 12 13 | .parent { display: table; width: 100%; table-layout: fixed; } .left { width: 100px; padding-right: 20px; } .right, .left { display: table-cell; } |
使用flex
- 原理: 通过设置CSS3布局利器flex中的flex属性以达到定宽+自适应+两块高度一样高。
- 用法:父元素display: flex,左子元素width、margin-right;右子元素flex:1。
- 示例:
1 2 3 4
<div class="parent"> <div class="left">left</div> <div class="right">right</div> </div>
1 2 3 4 5 6 7 8 9 10 | .parent { display: flex; } .left { width: 100px; margin-right: 20px; } .right { flex: 1; } |
- 优缺点: 代码量少,简洁,但是兼容性存在一些问题;
使用display
- 原理: 通过设置display中的CSS3的-webkit-box属性以达到定宽+自适应+两块高度一样高。
- 用法: 父元素display: -webkit-box、width:100%,左子元素width、margin-right,右子元素-webkit-box-flex: 1;
- 示例:
1 2 3 4
<div class="parent"> <div class="left">left</div> <div class="right">right</div> </div>
1 2 3 4 5 6 7 8 9 10 11 | .parent { width: 100%; display: -webkit-box; } .left { width: 100px; margin-right: 20px; } .right { -webkit-box-flex: 1; } |
- 缺点: 兼容性存在较大问题;
全屏布局
全屏布局的特点:
- 滚动条不是全局滚动条,而是出现在内容区域里,一般是主内容区域;
- 浏览器变大时,撑满窗口;
全屏布局的方法
使用position
- 原理: 将上下部分固定,中间部分使用定宽+自适应+等高;
- 用法: 见示例;
- 示例:
1 2 3 4 5 6 7 8
<div class="parent"> <div class="top">top</div> <div class="left">left</div> <div class="right"> <div class="inner">right-inner</div> </div> <div class="bottom">bottom</div> </div>
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 | html, body, .parent { margin: 0; padding: 0; overflow: hidden; } body { color: white; } .top { position: absolute; top: 0; left: 0; right: 0; bottom: 0; background-color: blue; } .left { position: absolute; left: 0; top: 100px; bottom: 50px; width: 200px; background-color: red; } .right { position: absolute; left: 200px; top: 100px; bottom: 50px; right: 0; background-color: pink; overflow: auto; } .right .inner { min-height: 1000px; } .bottom { position: absolute; left: 0; right: 0; bottom: 0; height: 50px; background-color: black; } |
- 优缺点: 兼容性好,IE6以下不支持;
使用flex
- 原理: 通过CSS3中flex属性和flex-direction属性;
- 用法: 见示例;
- 示例:
1 2 3 4 5 6 7 8 9 10
<div class="parent"> <div class="top">top</div> <div class="middle"> <div class="left">left</div> <div class="right"> <div class="inner">right</div> </div> </div> <div class="bottom">bottom</div> </div>
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 | html, body, .parent { margin: 0; padding: 0; overflow: hidden; } body { color: white; } .parent { display: flex; flex-direction: column; } .top { height: 100px; background-color: blue; } .bottom { height: 50px; background-color: black; } .middle { flex: 1; display: flex; } .left { width: 200px; background-color: red; } .right { flex: 1; overflow: auto; background-color: pink; } .right .inner { min-height: 1000px; } |
- 优缺点: 兼容性差,IE9及以下不兼容;