Home > Article > Web Front-end > 前端尝试以新角度深入理解CSS盒模型(2)_html/css_WEB-ITnose
接上篇。
矩形区域中各个属性的取值只有margin可以取负值,只有width和margin可以取auto关键字,border不能为百分数,其他属性都只能取正的数字或者正的百分数。其中margin和padding设置的值是一个块区域的垂直高度,这块区域的长和宽是随着内容的width和height变化而变化的。border设置的是自身的宽度,其长度也是随着相应边的长度变化而变化的。padding和border的取值是不会根据某些条件自动改变的,一旦设置就不会发生改变。margin的取值虽然可以自动变化,但产生变化的条件一般都是空间受限。取值可以根据内容变化而变化的只有width和height属性,前提是width、height取值为auto。下面根据块级和行内分开讨论,并在各种情况下再根据水平方向和垂直方向分开讨论。
1.块级矩形区域中:
在水平方向上,如果width没有设置固定值即值为auto的时候,width属性有尽可能宽的倾向,比如若width和margin同时设置为auto,那么margin的值会被浏览器重置为0。如果为width设定了固定值,那么它的值就是固定的了,不论是否脱离文档流是否超出了父元素的内容区。
1.当width设置为auto的时候,这种情况下width有一条原则:若该内容区在布局上下文中(父元素的内容区)则它的width会尽可能的大。若该内容区因为正的margin的原因全部超过了布局上下文,或者padding、border大于了布局上下文的宽,那么它的width取值是为0的,虽然width为0,但内容还是存在的并且padding和border属性值也都是不会改变的。但还存在一种情况,就是当padding和margin同时存在的时候,正数的margin-right不能使元素的矩形区域离开父元素的内容区,其数值再大也无效。而正数的margin-left可以是元素的矩形区域离开父元素的内容区。另外一条特殊性原则就是当margin为负的情况了,负数产生的效果就是把内容区穿过布局上下文并往布局上下文外侧移动相应的距离。当一侧margin为负数的时候,并还存在三种可能情况:另一侧margin没有数值、另一侧margin有正值、另一侧marging有负值。 另一侧margin没有值的时候,width会一直延伸。另一侧margin有正值的时候,根据正数的大小,以负数margin位置和正数margin位置为内容区的两边,自动调整width的大小,当正数margin延伸的位置与负数margin所在的位置重合的时候,width变为0。另一侧margin有负值的时候,内容区两边向布局上下文外侧左右延伸。
2.当width设置为固定值的时候,这种情况看起来复杂度低一些,毕竟可以自己改变的量只剩下了margin。此时如果在内容区两边同时添加左右padding是不会有任何冲突的,但是若同时添加左右margin就很可能产生冲突了。因为width是固定的,若固定一边的margin,那么另一边的margin也会是固定的,但另一边的固定的值很可能不是你设置的那个值。这时候这个矩形区域就会受限,首先的处理方法就是有一个优先级,如果左右margin相互冲突,那么优先满足左边的margin,如果上下margin相互冲突,那么优先满足上面的margin。像固定宽度的情况下两边都是负数的margin,那么元素会优先向左边移动。还有一个特殊用法是关于水平居中,即当左右两边margin设置为auto,并且width为固定值,则该内容区域在布局上下文中水平居中。
左右负外边距还有一个特殊的规则,就是如果左外边距为负数,并且元素都超出了浏览器,那么它就真的超出看不见了,不会在浏览器下面形成滚动条。如果右外边距为负数,并且元素向外移动超出了浏览器,那么它是不会消失看不见的,因为会在浏览器下面形成滚动条。还有在正常情况下,汉字在父元素高度允许的情况下会自动换行,若父元素的高不足以容纳所有汉字,并且父元素也没有设置over-flow属性,那么汉字内容就会超出父元素。而单词要想换行的话除了父元素高度要允许,还是额外设置word-wrap和word-break属性。
在垂直方向上,垂直方向上的情况比水平方向上的还要复杂一些,因为margin在垂直方向上可以合并而在水平方向上是不会合并的。垂直方向上的height属性不会像width一样默认情况下会尽量延展,而是会尽量虽小刚好为内容高度。这样在height为auto,并且父元素没有adding和border空间的时候,最高块级子元素和最低块级子元素的margin范围是不会在父元素的内容区内的,它俩margin作用范围和父元素的margin是一样的(都是父元素外的margin空间),并且有合并效果。如果父元素有border或者padding,那么这俩空间就会阻挡最高和最低块级子元素的margin作用范围超出其布局上下文,并会增加父元素的height数值。还要注意若padding或margin设置为了百分数,那么不管垂直还是水平方向这百分数的参照都是父元素的width。在一个布局上下文中,其中的各个块级子元素之间的相对位置是一定的,如果一个子元素位置发生了变化,那么它下面的子元素为了维持和原来一样的相对位置也会随着产生相应的位置变化。这在负的外边距情况下要特别注意,负的外边距根据父元素的height是否为auto表现的也不是很一样。这种不一样主要表现在最后一个块级子元素上,前面说过当margin-top的值和margin-bottom的实现冲突的时候要优先实现margin-top的值,因为块级子元素在布局上下文中根据margin可以自由调整位置的,所以第一个和中间的子元素是不存在margin-top和margin-bottom冲突的情况的,唯一可以出现冲突的情况就是最后一个块级子元素,因为最后一个块级子元素的margin-bottom是对父元素内容区的下边界产生作用的,如果这个下边界可变就没有冲突,如果这个下边界不可变就可能会有冲突,这个下边界可变与不可变就是父元素的height是否为auto决定的。当height为auto的时候,块级子元素所有的负的margin都会产生父元素变短的效果,若height为固定值,那么最后一个块级子元素的margin-bottom不会有任何作用。
2.行内矩形区域中:
行内矩形区域(盒模型)就简单一些了。首先行内矩形区域的width和height的设置是无效的,它只会根据内容的大小自动调整自己的大小。在外边距方面,margin的垂直设置是不会有任何效果的,因为它毕竟在行框内,margin改变不了行间距。而水平的margin是可以有相应的效果的。同样的padding,border的垂直设置也同样是不会改变行间距的,因此看不出效果,除非有背景或者颜色会有一些效果,比如说会遮盖住相邻上下两行的内容,但行间距还是没有改变的。水平设置倒是也同样会有相应的效果。