vertical-align
vertical-align除了支持很多属性都有的inherit之外,还包括其它四类属性值
1、线类
baseline,top,middle,bottom
2、文本类
text-top,text-bottom
3、上标下标类
sub,super
4、数值百分比类
20px,20%
数值和百分比
1、都带数字
20px,20%
2、都支持负值
margin,letter-spacing,word-spacing,vertical-align。其它基本不支持
3、行为表现一致
1)在baseline对齐基础上上下偏移对应数值大小。
<div style="background:#eee;"> <img src="imgs/text.png" alt="" style="width:200px"> <span>文字</span> </div>
发现去移动的时候,是根据基线上下移动的
2)百分比的大小是相对于行高的,上面的demo,div设置行高,下面span设置百分比
所以上面的例子说明line-height和vertical-align是一对好基友。
二、vertical-align起作用的前提
有时候我们会遇到这样的问题,为什么我设置了vertical-align,却没有作用?去搜索百度的时候,会发现,第一个匹配的就是vertical-align无效,说明这个问题还是非常常见的。
为什么vertical-align会无效呢?因为,vertical-align起作用有前提条件的。我们可以去看vertical-align的定义
翻译过来的意思就是vertical-align应用与inline水平以及'table-cell'元素。
那么哪些是inline水平元素,哪些是table-cell元素呢
inline:<img>,<span>,<strong>,<em>,未知元素,... inline-block:<input>,<button> 'table-cell'元素 table-cell:<td>
默认状态下:图片,按钮,文字,单元格是inline元素,vertical-align是起作用的
那么为什么是默认状态下呢?因为css里面有个属性叫做display,可以设置inline
举几个例子
1、display
<style> p{ vertical-align: middle; } </style> <body> <p style="background:#eee; line-height: 100px; text-align: center;"> <img src="imgs/text.png" style="width:200px" alt=""> </p> </body>
这里我们发现vertical-align并没有起作用。因为p默认是block.
<style> img{ vertical-align: middle; } </style> <body> <p style="background:#eee; line-height: 100px; text-align: center;"> 左青龙<img src="imgs/text.png" style="width:200px" alt="">右白虎 </p> </body>
将vertical-align设置在img上,发现这个就居中了。如果把img改成block,那肯定是不起作用的
2、csss声明间接改变display水平
<style> img{ vertical-align: middle; float: left; } </style> <body> <div> <img src="imgs/text.png" style="width:200px" alt=""> <span>文字</span> </div> </body>
这里本来是居中对齐的,加两个个float发现文字往上跑了。因为设置了float,就创建了一个bfc,变成了block的
<style> img{ vertical-align: middle; position:absolute; } </style> <body> <div> <img src="imgs/text.png" style="width:200px" alt=""> <span>文字</span> </div> </body>
这个vertical-align也没有作用,文字跑到图片后面去了,因为绝对定位,脱离文档流了。
那么,,这些我们都知道这样vertical是无效,关键我们遇到的场景不是这样的。
三、vertical-align与line-height
1)、vertical-align百分比是相对于line-height值计算的
{
line-height: 30px;
vertical-align: -10%;
}
{
line-height: 30px;
vertical-align: -3px; (30 * 10%)
}
2)、透过现象看本质
<body> <p style="background:#eee; text-align: center;"> <img src="imgs/text.png" style="width:200px;" alt=""> </p> </body>
下面有一段空隙,这个就是vertical-align和line-height搞基搞出来的附产物。
对于内联元素,vertical-align与line-height虽然看不见,但实际上到处都是!
对于上面的demo,只要将这两个好基友分开就可以了
1)、display:block(vertcal-align只对内联元素有作用,一旦设置block,baseline就不起作用了)
2)、改变对齐方式,不要基线对齐,底线对齐
3)、专门对付行高,line-height:0 或者font-size:0
再看个例子
<style> .dib-baseline{ display: inline-block; width:150px; height: 150px; border: 1px solid #cad5eb; background: #eee; } </style> <body> <p> <span class="dib-baseline"></span> <span class="dib-baseline">x-baseline</span> </p> </body>
这是为什么,为什么没有对齐。正常情况下,两个盒子,宽高都一样,放在一起,肯定都是对齐排列的。那么为什么这个完全不对齐。
前面这个盒子里面没有任何字符,那么此时,这个盒子的基线是底边缘。如果这个盒子有文字,这个盒子的基线是文字的基线。于是两个基线对齐,就变成了这种情况。
再然后,把后面的盒子的行高变成0,发现又往下掉了一点,为什么又往下掉了呢?一个字符,如果行高设置成0,他实际上那个高度就变成0了。
如果变成0了从哪里算呢?行高有居中的特性,这里其实也一样,当一段文字行高变成0,实际上这个0开始算就是从文字的中间算。那么这个时候后面盒子的基线就是字母下面的基线,就这样对齐了。
四、线性类属性值(top,middle,bottom,baseline)
1、vertical-align:bottom
1)inline/inline-block元素:元素底部和整行的底部对齐。
2)table-cell元素:单元格padding边缘和表格行的底部对齐。
<style> .dib-baseline{ display: inline-block; width:150px; height: 150px; border: 1px solid #cad5eb; background: #eee; } </style> <body> <p> <span class="dib-baseline"></span> <span class="dib-baseline">x-baseline</span> </p> </body>
这个时候设置vertical-align:bottom
<body> <p style="background:#eee; text-align: center;"> <img src="imgs/text.png" style="width:200px;" alt=""> </p> </body>
这个时候设置vetial-align:bottom;
都会底部对齐,很单纯的
2、vertical-align:top,跟bottom相反,也很单纯。
3、vertical-align:middle
1)inline/inline-block元素:元素的垂直中心点和父元素基线上1/2 x-height处对齐
2)tabel-cell元素:单元格填充盒子相对与外面的表格行居中对齐。
<style> p{ line-height: 250px; } img{ vertical-align: middle; } </style> <body> <p style="background:#eee; text-align:center"> <img src="imgs/text.png" width="200" alt=""> <span>x</span> </p> </body>
这个例子,近似垂直居中。为什么不是居中呢?仔细看,上面的会大一点。我们再理解下定义,元素的垂直中心点和父元素基线上1/2 x-height处对齐
也就是这张图片的垂直中心点,父元素的基线,其实就是字符x的底部,往上1/2x处,其实就是x的中心点。
那么可以理解为这张图片的中心跟x的中心点对齐。那么这个x的中线是根据行高来的,并不是x字符的中心点,为什么呢?因为这个字符有个下沉的特性的,也就是vertical-middle,行高的中心跟字符的中心不是完全重合的。随着字符的变大,这个中心区别就越来越大
五、vertical-align文本类属性值(text-top,text-bottom)
1、vertical-align: text-top
盒子的顶部和父级content area的顶部对齐
2、vertical-align: text-bottom
盒子的底部和父级content area的底部对齐
也就是自己的(内联元素)顶部/底部跟父级的内容区域的顶部/底部对齐
<div style="font-size:24px;"> <div style="background:#eee;"> <img src="imgs/text.png" width="200" alt="" style="vertical-align: text-top;"> <span style="font-size:20px;">20px</span> <span style="font-size:24px;">24px</span> <span style="font-size:32px;">32px</span> <span style="font-size:40px;">40px</span> </div> <div style="background:#eee;margin-top:20px;"> <img src="imgs/text.png" width="200" alt="" style="vertical-align: text-bottom;"> <span style="font-size:20px;">20px</span> <span style="font-size:24px;">24px</span> <span style="font-size:32px;">32px</span> <span style="font-size:40px;">40px</span> </div> </div>
img的底部/顶部跟父元素的内容(父元素的内功是24px),那么就跟24px的顶部/底部对齐。跟左右元素没有关系,只与父级的字体大小font-size有关。左右元素底line-height也没有任何关系
实际作用,平时用的比较少,另外一个理解不了,不敢用
当一个图标和文字在一起的时候,比较合适
<body> <div> <img src="imgs/haha.jpg" alt=""> <span>龇牙咧嘴</span> <img src="imgs/text.png" width="200" alt=""> </div> <!-- 默认的时候图片偏上 --> <!-- 用顶部,底部感觉很完美,加上图片就不行了,受影响 --> <!-- text-bottom最完美 --> </body>
六、vertical-align上标下标类(super,sub)
首先html有自带的上标<sup>,下标<sub>
<body> <div> 2<sup>^</sup>2 </div> <div> H<sub>2</sub>O </div> </body>
这个上标和下标一般是75%大小,sup这个上标之所以上标,是因为默认的属性是vertical-align:super
sub下标之所以下标,是因为默认的属性是vertical-align:sub.
1、vertical-align:super
提高盒子的基线到父级合适的上标基线位置。(没有具体的位置,可能是字体不一样,上标基线的位置也不确定)
2、vertical-align:sub
降低盒子的基线到父级合适的下标基线位置。
七、实际应用
一个图标+一段文字
一般都会用vertical-middle。这个用起来不是那么的好
第一是因为兼容行,ie6,7表现不一样,还需要hack
第二是这个垂直居中,并不是真正的居中。
导致我们可能用margin,float,成本会高一卡,我们可以vertical-align:-10px。负值。
20px图标+14px文字 -5px.
多行文字居中对齐