踩坑:font-family 和 em 单位实际渲染尺寸的关联
字体对渲染尺寸的影响
即使 font-size: 16px 固定不变,不同字体的视觉渲染高度完全不同:
css
/* 都是 16px,但实际渲染高度不同 */
font-family: Arial; /* 可能渲染为 14.2px 高 */
font-family: "PingFang SC"; /* 可能渲染为 15.8px 高 */
font-family: Helvetica; /* 可能渲染为 13.9px 高 */
这会导致:
- line-height 计算不同
- 垂直对齐偏移
- 整体布局微调
表单元素的字体继承问题
css
/* 浏览器默认行为 */
button {
font-family: system-ui; /* 不继承父元素 */
}
input {
font-family: system-ui; /* 不继承父元素 */
}
textarea {
font-family: monospace; /* 不继承父元素 */
}
/* 现代项目的标准做法 */
button,
input,
textarea {
font: inherit; /* 强制继承父元素的所有字体属性 */
}
rem 的特性
rem 是相对于根元素(<html>
)的 font-size 来计算的
css
html {
font-size: 16px;
}
.element {
width: 2rem; /* 永远是 32px (16px × 2) */
height: 1rem; /* 永远是 16px (16px × 1) */
}
为什么 rem 不受字体影响?
css
/* 场景1:使用 Arial 字体 */
html {
font-size: 16px;
}
body {
font-family: Arial;
}
.element {
width: 2rem; /* = 32px */
}
/* 场景2:切换到 PingFang SC 字体 */
html {
font-size: 16px; /* 根元素的 font-size 没变 */
}
body {
font-family: "PingFang SC";
}
.element {
width: 2rem; /* 还是 = 32px */
}
关键:rem 只看根元素的 font-size,不关心当前元素使用什么字体。
对比三种单位
css
/* 假设根元素 font-size: 16px,当前元素 font-size: 18px */
.element {
width: 2px; /* 绝对单位,永远 2px */
height: 2rem; /* 相对根元素,永远 32px (16×2) */
padding: 2em; /* 相对当前元素,36px (18×2) */
}
/* 当字体从 Arial 切换到 PingFang SC */
/* px: 不变 */
/* rem: 不变(除非根元素 font-size 改变) */
/* em: 可能变化(如果当前元素的实际渲染字体大小受影响) */
结论
- px:完全不受字体影响 ✅
- rem:不受字体影响,只受根元素 font-size 影响 ✅
- em:会受字体影响,因为依赖当前元素的字体渲染 ❌
所以如果你想避免字体切换导致的尺寸问题,rem 是一个很好的选择!