今天早些时候那篇《给博客做了一轮系统性的 SEO 优化》发出去,我自己从头读了一遍。

内容没看出什么问题,倒是眼睛一直被同一个地方绊住:文章里的小标题下面,压着一条淡蓝色的圆角条,位置偏高、又厚,把汉字的下半截盖住了。

像有人拿荧光笔在标题中间横着划了一道,还没划准位置。

文章正文中的小标题,下方的淡蓝色高亮条压住了文字下半部分
文章里小标题现在的样子:一条半透明的蓝色色带压在字的下半截上。

先排除掉"是我自己改坏的"

这站我动过的地方不少,第一反应是某次顺手改样式时留下的手尾。

WordPress 里改样式一般就那么几个去处:主题设置里的自定义 CSS、后台「外观 → 自定义 → 额外 CSS」、还有子主题的样式文件。前两个都存在数据库里,查一下就知道。

结果两个都是空的

那就不用往自己身上找了——这是主题原版自带的样子。

把生效的那条规则捞出来

Sakurairo 的样式不是一个静态的 CSS 文件。页面上引用的地址长这样:

/wp-content/themes/Sakurairo/css/?sakura_header&sakura&no_wave&minify&3.0.10

后面挂着一串参数,样式是 PHP 现场拼出来再输出的。想看清它到底长什么样,只能把这条地址整个抓下来——一百五十多 KB 的压缩 CSS。

在里面搜 H2,找到这么两条:

.entry-content h2 {
  position: relative;
  display: inline-block;
}

.entry-content h2:after {
  content: '';
  position: absolute;
  bottom: -2px;
  left: 30%;
  right: 0;
  width: 70%;
  height: 0.7em;
  background-color: var(--article-theme-highlight, var(--theme-skin-matching));
  opacity: 0.4;
  z-index: 0;
  border-radius: 30px;
  transition: all 0.3s ease;
}

看到 background-color 那一行就明白了:这压根不是下划线,是主题做的「荧光笔高亮」。

一条半透明的圆角色带,从标题的 30% 处起、横跨 70% 宽度,划过文字的下半部分。设计意图是像马克笔刷过一道——不少主题都这么干。

那它为什么在我这儿变成了"压在字上"?

三个参数叠在一起才出的问题

把这条规则拆开,问题集中在三行:

属性管什么
height0.7em条有多厚
bottom-2px条落在哪
z-index0条和文字谁在上面

先说 height 单位是 em,这是个相对单位,跟着字号走。也就是说条的高度永远是字号的 70%。字号小的时候看着正好,字号一大就失控——标题本来就比正文大,占的高度自然成比例地长。

再说 bottom: -2px 条的底边落在标题盒子底部往下 2px 的位置。听起来是"贴着底"的,但条本身有 0.7em 高,它是从底部往上长的。往上长 0.7em 是什么概念?汉字在 em 盒子里差不多占满,所以这条已经盖到汉字高度的七成位置了。

最后是 z-index: 0,这是挡字的直接原因。 色带是 ::after 伪元素画的,而伪元素在 DOM 顺序上排在文字后面。同层级的元素里,后面的盖前面的——所以这条 40% 透明度的色带,确确实实压在笔画上。透明度又不够让笔画清晰透出来,字就糊了。

浏览器开发者工具里,H2 元素的 ::after 伪元素样式规则
开发者工具 Styles 面板里展开的 .entry-content h2:after 规则,height、bottom、z-index 三行就是问题所在。

三个参数单看都说得通,凑一起就成了"又粗又高还挡字"。

手上只有一张截图时,怎么验证

规则找到了,但还有个问题:我怎么确定页面上生效的就是这一条? 主题 CSS 里同时存在多条 H2 相关规则,说不定哪条被别的覆盖了、真正起作用的是另一条。

常规做法是打开开发者工具看 computed 值。不过我手上正好有那张问题截图,就先拿它做了个粗验。

方法很笨——量比例

汉字在 em 盒子里基本是占满的,所以:

汉字全高 ≈ 1em(也就是字号)

那么在截图里量两个数:

  • 蓝色色带的像素高度
  • 汉字的像素高度

两者相除,就该等于那条规则里的 height 值。

我量出来是 0.69

0.7em。对上了。

顺带把字号也反推了出来:色带实测像素高 17px,除以 0.7 约等于 24px —— 和开发者工具 computed 面板里显示的 font-size: 24px 一致。

用截图工具量出蓝色色带高度与汉字高度的比例
在截图里量出来的比例是 0.69,与 CSS 里的 0.7em 吻合。

这个方法粗糙,但它能回答一个关键问题:我找到的这条规则,就是页面上真正生效的那条——而不是某条早就被覆盖掉的死代码。

动手改,连踩三个坑

方向很清楚:把条改薄,同时垫到文字下面去。

想法很直接,加几行覆盖掉原规则:

.entry-content h2:after {
  height: 0.34em;
  opacity: 0.5;
  z-index: -1;
}

刷新——色带不见了。

坑一:z-index: -1 跑到背景后面去了

