伪元素不显示主因是content未声明或值为none/normal/unset;必须写content: "",用attr()需属性存在且非空,Unicode需转义,引号不可省略。
伪元素不显示,八成是因为 content 根本没声明,或者写了但值是 none、normal、unset——浏览器直接跳过生成节点,后续所有样式(包括 display、background、position)全失效。
必须显式写:content: ""(空字符串)是最安全的写法;content: " "(一个空格)在部分安卓 WebView 中可能不渲染,不推荐。
attr() 时,确保 HTML 元素真有该属性,且值非空,比如 data-icon="★" 可以,data-icon="" 也行,但 data-icon 缺失就彻底不渲染content: "2192"(4 位十六进制),超 4 位用 content: "{1F60A}",且 CSS 文件必须存为 UTF-8 编码content: →)会导致整条规则被浏览器忽略,DevTools 中该样式会灰掉这时它其实“在”,DevTools 的 Elements 面板能看到 ::before 节点,Computed 里 content 值也对,只是没体积、没颜色、没位置。
最快速验证方式:临时加一句 outline: 1px solid red 或 border: 1px solid red,立刻确认盒子是否生成并定位到预期位置。
::before 默认是 display: inline,此时 width、height、top、left 全部无效——必须显式设 display: block 或 display: inline-block
content: url(),去 Network 面板确认图片请求是否 404 或被 CORS 拦截overflow: hidden,而伪元素靠 position: absolute 移出边界,就会被裁掉color 是否为 transparent,或 background-color 是否和父背景一致position: absolute 的伪元素不是相对于父元素定位的,而是找「最近的已定位祖先」(即 position 为 relative、absolute、fixed 或 sticky 的祖先)。找不到就上溯到 <html>,极易跑出可视区。
position: relative 是最稳妥的做法,哪怕它原本不需要定位z-index 只在定位元素上生效:必须同时有 position(非 static)+ z-index,否则无效transform、filter 或 will-change,会创建新层叠上下文,导致伪元素的 z-index 相对范围变小,容易被盖住<tr>)在 Safari 中无法作为可靠定位上下文,tr::after 会相对整个 <table> 定位,建议改用 <td> 或换用 Grid 布局Android 4.2 WebView 对伪元素解析极严格:不报错,但静默跳过整条规则。常见原因集中在 content 写法、父元素 display 类型和语法兼容性上。
:before,双冒号 ::before 在某些版本中会被忽略inline 元素(如未设 display 的 <span>),需显式设为 display: inline-block 或 display: block
display: block 或 display: inline-block,否则尺寸和定位无效attr() 含连字符的属性名(如 data-icon-name),老 WebView 解析不稳定;改用 data-iconname
-webkit-font-smoothing: optimizeLegibility,它在某些旧安卓上会干扰伪元素文本渲染真正卡住人的地方,往往不是某一条规则写错了,而是 content 值合法但被上游重置覆盖(比如全局 *::before { content: "" } 后又在子选择器里删了 content),或者 DevTools 默认不显示空 content 的伪元素,让人误以为没生效。调试时优先右键元素 → “Force element state” → :before,再看 computed 样式里的 content 最终值。