本文原创:liruifangcss
做为一个前端人,常常混迹于图片和文字相互糅杂的江湖中,稍有不慎便会中招,本文主要从line-height和vertical-align入手,分析项目中出现的“诡异”现象,透过现象看本质,从而化敌为友为我所用。html
<style type="text/css"> .demo1 { line-height: 100px; background-color: pink; } .demo1 span { font-size: 40px; background-color: grey; } </style> <div class="demo1"> <span>xxJD-BG-FExx</span> </div> 复制代码
为何单行文本的可视高度是109px,而不是100px?前端
<style type="text/css"> .demo2 { border: 1px solid black; width: 1080px; } .img { display: inline-block; height: 296px; } .text { background: pink; } </style> <div class="demo2"> <img class="img" src="img/konan.jpg"> </div> 复制代码
图片下方为何会出现空隙?html5
<style type="text/css"> .demo3 { font-size: 40px; } .icon { width: 1em; vertical-align: middle; } .gap { display: inline-block; } .gap span { /*vertical-align: middle;*/ } </style> <div class="demo3"> <p class="gap"><img class="icon" src="img/unpaid.png">待支付:</p> </div> 复制代码
明明用了vertical-align: middle,图片位置为何偏下?segmentfault
<style type="text/css"> .demo4 { display: inline-block; width: 100px; height: 100px; border: 1px solid red; } .align { /*line-height: 0;*/ /*font-size: 0;*/ /* vertical-align: top;*/ } </style> <div class="demo4"></div> <div class="demo4"></div> <div class="demo4">x见证奇迹x</div> 复制代码
矩形块为何不是一行排列?bash
<style type="text/css"> .ctn-block{ background-color: #bbb; } .ctn-block .child { display: inline-block; width: 100px; background-color: aliceblue; } .ctn-block .child-1 { height: 100px; vertical-align: middle; } .ctn-block .child-2 { height: 200px; } .ctn-block .child-3 { height: 300px; } </style> <div class="ctn-block"> <div class="child child-1"></div> <div class="child child-2"></div> <div class="child child-3"></div> </div> 复制代码
最小矩形块明明设置了vertical-align: middle;为何没有居中对齐,反而感受“掉”下去了?markdown
www.w3school.com.cn/cssref/pr_d…wordpress
line-height 属性设置行间的距离(行高)oop
不容许使用负值布局
a.该属性会影响行框的布局。在应用到一个块级元素时,它定义了该元素中基线之间的最小距离而不是最大距离。 b.line-height 与 font-size 的计算值之差(在 CSS 中成为“行间距”)分为两半,分别加到一个文本行内容的顶部和底部。能够包含这些内容的最小框就是行框。
取值 | 描述 |
---|---|
normal | 默认。设置合理的行间距。 |
number | 设置数字,此数字会与当前的字体尺寸相乘来设置行间距。 |
length | 设置固定的行间距。 |
% | 基于当前字体尺寸的百分比行间距。 |
inherit | 规定应该从父元素继承 line-height 属性的值。 |
a.分红两半加到文本行上下 b.相对值:相对于font-size计算
font-size: 14px;
line-height: 1.5;(21px)
line-height: 150%;
line-height: 1.5em;
复制代码
都是21px,三者是否彻底同样?
<head> <title>line-height相对值</title> <style type="text/css"> body,h3,p { margin: 0; } body { font-size: 14px; line-height: 1.5; /*line-height: 150%;*/ /*line-height: 1.5em;*/ } h3 { font-size: 32px; } p { font-size: 20px; } </style> </head> <body> <h3>标题</h3> <p>内容</p> </body> 复制代码
上例中,vertical-align:1.5时,标题和文字显示正常;其余两个值时,标题和文字却挤在了一块儿。
分析:继承的差异,line-height为数值时,全部子元素继承的都是这个值;而另外两个相对值,子元素继承的是最终的计算值。
1. 对于块级元素,line-height指定了元素内部行框盒子(line-boxes)的最小高度,对块级元素自己没有任何做用
2. 对于非替代纯内联元素,可视高度彻底由line-height决定(对,是彻底),line-height指定了用来计算行框盒子高度的基础高度
3. 对于替代行内元素,例如img、input、button,line-height没有影响
复制代码
<div class="demo"> <img src="img/konan.jpg"> </div> .demo { line-height: 256px; } .demo img { height:128px; } 复制代码
分析:根据以上规则,line-height对块级元素自己没有任何做用,指定的是内部行框盒子的最小高度,而本例中内部是替代行内元素,line-height对其没有影响,那么,最外层div的可视高度是多少?128px?错!是256px。
存在的前提:必须是html5声明
规范中的定义: Each line box starts with a zero-width inline box with the element's font and line-height properties. We call that imaginary box a ”struct"。
解释:每个行框盒子开始的位置都有一个与之行高、字体大小相同,宽度为零的内联盒子。===> 行框前面有一个宽为0的空字符 ===>幽灵空白节点(张鑫旭大师命名)
<div class="demo"> <span>此处是一行文字</span> </div> case1 .demo { line-height: 96px; } .demo span { line-height: 20px; } case2 .demo { line-height: 20px; } .demo span { line-height: 96px; } 复制代码
以上两种状况下,最外层div的可视高度是多少?都是96px
那么问题来了,若是是图文混杂的混合的行框盒子,高度如何表现?
只能决定最小高度,最终高度说了不算
why?
1.替代行内元素不受控制 2.vertical-align的影响
vertical-align 属性设置元素的垂直对齐方式。
1.该属性定义行内元素的基线相对于该元素所在行的基线的垂直对齐。 2.容许指定负长度值和百分比值。这会使元素下降而不是升高。 3.在表单元格中,这个属性会设置单元格框中的单元格内容的对齐方式。
取值 | 描述 |
---|---|
baseline | 默认。元素放置在父元素的基线上 |
sub | 垂直对齐文本的下标 |
super | 垂直对齐文本的上标 |
top | 把元素的顶端与行中最高元素的顶端对齐 |
text-top | 把元素的顶端与父元素字体的顶端对齐 |
middle | 把此元素放置在父元素的中部 |
bottom | 把元素的顶端与行中最低的元素的顶端对齐 |
text-bottom | 把元素的底端与父元素字体的底端对齐 |
length | |
% | 使用 line-height的百分比值排列,容许负值 |
inherit | 规定应该从父元素继承 vertical-align 属性的值 |
a. 做用前提:只应用于内联元素以及display: table-cell的元素;好比float和position:absolution会使元素块级化,没有理由和vertical-align同时出现 b.相对值:相对于line-height计算 c.基线为什么物? d.父元素的中部指的是?
小写字母'x'衍生出了"x-height"概念,指的的是小写字母x的高度,在css中用ex来表示这个相对单位
baseline肯定规则:
1.inline-table元素:table第一行的baseline 2.父元素line box:最后一个inline box 的baseline 3.纯文本的内联元素:字符x的下边缘 4.替换元素:替换元素的下边缘 5.inline-block: (1) 内部没有内联元素,或者overflow不为visible,则:baseline是该元素margin底边缘 (2) 内部有内联元素,baseline是元素里面最后一行内联元素的基线
内联元素:元素的垂直中心点和行框盒子基线往上1/2 x-height处对齐,即字符x的中心交叉位置点。 table-cell:单元格盒子相对于外面的表格行居中对齐。
嫌疑人:line-height,vertical-align,幽灵空白节点
突破口: line-box的基线,在哪里? inline级元素的基线,在哪里? line box先后打个小写字母“x”瞧瞧
vertical-align默认值是baseline, 也就是基线对齐。 “幽灵空白节点”的高度是由行高决定的
经过display或者position,float等将inline水平的img变成block,一口气干掉三个元凶 使用其余vertical-align值 直接修改line-height值:下面的空隙高度,其实是文字计算后的行高值和字母x下边缘的距离。所以,只要行高足够小,实际文字占据的高度的底部就会在x的上面,下面没有了高度区域支撑 line-height为相对单位,font-size间接控制
没有通过处理的文字,其基线和line box的基线重合,图片设置vertical-align:middle,其正中心对准父级元素的x的正中心; 可是x字母的正中心并非其所在的text-box的正中心,而是text-box中心稍稍的偏下了一点
咱们把“center”包裹起来并为也设置 vertical-align: middle,“center”的基线就再也不和line-box的基线重合了,而是稍稍下移了,图文对齐 利用margin-bottom处理 利用vertical-align: length(负值), 设置数值进行对齐 尺寸合适的状况下,能够采用1ex的方式(经验取值基于20px的图标)
根据基线的肯定规则,框里没有内联元素的,基线是容器的margin下边缘,框内有文字的,基线是文字的基线:字母x的下边缘;所以:左框下边缘与右框x字符底边对齐
line-height:0;或者font-size:0;(间隔更大,why?提示:line-height为0,字符占据的位置也为0,高度的起始位置变成字符内容框的垂直中心位置[存在字符下沉],字符上移,基线也上移) 换一种对齐方式,vertical-align设为其余值
middle对齐的参照标准是将子元素盒子的垂直中点与父盒子的baseline加上父盒子的x-height的一半位置对齐
一种方式是将最高的元素设为vertical-align:middle,而后将想要居中的也设定为vertical-align:middle (解释)最高元素设定为vertical-align:middle后,这个元素对于line box来讲,baseline就是其中线,再将须要设定垂直居中的元素也设定为vertical-align:middle,它们的baseline必然在最高元素的baseline之上,因此被强制下移,进行居中。
内联元素默认是基线对齐的,而基线就是x的底部,而1ex就是一个x的高度。设想下,假如咱们图标高度就是1ex, 同时背景图片居中,岂不是图标和文字自然垂直居中,并且,彻底不受字体和字号的影响。由于ex就是一个相对于字体字号的单位。
<div> liruifang<i class="icon-arrow"></i> 京东前端<i class="icon-arrow"></i> </div> <style type="text/css"> .icon-arrow { display: inline-block; width: 20px; height: 1ex; background: url(img/arrow.png) no-repeat center; } </style> 复制代码
- 近似的缘由:字符x的位置都是偏下一点的
![]()
- 彻底居中:font-size:0,绝对中心线和中线重合。
<i class="icon-delete"></i>删除 <i class="icon-delete">删除</i>(为了使得文字不可见,设置overflow:hidden) 复制代码
分析:空标签 or overflow:hidden 基线是底边缘,与文字默认不对齐
思路:图标和文字高度一致 + 基线一致 = 对齐!
- 图标和当前高度都是20px:如需合并背景图标,做者建议图标原图统一处理成一种规格再进行合并
- 图标标签里永远有文字:借助:before或者:after伪元素生成一个空格字符
- 潜在字符不可见,可是不使用overflow:hidden,保证基线为里面字符的基线
<style type="text/css"> .box { line-height: 20px; } .icon { display: inline-block; width:20px; height:20px; white-space: nowrap; letter-spacing: -1em; text-indent: -999em; } .icon:before { content:'\3000'; } /* 具体图标 */ .icon-xxx { background: url(img/delete.png) no-repeat center; } </style> <div class="box"> <h4>1. 空标签后面跟随文本</h4> <p><i class="icon icon-delete"></i>删除</p> <h4>2. 标签里面有“删除”文本</h4> <p><i class="icon icon-delete">删除</i>看一眼时间</p> </div> 复制代码
- 不须要margin和vertical-align的垂直偏移
- 小图标和文字对齐彻底不受字体大小影响
- 整个项目小图标和文字对齐的问题均可以解决,节约css代码,下降开发和维护成本
现象问题(使人抓狂)——> 属性介绍(透过现象看本质)——> 问题剖析(真相只有一个)——> 简单应用(化敌为友)