z-index: -1 的意思是"排在我所在的那个层叠上下文的最底层"。注意这个限定语:它得有个边界

往上找边界:.entry-contentposition: relative,但没有 z-index

而 CSS 里的规则是:position: relative 搭配 z-index: auto不构成层叠上下文

所以这个 -1 不会停在文章区域内,它会一路往上穿,穿到页面背景之后。

色带没消失,只是跑到访客看不见的地方去了。

修法也简单,给标题自己一个层叠上下文就行:

.entry-content h2 {
  z-index: 0;
}

有了这一行,-1 就有了边界——它只能在标题内部往下沉,落到文字后面,而不是整个页面的后面。

坑二:鼠标一悬停,线会跳一下

主题里还有一条配套规则:

.entry-content h2:hover:after {
  width: 85%;
  left: 15%;
  opacity: 0.7;
}

意思是鼠标移上去时,色带往左拉长一点、颜色深一点。这是原本的交互设计。

我一开始只覆盖了基础规则,结果鼠标一放上去,线会突然往左跳一截

问题出在优先级。CSS 选择器的权重是按「类 / 属性 / 伪类」和「元素 / 伪元素」分开计数的:

  • .entry-content h2:after → 一个类 + 一个元素 + 一个伪元素
  • .entry-content h2:hover:after两个类(多一个 :hover)+ 一个元素 + 一个伪元素

:hover 算作伪类,权重更高。所以我写的基础规则,在悬停状态下会被主题那条盖回去,leftwidth 又被改成了 15% / 85%。

要覆盖这类样式,必须连 :hover 那条一起覆盖。

坑三:CSS 填了,但没点「发布」

规则写好,刷新页面——一点变化都没有,色带还是老样子。

排查了一圈才发现,自定义器右上角那个蓝色的「发布」按钮还亮着。WordPress 的自定义器是个实时预览界面:你在里面写的东西会立刻应用到左边的预览窗口,但在点「发布」之前,它不会写进数据库——前台自然也不会有。

怎么快速判断是不是这个原因:前台页面按 Ctrl + U 看源码,搜你刚写的那条特征值(比如 0.34em)。搜不到,就是没保存。

这个坑不涉及任何技术,但很容易白费一轮排查——尤其是从"是不是选择器写错了"开始怀疑的时候。

最终的改动

四行,写进后台「外观 → 自定义 → 额外 CSS」:

.entry-content h2 {
  z-index: 0;
}
.entry-content h2::after {
  height: 0.34em;
  opacity: 0.5;
  z-index: -1;
}
.entry-content h2:hover::after {
  width: 85%;
  left: 15%;
  opacity: 0.6;
}
WordPress 后台额外 CSS 输入框里填好的四条规则
写进后台「额外 CSS」的内容。存在数据库里,主题更新不会把它冲掉。

改完的效果:

修改后的小标题,蓝色高亮条变薄并垫在文字下方,不再遮挡文字
改完之后:色带变薄了一半,整体沉到文字下沿,笔画完整可见。

验收

改完不看效果等于没改。我核对了这几项:

  • 标题文字完整可见,下半部分不再被压住
  • 色带高度从 16.8px 降到 8.16px(标题字号 24px,分别乘以 0.7em 和 0.34em)
  • 鼠标悬停时色带正常平滑拉长,没有跳动
  • 移动端一样正常——em 是相对单位,字号变了它自己会等比缩放
修复前后的对比,色带从压住文字的半透明色块变成文字下方的一条细线
同一处小标题的前后对比:上面是修改前,下面是修改后。

小结

问题不大,但这几个坑都挺典型:

  1. 装饰性伪元素的 z-index 容易出问题。 想让它"垫在文字后面",光写 z-index: -1 没用——得先确认父级有没有层叠上下文。没有的话它会一路穿到页面背景后面,看起来就像"元素凭空消失了"。
  2. 覆盖样式要连状态选择器一起覆盖。 :hover:focus:active 这类伪类会抬高权重;只覆盖基础规则,一交互就露馅。
  3. em 是把双刃剑。 它让样式跟着字号走、响应式友好,但也意味着在某个字号下调好的参数,换个字号就变形。主题作者在小字号下定的 0.7em,到了标题这种大字号上就过了。
  4. 「预览」和「保存」是两回事。 自定义器这类所见即所得界面,输入框里的东西默认只活在预览里;不点发布,前台永远看不到。排查"改了没反应",先去页面源码里搜一眼特征值。
  5. 没有开发者工具也能做粗验。 量截图比例是个笨办法,但它能验证"找到的规则是否真的生效",比凭感觉猜强。

最后记一句给自己:改这类样式,改完要把静态、悬停、移动端三个状态都过一遍。 这次三个坑里的两个,恰好都是在"静态看着没问题"之后才暴露出来的。

欢迎来到XiaoZou123,这里是一个电脑极客、数码爱好者网站。我平时喜欢关注数码新闻,研究计算机技术。如果你看我头像觉得我是二次元,那我其实还算不上!
最后更新于 2026-09-13