Skip to content

踩坑: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 是一个很好的选择!

Release time: 6/15/2024, 10:33:00

Last updated:

⟣ Growing, with you. ⟢