css布局
css布局是css体系的重中之重
所谓的布局就是确定页面的大概结构,布局就是layout,就是轮廓的意思,就是你的页面分多少块,每一块在什么地方,怎么把它撑起来,就是布局需要做的事。
早期以table为主
最早期的时候,网页都是使用table标签来搞定的,因为table本身就带有格子,本身就能实现各格子中的文本的垂直居中,所以,只要在每个格子里面填入对应的内容,就形成了最终的网页
后来以技巧性布局为主
包括在盒子模型的基础上,使用浮动,定位,进行行内盒和块级盒的转换,像例如浮动,最先是为了产生一种文字环绕图片的效果,后来被使用到了布局,常见的多列布局,都是使用浮动进行的。
现在有flexbox/grid
在css3的时候,终于引入了flex布局和grid布局,flex布局用于一维,而grid用于二维,它们都是css推出的真正用于布局的标准,当然缺点是兼容性不好,对于老版本的IE,无法进行兼容。
响应式布局是必备的知识
响应式布局是随着移动端开发的盛行,而产生别的一种布局,使用响应式布局,通过媒体查询的方式,可以实现一套网页,在移动端和pc端都能得到适配。移动端的布局具体将在下一篇文章中讲。
常用的布局方法
table 表格布局
<!DOCTYPE html><html lang="en"><head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Document</title> <style> .left{ width: 200px; background-color: red; text-align: center; } .right{ width: 200px; background-color: yellow; text-align: center; } tr{ height: 400px; } </style> <style> .table{ margin-top: 20px; display: table; width: 800px; height: 200px; } .table-row{ display: table-row; } .table-cell{ display: table-cell; vertical-align: middle; } </style></head><body> <table> <tr> <td class="left">左边</td> <td class="right">右边</td> </tr> </table> <div class="table"> <div class="table-row"> <div class="left table-cell">左</div> <div class="right table-cell">右</div> </div> </div></body></html>
现在 table 布局已经使用得比较少了,如果要使用得话,一般是通过设置display是table的相关属性进行设置。
盒子模型
盒子模型是css中一个很基础,也很重要的内容,上面的图片是在chrome浏览器中的默认盒子模型,这种盒子模型叫做content-box,css也提供了属性去修改盒子模型。
css提供了一个名叫box-sizing的属性用于修改css的盒子模型,值分别为border-box和content-box2种,两者的区别在于border-box设定width时,width会包含padding和border,而设定为content-box时,设定width,width并不包含padding,height也是同理,具体如下面的代码例子所示
<!DOCTYPE html><html lang="en"><head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Document</title> <style> .box{ box-sizing:border-box; width: 400px; height: 400px; padding: 200px; overflow: hidden; } .box div { width: 200px; height: 200px; padding: 200px; } </style></head><body> <div class="box"> <div >Hello word</div> </div></body></html>
chrome默认的盒子模型就是content-box,而且子标签也不会默认继承父标签的盒子模型。
注意,设置background-color 的时候是会包括 padding 在内的
display
用于确定元素的显示类型
- block 块级元素
- inline 行内元素
- inline-block 行内块级元素,下文会给出注意点
inline-block 布局
是把block 块级元素 横向打成 inline 内联元素的方案,让它们并列起来
像文本一样排block元素,没有清除浮动的问题,但是会有以下的问题需要注意:
- vertical-align 属性会影响到 inline-block 元素,需要把它的值设置为 top 。
- 需要设置每一列的宽度
- 如果HTML源代码中元素之间有空格,那么列与列之间会产生空隙
position
确定元素的位置
- static
- relative
偏移是相对于元素本身的,还会保留原来的文档位置
- absolute
脱离文档流,偏移是相对于最近的position值是非static的父元素,如果都找不到,那么就是相对于body
- fixed
脱离文档流,偏移是相对于屏幕,或者说是可视区域是固定的
- z-index
用于解决层级问题,定位为relative,absolute,fixed的元素可以设置 z-index,z-index值越大,层级越高,就能覆盖其它的元素。
float
- 元素“浮动”
- 脱离文档流
- 但不脱离文本流
对自身的影响:
- 形成”块”(BFC)
- 位置尽量靠上
- 位置尽量靠左(右)
对兄弟的影响
- 上面贴非float元素
- 旁边贴float元素
- 不影响其它块级元素的位置
- 影响其它块级元素的内部文本
对父级元素的影响
- 从布局上”消失”
- 高度塌陷
清除浮动
虽然浮动能实现布局,且在浏览器上有着很好的兼容性,但是元素浮动会导致父元素高度塌陷,兄弟元素内部文本显示异常,兄弟元素内文本排列异常等问题,所以需要清除浮动。
清除浮动的常见方法有以下几种
- 使用伪元素,设置清除浮动
- 新增标签,并在标签中进行清除浮动
- 将父元素设置为BFC
float浮动 + margin
非常经典的布局方式,不管是采用两列的还是三列的,都可以使用这种布局方式
flexbox 布局
css 规范第一次提供用于布局的方式,float最初的目的是为了实现 图文混排,inline-block 的设计初衷 也不是用于布局,但是它的缺点是存在兼容性的问题,在移动端布局中使用的比较广泛,像小程序,react native, uni-app 这些框架默认也是使用 flex 进行布局开发。
- 弹性盒子
- 盒子本来就是并列的
- 指定宽度即可
grid 布局
grid用于二维布局,因为本身内容比较多,所以我接下来会单独写一篇文章用来讲 grid 布局
常见的布局效果
实现居中
实现水平居中
text-align:center;
justify-content:center;
margin : 0 auto ;
position:absolute;left:50%;transform:translate(0%,-50%);
width:600px;position:absolute;left:50%;margin-left:-300px;
实现垂直居中
vertical-align: middle;
position:absolute;top:50%;transform:translate(-50%,0%);
height:600px;position:absolute;top:50%;margin-top:-300px;
margin:auto 0;
align-items:center;
两列布局
左边进行浮动,并给标签定宽高,右边设置成块级元素,加margin-left,这样可以实现左边定宽高,右边自适应的效果。
<!DOCTYPE html><html lang="en"><head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>两列布局</title> <style> *{ margin: 0px; padding: 0px; } .content{ width: 100%; } .left{ float: left; width: 200px; height: 200px; background-color: blue; } .right{ display: block; margin-left: 250px; height: 300px; width: 100%; background-color: bisque; } .left p { text-align: center; } .right p{ text-align: center; } </style></head><body> <div class="content"> <div class="left"> <h4>left</h4> <p>left</p> </div> <div class="right"> <h4>right</h4> <p>right</p> </div> </div></body></html>
也可以把margin 换成 overflow:hidden ,触发 right 块的BFC 属性,同时把 width 进行修改
.right{ display: inline-block; overflow: hidden; height: 300px; width :70% ; background-color: bisque; }
三列布局
左边的元素左浮动,右边的元素右浮动,然后把中间的元素写在最后,给中间的元素一个 margin-left和 margin-right
<!DOCTYPE html><html lang="en"><head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>三列布局</title> <style> *{ margin: 0px; padding: 0px; } .content{ width: 100%; } .left{ float: left; width: 200px; height: 200px; background-color: blue; } .right{ float: right; width: 200px; height: 200px; background-color: burlywood; } .middle{ margin-left: 230px; margin-right: 230px; height: 400px; background-color: chocolate; } p{ text-align: center; } </style></head><body> <div class="content"> <div class="left"><h4>left</h4><p>left</p></div> <div class="right"><h4>right</h4><p>right</p></div> <div class="middle"><h4>middle</h4><p>middle</p> </div> </div> </body></html>
圣杯布局
主要是使用了浮动和margin使用负值的方式实现的三栏布局,给容器设置左右padding,给middle区域(中间的自适应区域)先设置浮动,这样可以让middle区域先显示出来,然后给左右区域设置float,再通过margin负值和relative布局的方式调整布局。
<!DOCTYPE html><html lang="zh"><head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta http-equiv="X-UA-Compatible" content="ie=edge"> <title>圣杯布局</title> <style> * { margin: 0; padding: 0; } p{ text-align: center; } .header, .footer { height: 100px; line-height: 100px; background-color: green; text-align: center; font-size: 30px; font-weight: bolder; } .footer { background-color: goldenrod; } .container { padding: 0 220px 0 200px; overflow: hidden; } .left, .middle, .right { position: relative; float: left; min-height: 130px; word-break: break-all; } .left { margin-left: -100%; left: -200px; width: 200px; background-color: red; } .right { margin-left: -220px; right: -220px; width: 220px; background-color: green; } .middle { width: 100%; background-color: blue; } </style></head><body> <div class="header">header</div> <div class="container"> <div class="middle"> <h4>middle</h4> <p> middle </p> </div> <div class="left"> <h4>left</h4> <p> left </p> </div> <div class="right"> <h4>right</h4> <p> right </p> </div> </div> <div class="footer">footer</div></body></html>
- 首先把left、middle、right都放出来
- 给它们三个设置上float: left, 脱离文档流;
- 一定记得给container设置上overflow: hidden;可以形成BFC撑开文档
- left、right设置上各自的宽度
- middle设置width: 100%;
- 给left、middle、right设置position: relative;
- left设置 left: -leftWidth, right设置 right: -rightWidth;
- container设置padding: 0, rightWidth, 0, leftWidth;
双飞翼布局
也是使用了浮动和margin使用负值的方式实现的三栏布局,给middle区域(中间的自适应区域)先设置浮动,这样可以让middle区域先显示出来,然后给左右区域设置float,再通过margin负值和relative布局的方式调整布局。
<!DOCTYPE html><html lang="zh"><head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta http-equiv="X-UA-Compatible" content="ie=edge"> <title>双飞翼布局</title> <style> p{ text-align:center ; } * { margin: 0; padding: 0; } .header, .footer { height: 100px; line-height: 100px; background-color: green; text-align: center; font-size: 30px; font-weight: bolder; } .footer { background-color: goldenrod; } .container { overflow: hidden; } .left, .middle, .right { float: left; min-height: 130px; word-break: break-all; } .left { margin-left: -100%; width: 200px; background-color: red; } .right { margin-left: -220px; width: 220px; background-color: green; } .middle { width: 100%; height: 100%; background-color: blue; } .inner { margin: 0 220px 0 200px; min-height: 130px; background: blue; word-break: break-all; } </style></head><body> <div class="header">header</div> <div class="container"> <div class="middle"> <div class="inner"> <h4>middle</h4> <p> midfle </p> </div> </div> <div class="left"> <h4>left</h4> <p> left </p> </div> <div class="right"> <h4>right</h4> <p> right </p> </div> </div> <div class="footer">footer</div></body></html>
- 首先把left、middle、right都放出来,middle中增加inner
- 给它们三个设置上float: left, 脱离文档流;
- 一定记得给container设置上overflow: hidden; 可以形成BFC撑开文档
- left、right设置上各自的宽度
- middle设置width: 100%;
- left设置 margin-left: -100%, right设置 right: -rightWidth;
- container设置padding: 0, 0;
双飞翼布局和圣杯布局的异同

圣杯布局和双飞翼布局很像,都是三列布局,左右两栏固定宽度,中间的部分自适应,采用了浮动和margin,并都把middle作为第一个浮动元素。
因为双飞翼布局中,父元素的padding是0,middle的宽度是100%,所以,如果给middle设置背景颜色,会包括left和right的区域,在圣杯布局中,父元素设置了padding,虽然middle元素也是占据了100%,如果给middle设置背景颜色,那么背景颜色不会包括left 和 right 的区域
响应式设计和布局
限于文章的篇幅,这里只做简单的介绍,更多详细可以参看下篇文章
- 在不同的设备上正常使用
- 一般主要处理屏幕大小的问题
- 主要方法
- 隐藏 + 折行 + 自适应空间
- rem/viewport/media query
BFC
当设置成 float 时,元素会变成BFC,BFC会负责接管自己的宽高,解决float的问题,可以给父元素设置成BFC,让父元素去接管自己的宽高。BFC的详细内容篇幅也是比较多,所以,会在接下来单独开一篇文章讲,本文只做总结类描述。
结尾
到这里,本文的内容就告一段落了,本文总结了css中常见的布局,和常见的布局效果,后面的内容请看接下来的文章。
参考文章如下