垂直属性
元素的盒模型有几个较为重要的属性,本篇文章主要将脚垫聚集在与height相关的属性上。
对于一个并未显式设置高度块框来说,其height的高度不仅仅取决去内容的高度,而且还与该块框的宽度有关。宽度越窄,相应的需要容纳
相同内容所需要的空间越大,高度越高。
而对于一个非替换行内元素而言(所谓非替换元素,就是呈现的内容都在文档中,比如span,a;而替换元素的典型就是img和表单元素),是
无法通过设置高度或者外边距来改变行内元素的高度的,但是内边距对行内元素的background还是有影响的,这个后面再仔细分析。
块元素
块元素的七大垂直属性:marginTop,borderTopWidth,paddingTop,height,borderBottomWidth,paddingBottom,marginBottom,这些属性
只有marginTop,marginBottom,height可以取值auto。但是对于这三个垂直属性的auto值,和对应的3个水平属性取auto值还有些许不同。
当marginTop 或者 marginBottom取值auto时,浏览器会自动将他们置零,所以最终呈现的是块元素没有外边距,所以无法使用这种marginTop:auto;
marginBottom:auto;方式来居中。
另外,当对块元素的宽度设置auto时,会出现集中特殊的情况:
- 块元素的子元素若是行内元素时,则块元素的高度恰好为足以容纳行内元素的行盒(line-box)为止。什么是行内元素的行盒,在另一篇文章再讲
- 块元素的子元素若也是块元素时,若父元素并没有设置边界属性--上下边框或者上下内边距,则父元素的高度为最上层子元素的上边框到最底层子元素的 的下边框之间的距离。
- 块元素的子元素若也是块元素时,若父元素设置边界属性,则父元素的高度为最上层子元素的上外边距到最底层子元素的下边外边距之间的距离。
其中第二个规则有些类似外边框叠加,确实,给父元素设置边界属性可以有效的防止父元素和子元素外边框的叠加。
行内元素(非替换元素)
对行内元素而言,显示设置height或者外边距是没有效果的。原因比较简单,那是因为行内元素的盒模型规则比较特殊。
<span>abcdefg</span>
上述span是一个典型的行内元素,height对其无效,因为行内元素内的每个文本元素都有一个内容区,该内容区的高度默认与该文本元素的font-size相等,可以理解
内容区只是文本的高度,但是最终占用空间的高度并不是内容区,而是行内框(in-line box),行内框的高度由line-height来设置,具体的算法是
height(in-line box) = (line-height - font-size) + height(内容区);
最终结果就是行内框的高度始终等于line-height的值。
而行内元素的每一行都有一个行框,该行框的高度值来源于这一行中最高的行框上边框与最低行框的下边框的差值。行框的高度是该行文本元素最终占有的高度。
line-height的值只对非替换行内元素有效(这个后面再讲),如果对块元素设置了line-height值,则对块元素本身并没有什么影响,但是对块元素下的行内元素
有效,line-height是可以继承的,若对line-height以百分号赋值,则是相对本元素font-size而言。
口说无凭,举个例子:
<p style="line-height: 20px;"> this is a paragraph</br> yeas, i have a line box</br> ok, i know you do not believe</br> <span>abcdefg</span> </p>
这个例子还是比较有代表性的,p标签内有3行匿名文本和span标签的文本,设置p标签的线高为20px。对于匿名文本,css是如何处理的呢?
我们可以这样“优化”一下代码:
<p style="line-height: 20px;"> <content>this is a paragraph</content></br> <content>yeas, i have a line box</content></br> <content>ok, i know you do not believe</content></br> <span>abcdefg</span> </p>
这样就明了许多了,<content></content>标签是我自己加上去的,辅助理解。这样所有的文本都继承自line-height:20px,如我们所想,每个行框的高度
都是恰好可以容纳所在行的最高的行内框和最低的行内框,所以这4个行框高度都是20px,所以p标签的高度为4 * 20 = 80px。
但是我们是要知道的,我们看到的span高度只是span的内容区高度,并不是行框或者行内框的高度。但在p标签内,span元素确实占据了20px的高度。这里说的
有些晕,可以这样理解,当我们打开开发工具,将鼠标移至span元素上,会看到显示高度为16px,这是默认的字体大小,也就是内容区的高度,但是,这并不是span所占
据的实际高度,实际高度是20px。
好了,到此为止。
如果对行内元素设置padding属性,会发生什么呢?
<p> <span style="line-height: 20px;padding:15px;background: #c0c0c0;opacity: 0.5;"> abcabcacb </br> cdcdcdcdcdcdc </span> </p>
可以看到,下面的字符串的背景覆盖了上面字符串的背景。 此处的背景高度 = 内容区的高度 + padding的值。
但是需要注意的是,padding的值不会改变内容区的高度,更不会改变行内框的高度。也就是说,添加padding并不会
影响布局,仅仅是外观(背景)的改变而已,边框也是类似功能。
另外,我们发现左内边距和右内边距的应用也有点奇怪:在行内元素第一行的左边应用左内边距,在末尾行应用右内边距。
此时,p标签的高度仍然是40px。
替换行内元素
替换行内元素,典型的就是图片。在实际操作中img标签有width和height特性,这也说明了他的特殊性。替换行内元素可以设置所有的7个垂直属性,但也有
line-height属性,只不过此时的line-height属性并不会对行框高度有作用,替换行内元素的行高由该元素的垂直属性所确定,比如一个元素
<img src="../img/1.jpg" width="200" height="200" style=margin:20px;">
此时行框的高度 = 200 + 20 + 20 = 240px。
但是替换行内元素的line-height并不是一无是处。当我们对img元素使用 vertical-align: 50%; 时,这个line-height的作用就出来了。
vertical-align属性的值为百分数时,它的参考对象是该元素的line-height值,而不是父元素的line-height值。所以若要高度为200px的替换行内元素img向上
便宜20px,可以这样设置:line-height:40px;vertical-align: 50%。