总:
px是绝对单位,rem和em都是相对单位
分:
1.px是像素单位,1px代表一个像素点,不同的屏幕分辨率下,1px显示的效果可能不同(css中像素是逻辑像素,不等同于物理像素)
2.em是相对于当前元素或与之最近的已经设置了font-size的父级元素的字体大小而言,如果当前元素和父级元素都未设置font-size,则参考根元素字体大小而言(默认16px)
3.rem,拆开来就是root em,也就是相对于根元素的字体大小而言的一个相对单位。是移动端适配的常用布局单位。
以下论证em:
情况一:不设置font-size的情况下,查看元素的em
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>em</title>
<style>
a {
width: 20em;
}
h2 {
width: 20em;
}
p {
width: 20em;
}
input {
width: 20em;
}
</style>
<!-- 查看当前元素font-size的方法:调试工具->elements->computed->font-size (没找到font-size说明没有设置font-size) -->
</head>
<body>
<div>
<ul>
<li>
<!-- 行内元素 -->
<a>em相对于当前或最近父级已经设置font-size的元素字体大小而言</a>
<!-- 块级元素 -->
<p>em相对于当前或最近父级已经设置font-size的元素字体大小而言</p>
<!-- 行内块元素 -->
<input value="em相对于当前或最近父级已经设置font-size的元素字体大小而言"></input>
<!-- 带默认字体大小的块级元素 -->
<h2>em相对于当前或最近父级已经设置font-size的元素字体大小而言</h2>
</li>
</ul>
</div>
</body>
</html>
情况一结论:
(1)a标签,1em等于16px,参考根元素
但是这里有个问题,当我审查元素的时候,发现a标签的宽度,实际上不等于320px 。这是为啥,明明设置了宽度,却好像没有生效。
原因很简单,a是行内元素,行内元素不能设置宽高。
(2)p标签,1em等于16px。参考根元素
当前元素和父级元素没有设置font-size且字体没有自带font-size时,默认 参考根元素字体大小
(3)input标签,1em等于13px,参考当前元素
因为input标签默认自带字体大小为13px,所以em参考自身(实际审查元素大于266是因为把padding和boder也算进去了)
(4) h2标签,1em等于24px等于1.5 * 16px,参考当前元素
h2标签自带font-size,所以em参考自身font-size(其实h2的font-size也是参考根元素的,如图所示,font-size为1.5的em,所以实际上width = 20 * 16 * 1.5)
情况二:给当前元素设置font-size,查看元素的em
<style>
a {
width: 20em;
font-size: 14px !important;
}
h2 {
width: 20em;
font-size: 14px !important;
}
p {
width: 20em;
font-size: 14px !important;
}
input {
width: 20em;
font-size: 14px !important;
}
</style>
(1)a标签,1em等于14px,参考当前元素
由于是行内元素,设置宽高依然不生效
(2)p标签,1em等于14px。参考当前元素
(3)input标签,1em等于14px,参考当前元素
同样,border和padding占8px,所以会不等于280px
(4) h2标签,1em等于14px,参考当前元素
情况三:给父级元素设置font-size,查看元素的em
<style>
a {
width: 20em;
}
h2 {
width: 20em;
}
p {
width: 20em;
}
input {
width: 20em;
}
</style>
<ul style="font-size: 16px;">
<li style="font-size: 15px;">
<!-- 行内元素 -->
<a>em相对于当前或最近父级已经设置font-size的元素字体大小而言</a>
<!-- 块级元素 -->
<p>em相对于当前或最近父级已经设置font-size的元素字体大小而言</p>
<!-- 行内块元素 -->
<input value="em相对于当前或最近父级已经设置font-size的元素字体大小而言"></input>
<!-- 带默认字体大小的块级元素 -->
<h2>em相对于当前或最近父级已经设置font-size的元素字体大小而言</h2>
</li>
</ul>
(1)a标签,1em等于15px,参考最近父元素
(2)p标签,1em等于15px。参考最近父元素
(3)input标签,1em等于13.3333px,参考当前元素
当父级和当前元素都设置了font-size的时候,优先参考当前元素的字体大小
(4) h2标签,1em等于22.5px,参考当前元素
这个h2就比较有意思了,虽然它也自带font-size,但是它的font-size并不像input一样是个px死值,而是em。由于我给h2的父元素设置了font-size为15px,所以h2的em参考15px,即font-size为15*1.5=22.5px,因此width = 20em = 20 * 22.5 = 450px
特殊情况:设置的font-size小于浏览器最小字体大小时
<ul style="font-size: 16px;">
<li style="font-size: 10px;">
<!-- 行内元素 -->
<a>em相对于当前或最近父级已经设置font-size的元素字体大小而言</a>
<!-- 块级元素 -->
<p>em相对于当前或最近父级已经设置font-size的元素字体大小而言</p>
<!-- 行内块元素 -->
<input value="em相对于当前或最近父级已经设置font-size的元素字体大小而言"></input>
<!-- 带默认字体大小的块级元素 -->
<h2>em相对于当前或最近父级已经设置font-size的元素字体大小而言</h2>
</li>
</ul>
(1)a标签,1em等于10px,参考最近父元素
虽然调试工具中查看a标签font-size是12px,且页面上显示大小也为12px,但em还是参考我们手动设置的10px为准
(2)p标签,1em等于10px。参考最近父元素
同a标签,在本身未设置font-size时,参考最近父元素的font-size,哪怕父元素设置的font-size小于浏览器最小字体大小12px,也要以父元素的为准(不过显示在浏览器中的效果仍然以12px为准)
(3)input标签,1em等于13.3333px,参考当前元素
input还是老样子,以自身默认的字体大小为准
(4) h2标签,1em等于15px,参考当前元素
h2是个很有意思的标签,首先它自带有一个font-size,而这个font-size是一个相对单位em,为1.5em,如果父级元素没有设置font-size,那么这个1.5em默认为1.5*16 = 24px。但我这里设置了父级元素为10px,所以1.5em = 15px,故width = 20 em = 20 * 15px = 300px
小结一下:
- px是绝对单位,代表逻辑像素,与电脑的显示器分辨率有关,不同电脑上的1px呈现效果可能不一样。
- em是相对单位,相对于已有font-size的当前元素或最近的父级元素而言。如果都没有设置font-size,则相对于root(根元素)而言,此时em和rem其实是一样的。
- rem是相对单位,相对于根标签的字体大小而言。使用rem可以更好的进行移动端页面适配。
参考文献:
CSS 中的像素(px)_居十四的博客
设备像素比(devicePixelRatio)
移动端开发-为什么需要“(二倍图,三倍图,四倍图)图解”