CSS中的相对单位
1. em 和 rem
em 是相对于字体大小的相对长度单位。1em 等于当前元素的字体大小。
1.1 用 em 设置内边距
<!doctype html>
<head>
<style>
.padded {
border: dashed grey 1px;
font-size: 16px;
padding: 1em;
}
</style>
</head>
<body>
<div class="padded">
快来 <a href="https://www.csdn.net/">CSDN</a> 写博客。
</div>
</body>
这里内边距的值为 1em
,乘以字体大小就是16px
。浏览器根据相对单位计算出的绝对值就是计算值。
如果将内边距设置为 2em
,内边距就是32px
。
1.2 用 em 定义字体大小
em 用于 font-size 属性时,当前元素的字体大小是相对于继承的字体大小来计算的。
<!doctype html>
<html>
<head>
<style>
body{
font-size:16px;
}
.example{
font-size:1.5em;
}
</style>
</head>
<body>
我爱CSDN
<p class="example">我爱CSDN</p>
</body>
</html>
example 的指定字号是 1.5em
,根据继承的字号大小 16px
可以算得字号是 24px
。
知道字号的像素值还想用 em 声明时,可以用想要的字体大小除以继承的字体像素大小。
1.3 将 em 用于字体和其他元素
当设置 padding、height、width、border-radius 等属性时,使用 em 会很方便,因为当字体大小改变时,这些属性也会均匀缩放:
<!doctype html>
<head>
<style>
body {
margin: 1.5em;
}
.box {
padding: 1em;
border-radius: 1em;
background-color: lightgray;
}
.box-small {
font-size: 0.8em;
}
.box-large {
font-size: 1.2em;
}
</style>
</head>
<body>
<span class="box box-small">Small</span>
<span class="box box-large">Large</span>
</body>
两个字体大小通过 em 分别设置为了 0.8 × 16 0.8 \times 16 0.8×16 px、 1.2 × 16 1.2 \times 16 1.2×16 px。所以两个盒子的内边距,圆角都会因为字体大小而不同:
1.4 解决多级列表中字体缩小的问题
当用 em来指定多重嵌套的元素的字号时,就会产生奇怪的结果:
<!doctype html>
<head>
<style>
body {
font-size: 50px;
}
ul {
font-size: 0.8em;
}
</style>
</head>
<body>
<ul>
<li>Top level
<ul>
<li>Second level
<ul>
<li>Third level
<ul>
<li>Fourth level
<ul>
<li>Fifth level</li>
</ul>
</li>
</ul>
</li>
</ul>
</li>
</ul>
</li>
</ul>
</body>
由于每个内层嵌套的列表都是ul
的子元素,所以每个li
都应是自己父元素字号的 0.8 倍。所以随着嵌套的等级越来越高,字体的大小就会逐渐变小。
要解决上面的问题,就需要控制多级列表的字号继承,即可以控制ul
的子孙结点不加放缩地继承ul
的字号。我们可以在<style>
标签中加入:
ul ul{
font-size: 1em;
}
即可让嵌套列表的字号等于其父结点的字号:
1. 5 使用 rem 定义字号
浏览器解析 HTML 文档时,会在内存里将页面所有元素表示为文档对象模型。它是个树结构,每个元素由一个节点表示。<html>元素是根节点,他下面是子节点 <head> 和 <body>,再下面是逐级嵌套的后代节点。
可以使用伪类选择器(:root
)选中根节点,也可以使用类型选择器 html
,但是:root
的优先级更高。
rem
是 root em 的缩写,也就是相对于根元素的单位。不管在文档的什么位置使用 rem,都会得到相同的计算值。
使用 rem 解决上面多级列表的问题:
:root{
font-size: 50px;
}
ul{
font-size: 0.8rem;
}
根元素字号为 50px。无序列表的字号为 0.8 rem,计算值为 40px。所有无序列表字号大小都是相对于根元素,所以他们的字号大小都是相同的。
2. 视口的相对单位
除了相对于 font-size 定义的em 与 rem,还有相对于浏览器视口定义长度的视口的相对单位。
浏览器窗口里网页可见部分的边框区域称为视口。不包括浏览器的地址栏、工具栏、状态栏。
视口的相对单位主要有以下4个:
vh
:视口高度的 1/100。vw
:视口宽度的 1/100。wmin
:视口宽、高中较小的一方的 1/100。vmax
:视口宽、高中较大的一方的 1/100。
比如,50vw等于视口宽度的一半,25vh等于视口高度的 25%。横屏时,vmin取决于高度,竖屏时取决宽度。
用 vmin
展示正方形元素:
<!doctype html>
<head>
<style>
.square {
width: 90vmin;
height: 90vmin;
background-color: #369;
}
</style>
</head>
<body>
<div class="square"></div>
</body>
效果图:
宽度不变,拉长高度后:
2.1 使用 vw 定义字号
使用 vw 定义字号时,字号大小会设置为 vw 值乘以屏幕像素宽度
。
比如 font-size: 2vw 在 2k 显示器上字体大小就为51.2px:
在手机上可能只有几个px,对于大多数人来说几个px还是太小了。使用 calc() 函数可以改进一下。
2.2 使用 calc() 定义字号
calc() 函数可以进行数值的基本运算:加减乘除。
要解决上一小节中字体在手机上显示太小的问题,我们需要设置一个字体最小值。将 font-size 设置成一个常量加变量即可:
<!doctype html>
<head>
<style>
:root {
font-size: calc(0.5em + 1vw);
}
body {
font-family: Helvetica, Arial, sans-serif;
}
.panel {
font-size: 1rem;
padding: 1em;
border: 1px solid #999;
border-radius: 0.5em;
}
.panel > h2 {
margin-top: 0;
font-size: 0.8em;
font-weight: bold;
text-transform: uppercase;
}
.panel.large {
font-size: 1.2em;
}
</style>
</head>
<body>
<div class="panel">
<h2>Single-origin</h2>
<div class="body">
我爱写博客,尤其是在 <a href="/batch-size.html">CSDN</a> 上
</div>
</div>
</body>
缩小网页宽度后:
这样在小屏设备上显示字就不会太小了。
3. 没有单位的数和行高
支持没有单位的值的属性包括 line-height 、z-index 、 font-weight。长度单位都可以使用无单位的 0。
其中 line-height 既可以有单位也可以无单位。从下面的代码中查看两者的区别。
没有单位:
<!doctype html>
<head>
<style>
body {
line-height: 1.2;
}
.about-us {
font-size: 2em;
}
</style>
</head>
<body>
<p class="about-us">
We have built partnerships with small farms around the world to
hand-select beans at the peak of season. We then carefully roast in
small batches to maximize their potential.
</p>
</body>
效果图:
这个段落继承了行高 1.2。本例中就是 1.2 x 2 x 默认字号
文字间距看起来还是比较舒服的。
有单位:
body {
line-height: 1.2em;
}
效果图:
当一个元素的值定义为长度时,子元素会继承它的计算值,本例中 line-height 的计算值就是 1.2 x 默认字号
。
所以能得出结论: 使用无单位的数值时,继承的是声明值,每个继承子元素上会重新计算它的计算值;使用有单位数值时,继承的是计算值。