任务12-负边距、三栏布局
1. 负边距在让元素偏移时和position: relative
有什么区别?
通过负边距进行偏移的元素,它会放弃原来占据的空间,这样,它后面文档流中的其它元素就会“流过来填充这部分空间。
在文档流中,元素的最终边界是有 margin 决定的。margin 为负的时候相当于元素的边界向里收,文档流认的是这个边界,不会管你实际尺寸是多少。
而 psoition: relative;
只是“外观”变了,原来的位置依然“霸占”着,它仍然会坚守着原来占据的空间,不会让文档流其他元素趁虚而入。“页面布局”跟原来一样。偏移后不对周围的元素产生影响。
拓展阅读:
2. 使用负 margin 形成三栏布局有什么条件?
- 这“三栏”都要设置浮动
- 中间那一栏在最前面(这一栏的宽度会与父容器的 content 一样)
- 左右两栏利用负margin"移动"到上面。
- 接着就按情况调整,父容器设置 padding、左右两栏设置偏移(relative)等等 或者 在中间那一栏加个 div 在设置两边 margin
另外,负边距对元素宽度的影响
负边距不仅能影响元素在文档流的位置,还可以增加元素的宽度!!!
这个作用的前提是,该元素没有设定 width。
补充:三栏布局
1) 用浮动实现三栏布局
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>浮动实现三栏布局</title>
<style media="screen">
body {
margin: 0;
padding: 0;
}
#left {
float: left;
width: 200px;
height: 200px;
background-color: red;
}
#right {
float: right;
width: 180px;
height: 200px;
background-color: blue;
}
#center {
height: 500px;
margin-left: 210px;
margin-right: 190px;
background-color: pink;
}
</style>
</head>
<body>
<div id="left">left</div>
<div id="right">right</div>
<div id="center">center</div>
</body>
</html>
效果图:
浮动实现三栏布局.png这种方法的缺点是:#center 必须放在 #left 和 #right (浮动两栏) 的后面。
这里三个div标签的顺序的关键是要把主体div放在最后,左右两栏div顺序任意。
此方法的优点是:代码足够简洁与高效
不足在于:中间主体存在克星,clear:both属性。如果要使用此方法,需避免明显的clear样式。
2) 利用绝对定位实现三栏布局
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>绝对定位实现三栏布局</title>
<style media="screen">
html, body {
margin: 0;
padding: 0;
height: 100%;
}
#left, #right {
position: absolute;
top: 0;
width: 200px;
height: 100%;
}
#left {
left: 0;
background-color: red;
}
#right {
right: 0;
background-color: blue;
}
#center {
margin: 0 210px;
background-color: pink;
height: 100%;
}
</style>
</head>
<body>
<div id="left"></div>
<div id="center"></div>
<div id="right"></div>
</body>
</html>
效果图:
这里的左中右三个div的顺序是可以任意调整的。
此方法的优点是,理解容易,上手简单,受内部元素影响而破坏布局的概率低,就是比较经得起折腾。缺点在于:如果中间栏含有最小宽度限制,或是含有宽度的内部元素,当浏览器宽度小到一定程度,会发生层重叠的情况。然而,一般情况下,除非用户显示器分辨率宽度>=1600像素,否则用户不会把浏览器缩小到1000像素以下的,所以该缺陷危害指数3。
3) 圣杯布局、双飞翼布局
略(下面有)
拓展阅读:
3. 圣杯布局的原理是什么?简述实现圣杯布局的步骤
<div id="content">
<div class="main"></div>
<div class="aside"></div>
<div class="extra"></div>
</div>
原理:
在三列中添加了一个父级容器, 容器设置左右padding,分别等于左右两列的宽度。三列都设置为左浮动,使用负边距和定位将左右两列放置于左右两侧。中间这列设置宽度100%,达到自适应宽度。
- “三栏”都要被一个父元素包着。中间那一栏放在最前面(自适应宽度)
- “三栏”都要设置浮动
- “左右两栏”利用“负margin”来移动到上面去。(.aside {margin-left: -100%;}移动到左上角,.extra {margin-left: -自身宽度;}移动到右上角。)
- 父元素 .content 设置 padding (.main 的宽度跟 .content 的 content 相同)来“留空”
拓展阅读:
4. 双飞翼布局的原理?实现步骤?
双飞翼布局原理跟圣杯布局差不多。
双飞翼布局两边留白是靠 .main 里面增加一个 .wrap (设置margin-left、margin-right),由此,.aside 和 .extra 就不用在设置定位偏移了。而圣杯布局两边留白是靠 .main 的父元素 设置 padding,两边还需要设置偏移。
简单说起来就是”双飞翼布局比圣杯布局多创建了一个div,但不用相对布局了“。
总结:
圣杯布局与双飞翼布局的比较
- 两种布局方式都是把主列放在文档流最前面,使主列优先加载。
- 两种布局方式在实现上也有相同之处,都是让三列浮动,然后通过负外边距形成三列布局。
- 两种布局方式的不同之处在于如何处理中间主列的位置:圣杯布局是利用父容器的左、右内边距定位;双飞翼布局是把主列嵌套在div后利用主列的左、右外边距定位。
两者相比较,双飞翼布局虽然多了一个div,却减少了相对定位属性的代码,个人认为双飞翼布局在实现思路和代码简洁度上都要比圣杯布局更好一些。
拓展阅读:
补充:
关于 margin
margin 参考线
margin 属性中有 2 类参考线,top 和 left 的参考线属于一类,right 和 bottom 的参考线属于另一类。
top 以 containing block 的 content 上边或者垂直上方相连元素 margin 的下边为参考线垂直向下位移;left 以 containing block 的 content 左边或者水平左方相连元素 margin 的右边为参考线水平向右位移。
right 以元素本身的 border 右边为参考线水平向右位移;bottom 以元素本身的border 下边为参考线垂直向下位移。什么叫以元素本身为参考呢,确切含义是指以自身为参考来影响周围元素的位置(实质即为影响下边和右边相邻元素的参考线)
从上我们可以看到 top 和 left 都是以外元素为参考,而 right 和 bottom 以本元素为参考。
上面的位移方向是指 margin 数值为正值时候的情形,如果是负值则位移方向相反。
示意图:
margin参考线.gif
demo: margin-bottom为负值时
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>我知道你不知道的负Margin - margin参考线举例说明</title>
<style media="screen">
* {
margin: 0;
padding: 0;
}
.wrap {
width: 400px;
}
.example {
width: 200px;
height: 200px;
background-color: #ccccff;
/*margin: -10px 20px -30px 40px;*/
margin-bottom: -30px;
}
.normal {
width: 200px;
height: 200px;
background-color: #cce8cf;
opacity: 0.5;
/*
normal 仅作为 example 前后(有无 margin)效果的参照
*/
}
</style>
</head>
<body>
<div class="wrap">
<div class="example">example元素:margin参考线举例说明文字,
请查看此元素由于margin的变化所移动的位移量</div>
<div class="normal">一个普通的Box</div>
</div>
</body>
</html>
margin-bottom负.png
可以看出,当 .example 设置 margin-bottom: -30px; 时,对于自身并没有影响,影响的是下面的 .normal。使 .normal 上移 30px。
因为 .normal 的上边界元素是 .example 。.normal 会根据 .example 的边界来判定自身的位置。
想象下,如果 .example 的 margin-bottom: 30px;,那么 .example 将隔开下方的 .normal ,反之 margin-bottom: -30px;,下方的 .normal 因为 .margin 参考线内凹,导致 .naomal 不得不上移。
什么叫以元素本身为参考呢,确切含义是指以自身为参考来影响周围元素的位置(实质即为影响下边和右边相邻元素的参考线)
另外,margin-bottom: -30px; 并不会改变 .example border内的物理大小,但会改变 box 的逻辑大小,即:以此 box 的 margin 的下边为参考线,不是从 box 的物理位置开始,而是从逻辑位置开始。(现象:.normal 盖住了 .example 的一部分)
总结:
当 margin 4 个值都为正数时,margin 按照正常规律与周围元素产生边距。
当元素 margin 的 top 和 left 为负值时,会令元素上移和左移。
当元素 margin 的 bottom 和 right 为负值时,会影响到下边和右边相邻元素的参考线。
box 最后的显示大小等于 box 的 border 及 border 内的大小加上正的 margin 值。而负的 margin 值不会影响 box 的实际大小,如果是负的 top 或 left 值会引起 box 的向上或向左位置移动,如果是 bottom 或 right 只会影响下面 box 的显示的参考线。