零、块状和内联元素
1、块状元素:
单独一行,一个块状元素总是从新的一行开始,默认宽度(在不设置宽度/外边距的时候)则与自己的父元素的宽度一样(既:width:100%,margin-right:0);
2、行内元素:
不能定义宽度和高度(input是个例外,可以独立设置宽/高)。宽度则有自己的内容决定。高度也不可定义(但是可以通过设置行高line-height,将高度撑起来);
- 垂直方向的内边距、外边距以及边框会被应用但是不会把其他处于
inline
状态的盒子推开(即会覆盖其他周边处于inline状态的盒子)。 - 水平方向的内边距、外边距以及边框会被应用且会把其他处于
inline
状态的盒子推开
注意:行内元素(内联元素)设置行高是有效果的,但是不建议这么做。虽然行内元素设置行高之后会有下一行内容位置的变化,但是并没有改变盒子大小(字体大小),所以在为行内元素设置背景时,还是默认高度的地方有背景。(既:行内元素不能设置宽、高;所有宽高大小就是文本内容本身,line-height未改变其元素本身大小)。
一、基线:
字体排印中的概念,一般指的是大多数字母排列的基准线;
如上图所示:xNh(大多数)字母排列的基准线------基线; 更确切的说,字母x的下边缘(线)就是基线的所在。
二、line-height(行高)、leading(行距);
line-height = 字体大小 + 行距(上半行距+下半行距);
对于块级元素,它指定元素行盒(line boxes)的最小高度。对于非替代的 inline 元素,它用于计算行盒(line box)的高度。
三、inline-box(行内框)、line-box(行框/行盒)、containing(包含) box 和 content area(内容区域)
1、containing boxs:
2、“内联盒子”(inline boxes)
让内容排成一行的作用,如果有外部含inline水平的标签(span,a,em,strong等),则属于“内联盒子”,如果只是光秃秃的文字,则属于“匿名内联盒子”;
行高应用在 inline box上;
对于非替换元素,元素行内框的高度刚好等于line—height的值。对于替换元素,元素行内框的高度则恰好等于内容区的高度,因为行间距不能应用到替换元素。
行高应用在inline box上;
3、“行框盒子”(lines boxes)
每一行就是一个“行框盒子”,它其实就是包裹每行文字。一行文字一个line boxes。
所以一个没有设置height属性的div的高度就是由一个一个line boxes的高度堆积而成的。
4、“内容区域”(content area)
是一种围绕文字看不见的盒子,大小与字体大小有关;
Line boxes其实是由它里面的内联盒子(inline box)里的文字啊,图片等等,谁最高就决定,高度值就是谁。
综上,每个非替换"内联盒子"(一行中一个个盒子,让内容排成一排)高度= 它的 字体大小(内容区域)+上下半间距 = 它的 line-height; 而行框(行盒子)的高度则有 行中各个内联盒子(包括img等替换元素) 最上的顶边 到 最下的 底边的距离; 所以,非替代的 inline 元素,line-height能用来计算行框的高度(line-height能影响行框高度);
如果作为块状元素设置了line-height,line-height则指定行盒的最小高度(如果有图片等替换元素>行盒的最小高度,行盒的高度受影响);
上图中,图片是一个行内盒子,文字是零一个行内盒子,行盒(行框)高就是一行中最顶端到最低端的距离;
三、line-height的值和继承
1、em、%百分比都表示元素行高的 高度 = 当前字体大小的倍数(百分数);如果单位是px则表示行高大小固定为(xxx)px;
2、如果父元素设置了诸如line-height:1.5em、或者line-height:150%、甚至直接是line-height:36px的时候(数字后面带代位),此时是先算出行高(字体大小 * 1.5em),得出具体的行高数值,然后里面各个子元素的行高都继承这一个行高数值;
3、如果父元素设置了诸如line-height:1.5(纯数字,后面无单位),则子元素直接继承的是line-height:1.5,然后再根据各个子元素的字体大小,算出各个子元素自己的行高;
四、vertical-align:相对(和)谁对齐?
1、一个行盒子中有基线(x)、上边(行框最顶端)和下边(行框最底端);
2、一个行盒子中有一个或者多个行内元素(以及行内块状元素);每个行内(块状)元素都有其自己的基线、上边(行内盒顶部)和下边(行内盒底部);
3、所谓vertical-alingn垂直对齐,就是 行内(块状)元素的基线、外边界 相对于 行框的基线、外边界对齐;
五、行内(块状)元素的基线 和 行框的基线确定
1、行内元素的基线,比如一个文本,它的基线是大部分字母的对齐线,就是字母X的下边线;
2、行内块状元素的基线
- 如果行内块状元素中有流内容,其基线就是正常流中,最后元素的基线;
- 如果行内块状元素中有流内容,但是其overflow属性值不是visible(是hidden或者其他);或者,行内块状元素没有流内容,那么,此时 行内块状元素的基线则是 此元素的外边距盒子的底边
3、行框(行盒子)的基线:
通俗的说,就是设想在行盒的开头(或者结尾)加上一个字母X,这个字母X的下边线就是基线;
行盒子(行框)的基线是由一个行框中,最大的/最高的行内框(内联盒子)决定的;此行盒中的其他的较小的行内元素,将会以此行盒基线,为参照;(既:找出行盒中最高的元素,根据这个元素的对齐方式,确定基线位置,其他元素再进行参照);
六、vertical-align的各种属性值得说明:
注意:大多数情况下,行框基线上x-height的一半(字母X的中心)这个高度的位置,比line-height最中间点的高度要低;此现象又称为“字母下沉”;
以上由于设置了line-height,他的line-height中心线 的高度 一般高于字母X中间位置的高度,所以只能说是近似居中;
完美居中的两种方案:
1、对父元素设置font-size:0;
由于父元素设置了字体大小是0,那么此时,行高中间的字体也是就是0了,那么这个字体的基线、顶线、底线、X中点线都将合并,并且位置在line-height的正中间。所以此时,在元素A再设置vertical-align:middle;元素A的中间正好与line-height的正中间对齐了;
2、父元素不设置line-height,并且给他添加一个伪元素;(行盒子基线的改变)
.wrap:before {
content:'';
width: 0%;
display:inline-block; // 设置成行内(块状)元素,当成一个整体作为一行中展示;
vertical-align:middle; // 伪元素的中间位置,与x的中间位置对齐(基线位置改变了);其他元素再设置
vertical-align:middle;也就与垂直居中了;
height:100%; // 高度与父元素的高度一样;
}
行盒基线的改变;
1、div没有设置高度,图片也没有设置垂直居中的时候(默认基线对齐);
此时整个行盒的高度是img高度+基线到底线的距离+行距下半高度;
2、图片设置成vertical-align:middle;行盒的基线如下所示;
此时行盒高度是img的高度;
3、图片设置成vertical-align:top;此时行盒基线位置如下;
此时div高度依然是img的高度;
4、给div设置一个高度(大于img的高度)此时,行盒的基线如下;
div高度就是所设置的高度;虽然img设置了垂直居中,但是只是和x的中心线对齐的;
5、设置了line-height等于height;或者直接没有设置height;此时先固定的是基线;
div高度就是line-height的高度(大于img的高度);
6、没有设置line-height(的高度大于图片的高度,其实默认有line-height的),但是有div的高度,并且div高度大于图片高度;
此时div的高度就是设置的高度,若将图片在div中垂直居中;那么需要设置x的中心线正好在div的正中间(改变基线位置);
可以添加一个伪元素,改变行盒基线,使x的中心线正好在整个div的正中间;
通过vertical-align的值对齐一个较高的元素时,基线也会移动以匹配对齐(一般行盒的基线是随着 行框中 最高的行内元素 vertical-align的值而改变的;);如果新增的元素会超出行盒子的边界,那么行盒子的高度和基线就会再次调整;
参考:https://www.zcfy.cc/article/vertical-align-all-you-need-to-know
http://www.ddcat.net/blog2005/archives/2008/07/233.html
http://www.cnblogs.com/fengzheng126/archive/2012/05/18/2507632.html
https://segmentfault.com/a/1190000003038583
https://www.cnblogs.com/rainman/archive/2011/08/05/2128068.html