伪元素::before不能自动选中首字,必须手动或用JS将首字包裹在独立标签中再样式化;正确做法是直接对包裹首字的span设置float、font-size、line-height等CSS实现首字下沉。
::before能给首字加样式,但不能直接选中“第一个字”浏览器不提供::first-character这种选择器,::before本身也不识别文本内容——它只能挂载在某个已有元素上,然后插入内容。所以想让“文章开头那个字”变大变色,必须先确保那个字被一个独立的标签包裹,比如<span class="dropcap">文</span>,再对这个span用::before就毫无意义;真正该用的,是直接对这个span本身设置样式。
常见错误现象:p::before { content: "文"; font-size: 3em; }——这会把“文”插在段落最前面,覆盖原文首字,导致重复显示。
<span class="first-letter"></span>
<script>、<pre>等非文本容器content属性在::before里只接受字符串、计数器或attr(),不能引用文本节点有人试过p::before { content: attr(data-first-char); },指望从<p data-first-char="文">文字内容...</p>里读取,这确实可行,但前提是你要自己提前把首字塞进data-属性——::before不会自动帮你提取。
content: "W" → 静态字符,适合固定标题content: attr(data-dropcap) → 需 HTML 中显式写<p data-dropcap="W">
content: open-quote或counter() → 和首字排版无关,别混用float + line-height + margin
光靠::before插内容远远不够,视觉上要“下沉”,得靠浮动和行高配合。现代方案倾向用float: left,而不是display: inline-block——后者容易破坏基线对齐,尤其在不同字体下表现不稳定。
立即学习“前端免费学习笔记(深入)”;
span.first-letter { float: left; font-size: 3.5em; line-height: 0.8; margin-right: 0.2em; margin-top: 0.15em;}
line-height: 0.8压缩首字自身行高,避免撑开第一行margin-top微调垂直位置,弥补不同字体的上升部(ascent)差异font-weight: bold或指定字体,否则小字号衬线体可能看不清vertical-align,它对float元素无效em单位比px更可靠,但需重设断点处的line-height
用em写font-size和margin能随父级缩放,但line-height是相对当前字体大小计算的,小屏下line-height: 0.8可能导致首字和第二行文字粘连。
@media (max-width: 768px)里把line-height提到1.0或1.1
font-size可降到2.8em,但别用rem——它基于根字体,会脱离段落上下文float + inline混合布局偶有重绘异常,加transform: translateZ(0)可缓解真正麻烦的是中文字体:没有统一的 x-height 或 ascent 值,同一套 CSS 在“思源宋体”和“霞鹜文楷”里下沉位置可能差两像素——得为关键字体单独微调margin-top。