一、左右负边距对元素宽度的影响
先来看这样一个例子。
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title>负边距相当于增加元素宽度</title> <style type="text/css"> body,ul,li { padding:0; margin:0; } ul,li { list-style:none; } .container { height:210px; width:480px; border:5px solid #000; } ul { height:210px; overflow:hidden; } li { color:white; height:100px; width:100px; background-color:blue; float:left; margin-right:20px; margin-bottom:10px; } </style> </head> <body> <div class="container"> <ul> <li>子元素1</li> <li>子元素2</li> <li>子元素3</li> <li>子元素4</li> <li>子元素5</li> <li>子元素6</li> <li>子元素7</li> <li>子元素8</li> </ul> </div> </body> </html>
讲这个例子之前,还要先了解一下浮动原理。
浮动原理:(以左浮动为例)所有子元素向左浮动。浮动框向左移动,直到它的外边缘碰到包含框或另一个浮动框的边框为止。所以子元素2向左浮动直到碰到子元素1的外边距为止。其他类推,当包含框无法容纳水平排列的浮动元素时,其他浮动元素向下移动。
例子中,container宽度为480。ul元素没有设置宽度,所以它的宽度是自动的,由它里面的文档流的宽度决定(高度与此类似)。各子元素宽度为100,右外边距为20。
所以父元素ul宽度=子元素1~4宽度之和 + 子元素1~4右外边距之和。
本例中ul宽度为480,刚好等于其父元素container之后,所以子元素5自动换行然后靠左浮动。
如果把container宽度改为460,这样由于水平宽度不够,子元素4就会向下移动。想让子元素1~4仍然水平排列,可以把最右边子元素的右边距设为0。单如果这些子元素是在模板中通过循环动态输出,在循环的时候还要判断哪些子元素是靠近右边界的,这样比较麻烦。此时负边距就发挥作用了。
本例中,把子元素的父元素ul的margin-right设置为-20。这样刚好可以抵消元素4的右边距20。于是container正好可以容纳下元素1~4。
可以看出,负边距的一个应用就是缩小边距。在实际应用中,可以给父元素设置负边距,用来抵消子元素在相同方向上的边距(前提是父边距没有设置宽度或为auto)。使得整个块正好可以容纳在固定宽度的上一级块级元素中。
改动1:container宽度为460,把子元素li右边距改为30。ul右边距为-30。
此时ul宽度为100*4+30*4-30> 460。所以子元素4要向下移动。
改动2:container宽度为460,把子元素li右边距改为30。ul右边距为-60。
此时ul宽度为100*4+30*4-60 = 460。
此时子元素4不用向下移动。只是子元素1到4之间的宽度超过container宽度,所以子元素4有部分在container之外。
二、负边距对浮动元素的影响
三、负边距对绝对定位元素的影响
绝对定位元素的top、right、bottom、left等值是元素自身的边界到最近的已定位祖先元素的距离。这个自身的边界指的是margin定义的边界。所以,如果margin为正时,元素边界是向外扩张的;如果margin为负,则它的边界是向内收缩的。利用这点,可以通过绝对定位方法来实现居中。
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title>利用负边距和绝对定位实现居中</title> <style type="text/css"> body { padding:0; margin:0; } div { width:150px; height:150px; background:#f00; position:absolute; left:50%; top:50%; } </style> </head> <body> <div>块元素绝对定位,left和top值为50%。顶点A距离top和left边距均为50%。若要块元素居中,应该是中心点B距离top和left边距为50。</div> </body> </html>
如果不设置负边距,则是块元素的定点A在居中的位置。若要块元素居中,应该是它的中心点B在居中位置。所以要把块元素向上移动自身高度的一半,同时向左移动自身宽度的一半。代码如下:
<style type="text/css"> body { padding:0; margin:0; } div { width:150px; height:150px; background:#f00; position:absolute; left:50%; top:50%; margin-left:-50px; margin-top:-50px; } </style>
参考文献:本文参考了该文: