在上一篇想要清晰的明白(一): CSS视觉格式化模型|盒模型|定位方案|BFC比较宏观的了解了盒子模型的作用,接下来就详细的介绍两种盒子的具体细节
Block Box
(图自《css权威指南》)
display : block 、 list-item 以及 table 会让一个元素成为块级元素。
在Block Box中,会被水平格式化,垂直格式化,那我们就分垂直和水平来讲讲
水平格式化
如何计算其宽度
正常流中,块级元素框的水平部分 = 其父元素的width
= margin-left+margin-right + padding-left+padding-right+ border-left+border-right+自身width
这个理解非常重要!是等于其父元素的width!
width & margin & auto
为什么.a中设置padding为auto,均invalid?
在padding-left/right,margin-left/right,border-left/right,width(我们简称下水平7大属性)中只有margin和width的值可能为auto设置margin-left为10px,显示正确,为什么margin-right是剩余的所有宽度?
因为当margin-left/right,width三个值均设置有固定宽度的时候,margin-right会根据包含块的width自动补齐利用margin:0 auto 居中
所以,利用这种方式居中的时候,必须是要设置居中元素的宽度,这样左右margin的值便会相等,从而引起的居中,这个和text-align:center只能块级元素的内联内容设置居中是不一样的。
垂直格式化
height与width一样,height定义了内容区的高度,而不是元素框的高度。元素框上下的内边距,边距,都会增加到height值里。
只有三个属性可以设置auto,height,和margin-top/bottom。注意!这里如果margin-top和margin-bottom同时设置为auto,也不会垂直居中,而是默认为零。
垂直格式化,有一个很重要的方面是会造成垂直相邻外边距合并,解决这个的方式见想要清晰的明白(一)中的BFC部分。
负margin
水平方向
问: 水平7大属性相加要等于父元素的width,那margin负值会造成什么?
若width不是固定值,那么width的值则会增大
因为要满足条件等于父元素width,负margin相当于负值,width auto自动增大
若width为固定值,那么margin-right则会auto增大来满足这个条件
灰色部分是body内的一个盒子,图二,没有定框使用负margin后,发生偏移,并且宽度增加,图三,定宽,发生偏移但是,宽度不增加,我们常常会发现出现莫名的水平滚动条,这里很有可能就是margin这小子在作祟
垂直方向
黑色是接在灰色div后的一个div,可以看到,margin-bottom为负值,不会造成元素本身的移动,而是造成兄弟元素往上移动,就像我不动,拉了下面的人一把,而margin-top为负值,就像我们排成一队,然后像兔子跳一样一起往前面跳了一步。
从图二也可以看出来,黑色盒子对灰色盒子发生了覆盖,因为浏览器总是按从前到后的顺序显示元素,所以文档中后出现的正常流元素可能会覆盖较早出现的元素。
可以发现,灰色盒子的高度依旧保持着并且渲染出来了,但是CSS读取的高度已经减小,下面的元素自然往上移动了
负margin与float应用 ——双飞翼
不知道为啥每次看到这名字,就....莫名的想笑,雅蠛蝶
<div class="main">
<div class="main-container">身子</div>
</div>
<div class="left">左边小翅膀</div>
<div class="right">右边小翅膀</div>
分析
margin负值导致两个翅膀是覆盖在div.main上,我们看到的蓝色部分是.main-container,margin-left:-100%,相当于是把第二排的第一个,从后面拉动一个100%距离,也就是到了第一排和第一排第一个一起站着,第二排第一个走了,第二排第二个(也就是div.right)自动补到他的位置上,这时候又来了个margin-left:-200px利用到第二排第二个上,往前拉动200px的距离,于是就到了现在div.right的位置
总而言之,水平上的七个元素的宽度和一定会等于父元素的宽度
Line Box
每一行称为一条Line Box,它又是由这一行的许多inline-box组成,它的高度可以直接由line-height决定,line boxes的高度垂直堆叠形成了containing box的高度,就是我们见到的div或是p标签之类的高度了。
基础概念
匿名文本
<div>当你只有一把锤子<span>一切看起来</span>都像是颗钉子</div>
未包含在行内元素的字符串(当你只有一把锤子,都像颗钉子)就叫匿名文本
内容区 行内框 间距
内容区
css假设每个元素都会生成一个或者多个Box,称为元素框,元素框中心有内容区,内容区外周围包括了padding,border,margin,但是,替换元素是包括外边距,内边距,边框的。
行间距
行间距是font-size与line-height的差值,被分成两半在内容区的上下
行内框
非替换元素,行内框高度=line-height
替换元素,行内框高度=内容区宽度(行间距不应用到替换元素)
行高
两行文字基线的距离
行框
一行有很多行内框,行框是包含这一行行内框最高点和最低点的
基线
不同元素的基线位置不同,整个行框会有一个基线,行内元素的位置是基于两者基线对齐
vertical-align(垂直对齐)
该属性 定义 行内元素的基线相对于该元素所在行的基线的垂直对齐的方式。
只有一个元素属于inline或是inline-block(table-cell也可以理解为inline-block水平)水平,其身上的vertical-align属性才会起作用.
同时也可以知道,改变其,会影响到行内框的位置,从而会影响到一整行行内元素的位置
需要注意vertical-align为数值时,会让文字上下移动,当其为百分比时是针对font-size的百分比
line-height(行高)
<div style="width:100px;height:10px"></div>
//这个div调整line-height不会发生变化,因为里面没有文字
<span style="line-height:10px;border:1px solid green"></span>
//span的高度会随着line-height的变化而变化
//说明行内元素的高度是由line-height的支撑决定,行内框的高度也等于line-height
管理line-height
因为line-height是根据自己font-size设置,而不是父元素,所以将line-height设置为1em,该元素的line-height则会与相同(em单位是一般是相对与父元素进行设置大小)
<div style="font-size:12px;line-height:12px">
<span style="font-size:15px;line-height:1em">
嘿嘿嘿,这里的line-height值为15px
</span>
</div>
margin padding border对行高的影响
行内元素其padding、margin、border-top、border-bottom 不会增加行高。
padding会覆盖;margin将重置为0;border-top和border-bottom同样会覆盖。
css2.1规定margin-top和margin-bottom可以运用到不是行内非替换元素的所有其他元素
行内替换元素(如:img)元素会影响行高
inline-block
将对象呈现为inline对象,但是对象的内容作为block对象呈现。之后的内联对象会被排列在同一行内。比如我们可以给一个link(a元素)inline-block属性值,使其既具有block的宽度高度特性又具有inline的同行特性。
参考资料
《CSS 权威指南 第三版》
《The Definitive Guide to Using Negative Margins》
margin为负值产生的影响和常见布局应用
CSS布局 -- 圣杯布局 & 双飞翼布局
CSS深入理解vertical-align和line-height的基友关系
深入理解CSS中的行高