1、line-height的定义
行高,两行文字基线之间的距离
定义三问
1)、什么是基线?
2)、为何是基线?
基线是定义任何线的根本。
3)、需要两行?—— 一行文字没有行高?
一行文字也是有行高的。两行的定义已经决定了一行的表现!
4)、 不同字体的基线位置也有不同:
5)、为何line-height可以让单行文本垂直居中?
图中的红线为元素垂直距离的中线。实际上没有垂直居中,只是看起来居中了。
2、line-height与行内框盒子模型
所有内联元素的样式表现都与行内框盒子模型有关!例如浮动的图文环绕效果等。
行内框盒子模型讲解,下图:
1)、 “内容区域”(content area)
是一种围绕文字看不见的盒子。“内容区域”(content area)的大小与font-size大小有关;
内容区域的大小个人理解为我们选中文字时所看到的选中区域
2)、“内联盒子”(inline boxes)
3)、“行框盒子”(line boxes)—— 有几行文字,就有几个“行框盒子”
4)、“包含盒子”(containing box)
<p>
标签所在的“包含盒子”(containing box),此盒子有一行一行的“行框盒子”(line boxes)组成;
*总结,行内框盒子模型有:
其中,4包含3,3包含2,2和1的关系说不清
3、line-height的高度机制和原理(主要讲内联元素)
<body>
<p>这是一行普通的文字,这里有个<em>em</em>标签。</p>
<script>
console.log(document.querySelector('p').clientHeight); // 21
</script>
</body>
上面p的高度是:21px
1)、 思考:内联元素的高度从何而来?
是不是由里面的文字撑开的?—— 不是。实际上是由line-height决定的!
<style>
.test1 {
font-size: 36px;
line-height: 0;
border: 1px solid #ccc;
}
.test2 {
font-size: 0;
line-height: 36px;
border: 1px solid #ccc;
}
</style>
<body>
<p class="test1">这是一行普通的文字,这里有个<em>em</em>标签。</p>
<p class="test2">这是一行普通的文字,这里有个<em>em</em>标签。</p>
</body>
2)、 line-height明明是两基线之间的距离,单行文字哪来的行高,还控制了高度?
需要知道的:
- 行高由于其继承性,影响无处不在,即使单行文本也不例外;
- 行高只是幕后黑手,高度的表现不是行高,而是内容区域和行间距,只不过,正好:内容区域高度 + 行间距 = 行高。
3)、 内容区域高度:
- 内容区域高度只与字号以及字体有关,与line-height没有任何关系。
- 在simsun(宋体)字体下,内容区域高度等于font-size大小值。
simsun(宋体)字体下:font-size + 行间距 = line-height
4)、行间距(假设是宋体):
font-size: 240px;
line-height: 360px;
则行间距 = 360px - 240px = 120px;
实际上文字的行间距是上下均分的: 行间距上下拆分,就有了“半行间距”。
总结:
行高决定内联盒子高度;行间距可大可小(甚至负值),保证高度正好等同于行高。
5)、 如果行框盒子里面有多个不同行高的内联盒子?
由行高最高的那个盒子决定?—— 似是而非,看上去是对的其实不对。
<body>
<p>这是一行简单地文字<em style="line-height:80px;">em</em></p>
<script>
console.log(document.querySelector('p').clientHeight); // 80
</script>
</body>
上面<p>
高度是:80px
<body>
<p>这是一行简单地文字<em style="line-height:80px;vertical-align: 40px;">em</em></p>
<script>
console.log(document.querySelector('p').clientHeight); // 90
</script>
</body>
上面<p>
高度是:90px ≠ 高度最高的内联元素
6)、包含多个行框盒子的包含容器:
多行文本的高度就是单行文本高度累加。
4、line-height各类属性值
1)、line-height支持的属性值
- normal
- <number>
- <length>
- <percent>
- inherit
2)、line-height:normal—— 默认属性值,跟着用户的浏览器走,且与元素字体关联。
mormal值 = 文字占据的高度 / 字体的font-size (由于mormal值的不确定,因此在网页开发中,经常在body元素样式里面设置一个固定的line-height值)
3)、line-height:<number>—— 使用数值作为行高值
line-height: 1.5;
根据当前元素的font-size大小计算。
假设文字大小(font-size)20像素,则实际的行高像素值是:
line-height = 1.5 * 20px = 30px;
<style>
p {
font-size: 20px;
line-height: 1.5;
}
</style>
<body>
<p>哈哈哈哈哈哈哈哈哈哈哈哈哈哈或</p>
</body>
4)、line-height:<length>—— 使用具体长度值作为行高值
line-height: 1.5em;
line-height: 1.5rem;
line-height: 20px;
line-height: 20pt;
5)、line-height:<percent>—— 使用百分比作为行高值
line-height: 150%;
相对于设置了该line-height属性的元素的font-size大小计算。
假设文字大小(font-size)20像素,则实际的行高像素值是:
line-height = 150% * 20px = 30px;
<style>
p {
font-size: 20px;
line-height: 150%;
}
</style>
<body>
<p>哈哈哈哈哈哈哈哈哈哈哈哈哈哈或</p>
</body>
6)、line-height:inherit—— 行高继承,IE8+
input { line-height: inherit; }
input框等元素默认行高是normal,使用inherit可以让文本框样式可控性更强。
7)、line-height:1.5, line-height:150%, line-height:1.5em有什么区别?
- 计算无差别
- 应用元素有差别
- line-height:1.5 所有可继承元素根据font-size重新计算行高;
- line-height:150%/1.5em 当前元素根据font-size计算行高,继承给下面的子元素;
<style>
.p1 {
font-size: 20px;
line-height: 1.5;
}
.p2 {
font-size: 20px;
line-height: 150%;
}
span {
font-size: 60px;
}
</style>
<body>
<p class="p1">
<span>我的font-size为60px</span>
</p>
<p class="p2">
<span>我的font-size也为60px</span>
</p>
</body>
8)、网页开发时,body全局数值行高使用经验—— 匹配20像素的使用经验,方便心算
line-height = 20px / 14px ≈ 1.4285714...
font-size:14px;
/* chrome浏览器计算出来是19px */
line-height: 1.42857;
因此取:
font-size: 14px;
line-height: 1.4286;
同时设置字体:
font: 14px/1.4286 'microsoft yahei';
5、line-height与图片的表现
行高不会影响图片实际占据的高度!
1)、如何消除图片底部间隙
- 图片块状化 - 无基线对齐
img { display: block; }
- 图片底线对齐
img { vertical-align: bottom; }
- 行高足够小 - 基线位置上移
.box { line-height: 0; }
2)、小图片和大文字
基本上高度受行高控制
6、line-height的实际应用
1)、图片水平垂直居中 - IE8+以上浏览器支持
.box {line-height: 300px; text-align: center;}
.box > img {vertical-align: middle;}
2)、多行文本水平垂直居中
.box {line-height: 250px; text-align: center;}
.box > .text {display: inline-block; line-height: normal; text-align: left; vertical-align: middle;}
多行文字水平垂直居中实现的原理跟上面图片的实现是一样的,区别在于要把多行文本所在的容器的display水平转换穿成和图片一样的,也就是inline-block,以及重置外部继承的text-align和line-height属性值。
IE6等浏览器下,元素一旦有了高度,就表现为了display:block样式,父级的display:inline-block就不起作用了