参考链接: 常见5大布局
- 单列布局
- 两列自适应布局
- 圣飞布局和双飞翼布局
- 伪等高布局
- 粘连布局
一、单列布局
常见的单列布局有两种:
header,content和footer等宽的单列布局。
header和footer等宽,content略窄的单列布局。
实现:
- 等宽的单列布局
2.不等宽的单列布局
<div class="header"> <div class="nav"></div> </div> <div class="content"></div> <div class="footer"></div>
.header{ margin:0 auto; max-width: 960px; height:100px; background-color: chocolate; } .nav{ margin: 0 auto; max-width: 800px; background-color: coral; height: 50px; } .content{ margin: 0 auto; max-width: 800px; height: 400px; background-color: cyan; } .footer{ margin: 0 auto; max-width: 960px; height: 100px; background-color:darkorange; }
二、两列自适应布局
指一列由内容撑开,另一列撑满剩余宽度的布局方式
首先看不是自适应的布局:只需要一个浮动,一个设置margin即可
<!-- 普通布局只需要浮动加普通元素的margin就可以实现 --> <div class="left"></div> <div class="right"> </div>
.left{ float:left; width: 100px; height: 1000px; background-color: darkorchid; } .right{ margin-left:100px; height: 1000px; background-color: darkred; }
1、float+overflow:hidden
BFC
<!-- 两栏的自适应布局 float+overflow:hidden--> <!-- 通过overflow触发BFC,而BFC不会重叠浮动元素 --> <div class="parent"> <div class="left"> <p>left</p> </div> <div class="right"> <p>right</p> <p>right</p> </div> </div> .parent{ overflow:hidden; background-color: darksalmon; width: 100px; height: 100px; } .left{ float:left; background-color: darkslateblue; } .right{ background-color: darkturquoise; overflow:hidden; }
当删去left中的内容:
三、三栏布局
特征:中间列自适应宽度,旁边两侧固定宽度。
注意:content要在最后面,不然浮动的元素会在其下面
1、浮动方法
<body> <div class="right">right</div> <div class="left">left</div> <div class="content">content</div> </body> <style> .right{ float:right; width: 100px; height: 100px; background-color: aqua; } .left{ float:left; width: 100px; height: 100px; background-color: antiquewhite; } .content{ margin-left: 100px; margin-right: 100px; background-color: black; }
2、定位方法
<body> <div class="left">left</div> <div class="content">content</div> <div class="right">right</div> </body> <style> .right{ position:absolute; right:0; width: 100px; height: 100px; background-color: aqua; } .left{ position:absolute; left:0; width: 100px; height: 100px; background-color: antiquewhite; } .content{ position:absolute; left:100px; right: 100px; background-color: black; }
效果一致,但这种方法使用的有效性较差,因为整个容器都脱离了文档流。
3.flexbox布局
有关flex详情请看: css之flex属性(弹性布局)
<body> <div class="main"> <div class="left">left</div> <div class="content">content</div> <div class="right">right</div> </div> </body> <style> .main{ display: flex; } .right{ width: 100px; height: 100px; background-color: aqua; } .left{ width: 100px; height: 100px; background-color: antiquewhite; } .content{ flex:1; background-color: blue; }
flex布局的缺点是从ie10开始支持
4.表格布局
table是一种常见的布局方式,他可以将整个页面按照表格的方式设置为多行多列,但是书写table标签比较麻烦,所以可以用display:table的方法。子元素为display:table-cell
<body> <div class="main"> <div class="left">left</div> <div class="content">content</div> <div class="right">right</div> </div> </body> <style> .main{ display:table; width: 100%; } .main div{ display: table-cell; } .right{ width: 100px; height: 100px; background-color: aqua; } .left{ width: 100px; height: 100px; background-color: antiquewhite; } .content{ background-color: blue; }
优点:兼容性好,内容溢出时会自动撑开父元素
缺点:
- 无法设置栏边距
- 对seo不友好
- 当其中一个单元高度超过的时候,两侧的单元格也是会一起变高的
5.网格布局
网格布局将网页划分为一个个网格,可以任意组合不同的网格,做出各种各样的布局
将属性display值设为grid或inline-grid就创建了一个网格容器。
gird提供了 gird-template-columns、grid-template-rows属性让我们设置行和列的高、宽
<body> <div class="main"> <div class="left">left</div> <div class="content">content</div> <div class="right">right</div> </div> </body> <style> .main { display: grid; width: 100%; grid-template-columns: 100px auto 100px; grid-template-rows: 150px; } .right { background-color: aqua; } .left { background-color: antiquewhite; } .content { background-color: blue; } </style>
兼容性不好。
与表格不同的地方:网格布局没有内容结构
3、特殊的三栏结构:圣杯布局
参考链接:https://www.jianshu.com/p/81ef7e7094e8
同样也是两边固定宽度,中间自适应,唯一区别是 dom 结构必须是先写中间列部分,这样实现中间列可以优先加载。
要点:
两侧宽度固定,中间宽度自适应
中间部分在DOM结构上优先,以便先行渲染
允许三列中的任意一列成为最高列
只需要使用一个额外的
实现步骤:
1、三个部分都设定为左浮动,否则左右两边内容上不去,就不可能与中间列同一行。然后设置 center 的宽度为 100%(实现中间列内容自适应),此时,left 和 right 部分会跳到下一行
2、通过设置 margin-left 为负值让 left 和 right 部分回到与 center 部分同一行
3、通过设置父容器的 padding-left 和 padding-right,让左右两边留出间隙。
4、通过设置相对定位,让 left 和 right 部分移动到两边
Q:为什么设置margin—left为自身宽度可以回到第一行?
A:因为一开始元素在第二行的原因是第一行的宽度被center完全占满。但当left元素设置margin-left为负的自身宽度,此时这个元素的宽度为0,第一行可以容纳宽度为0的元素,所以回到了第一行。
<!-- 两侧宽度固定,中间宽度自适应 中间部分在DOM结构上优先,以便先行渲染 允许三列中的任意一列成为最高列 只需要使用一个额外的<div>标签 --> <body> <!-- 首先定义出整个布局的dom结构 --> <div id="header"></div> <div id="container"> <!-- center要定义在最前面 --> <div id="center" class="column"></div> <div id="left" class="column"></div> <div id="right" class="column"></div> </div> <div id="footer"></div> </body> <style> #container{ padding-left:100px; padding-right:100px; } #container .column{ float:left; } #left { background-color: chartreuse; width: 100px; height: 100px; /* 使其回到第一行 */ margin-left:-100%; /* 定位元素让他到预留的位置 */ position:relative; right:100px; } #right { margin-right:-100%; background-color: coral; width: 100px; height: 100px; } #center { height: 100px; width: 100%; background-color: cyan; } #footer{ clear:both; } </style>
双飞翼布局
<body> <body> <div id="header"></div> <div id="container" class="column"> <div id="center"></div> </div> <div id="left" class="column"></div> <div id="right" class="column"></div> <div id="footer"></div> <body> </body> <style> body{ max-width:500px; } #container { width: 100%; } .column { float: left; } #center { margin-left: 200px; margin-right: 150px; height: 100px; background-color: darkorange; } #left { width: 200px; height: 100px; background-color: darkgreen; margin-left:-100%; } #right { width: 150px; height: 100px; background-color: darkmagenta; margin-left:-150px; } #footer { clear: both; }
② 实现步骤(前两步与圣杯布局一样)
三个部分都设定为左浮动,然后设置 center 的宽度为 100%,此时,left 和 right 部分会跳到下一行;
通过设置 margin-left 为负值让 left 和 right 部分回到与 center 部分同一行;
center 部分增加一个内层 div,并设 margin: 0 200px;
③ 缺点
多加一层 dom 树节点,增加渲染树生成的计算量。
④ 圣杯布局和双飞翼布局实现方式对比:
两种布局方式都是把主列放在文档流最前面,使主列优先加载。
两种布局方式在实现上也有相同之处,都是让三列浮动,然后通过负外边距形成三列布局。
两种布局方式的不同之处在于如何处理中间主列的位置: 圣杯布局是利用父容器的左、右内边距+两个从列相对定位; 双飞翼布局是把主列嵌套在一个新的父级块中利用主列的左、右外边距进行布局调整
粘连布局
<body> <div class="wrap"> <div class="main"> main<br /> main<br /> </div> </div> <div class="footer"></div> </body> <style> html,body{ height: 100%; margin:0; } .wrap{ width: 100%; min-height: 100%; } /* 让出一部分区域,防止内容被遮盖 */ .main{ padding-bottom:30px; } .footer{ width: 100%; height: 30px; background-color: darkorchid; /*main已经为100%,此时设置负值使其上移*/ margin-top:-30px; } </style>
---------补充margin为负值时--------
参考链接:https://blog.csdn.net/weixin_38912024/article/details/88837111
①元素本身没有宽度,会增加元素宽度
<body> <div class="parent"> <div class="child"> 设置margin-left为负值 </div> </div> </body> <style> .parent{ width: 100px; height: 100px; background-color: cyan; margin-left:20px; } .child{ background-color: darkgreen; margin-left:-20px; } </style>
②元素本身有宽度,会产生位移
<body> <div class="parent"> <div class="child"> 设置margin-left为负值 </div> </div> </body> <style> .parent{ width: 100px; height: 100px; background-color: cyan; margin-left:20px; } .child{ width: 50px; background-color: darkgreen; margin-left:-20px; } </style>
margin-top为负值,不管是否设置高度,都不会增加高度,而是会产生向上的位移
margin-bottom为负值的时候不会位移,而是会减少自身供css读取的高度.
对文档流的影响
元素如果使用了margin-left为负,则自身会向左偏移。且在其后面的元素会补位,后面的行内元素会津贴在此元素的后面。即如果不脱离文档流不使用float的话,负margin元素是不会破坏页面的文档流。
如果使用负margin上移一个元素,所有跟随的元素都会被上移
对绝对定位影响
对于绝对定位元素,负margin会基于其绝对定位目标再偏移