直接写 ::first-letter 无法让中文首字下沉,因为该伪元素只匹配 unicode 字母类(l)和数字类(n)字符,而汉字属于“其他字母(lo)”,chrome、firefox、safari 均不识别。

为什么直接写 ::first-letter 无法让中文首字下沉
因为浏览器规范里 ::first-letter 只匹配 Unicode 字母类(L)和数字类(N)字符,而汉字属于“其他字母(Lo)”,Chrome、Firefox、Safari 全都不识别。你写了 p::first-letter { font-family: "Ma Shan Zheng"; },DevTools 里根本看不到 computed 样式——不是字体没加载,是伪元素压根没生成。
中文复古排版必须手动包裹首字
国风或复古风格讲究首字下沉+书法字体+衬线强化,可控性远比依赖伪元素重要。实际做法是把首个汉字单独用 <span class="lead-char"></span> 包起来:
- 服务端渲染时用正则提取首个
/[\u4e00-\u9fa5]/并包裹(避免前端 JS 闪动) - 若必须前端处理,用
document.querySelectorAll('p')遍历,对每个段落取textContent.trim()[0],再用replace()替换为带<span></span>的结构 - 注意跳过开头标点:用
/^[\u3000-\u303f\uf900-\uf9fc\uff00-\uffef\u2000-\u206f\uff01-\uff5e]+/匹配并移除前缀
::first-letter 在英文段落中实现真正下沉的三要素
哪怕只用于英文,::first-letter 也不只是放大字号。要形成视觉下沉,必须同时满足:
-
float: left:唯一能触发文字环绕的属性,缺了它后续文字不会绕排 -
line-height: 0.75(无单位):必须显式设,不能继承父级;数值低于 0.6 易截顶,高于 0.9 容易顶开第二行 -
font-size: clamp(2rem, 4vw, 3.5rem):响应式更安全,固定值至少用2.5em,2em在多数中文字体下几乎看不出下沉感
额外建议:margin-right: 0.2em 控制间距比空格稳定;display: block 在 Safari 下可减少浮动抖动。
中文首字下沉最容易被忽略的兼容细节
中文没有 ascender/descender 基线,不同字体上下伸展差异极大:
- 思源宋体、Noto Sans CJK 的字形高度不一致,同一
line-height: 0.8在 A 字体刚好,在 B 字体可能截顶或留白过多 - 不要用
vertical-align调位置——浮动上下文中不可靠;改用margin-top: -0.1em或transform: translateY(-2px) - 如果父容器用了
text-align: justify,手动包裹的<span></span>更可控;initial-letter在此场景下极易断行异常
真正做上线项目时,别赌 initial-letter ——它在 Chrome 需手动开 flag,Safari 16.4+ 才支持,Firefox 完全无视,中文渲染还常选错字符。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











