You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用Emotion时:first-child报错且替换为:first-of-type不符合需求如何解决?

问题原因解析

为什么Emotion会触发:first-child警告

Emotion的该报错是为了规避SSR(服务端渲染)场景下的hydrate不匹配问题:如果组件在服务端渲染和客户端注水时的子元素数量、顺序存在差异,:first-child这类和子元素位置强绑定的伪类会出现两端匹配结果不一致的问题,因此Emotion默认会对这类选择器做安全提醒。

为什么:first-of-type达不到预期效果

:first-of-type的匹配规则是按标签类型匹配同类型下的第一个子元素,你的DOM结构中存在span和div两种标签:

  • 第一个span(类名one)是span类型的首个元素
  • 第一个div(类名two)是div类型的首个元素
    因此*:not(:first-of-type)会同时排除这两个元素,只有第三个的span(类名three)和第四个的div(类名four)会命中样式,和你想要的「排除所有子元素中的第一个,其余全部变红」的需求不符。
解决方案

方案1:使用* + *相邻兄弟选择器(最优解)

该选择器的匹配规则是「匹配所有前面存在相邻兄弟元素的子元素」,效果和你原来写的:not(:first-child)完全一致,且不会触发Emotion的SSR安全警告:

.parent {
    & > * + * {
        color: red;
    }
}

方案2:临时忽略当前选择器的警告

如果你能100%确认当前父组件的子元素结构在服务端和客户端完全一致,没有动态插入/删除子元素的逻辑,可以加特殊注释关闭当前行的警告:

.parent {
    /* emotion-disable-server-rendering-unsafe-selector-warning */
    & > *:not(:first-child) {
        color: red;
    }
}

方案3:手动给首个子元素加专属类名

如果可以控制子元素的渲染逻辑,直接给第一个子元素加专属类名匹配,完全规避位置类伪类的风险:

<div class="parent">
    <span class="one first-child">1</span>
    <div class="two">2</div>
    <span class="three">3</span>
    <div class="four">4</div>
</div>

对应样式:

.parent {
    & > *:not(.first-child) {
        color: red;
    }
}

内容的提问来源于stack exchange,提问作者Chilyan

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.26 14:45:03