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

Chakra UI多部分组件子组件__css样式不生效问题

Chakra UI 自定义多部分组件子项样式不生效问题

问题现象

基于 create-react-app 搭建的 TypeScript + React 项目中使用 Chakra UI 开发时,自定义 <Dropdown> 根组件的 CSS 样式可正常应用,但内部 <DropdownItem> 组件配置的样式完全不生效:

  • 代码参考 Chakra UI 官方多部分组件样式配置文档编写,和官方源码中 List 组件的实现逻辑对比无明显异常
  • 项目运行无控制台报错
  • 打印 useStyles()、useMultiStyleConfig() 返回的 CSSDict 样式对象内容正常,初步定位问题出在 __css={styles.item} 的属性传递环节

相关代码

Select.tsx(组件调用处)

<Dropdown onClick={() => setOpen(!open)}>
      <DropdownItem>{currItem}</DropdownItem>
</Dropdown>
const [StylesProvider, useStyles] = createStylesContext("Dropdown");

export function Dropdown(props: any): any {
  const { size, variant, children, ...rest } = props;
  const styles = useMultiStyleConfig("Dropdown", { size, variant });
  return (
    <List __css={styles.dropdown} {...rest}>
      <StylesProvider value={styles}>{children}</StylesProvider>
    </List>
  );
}

export function DropdownItem(props: any): any {
  const styles = useStyles();
  return <ListItem __css={styles.item} {...props} />;
}

theme.ts(全局主题配置)

export const theme = extendTheme({
  components: {
    Button,
    Dropdown,
  },
  colors: {
    main: {
      independence: "#3D405B",
      purplenavy: "#51557A",
      darkbluegray: "#656A99",
      terracotta: "#E07A5F",
      eggshell: "#F4F1DE",
    },
  },
  styles: {
    global: () => ({
      body: {
        bg: "main.independence",
        height: "100%",
      },
    }),
  },
  shadows: {
    terra: "2px -2px #E07A5F",
    eggshell: "2px -2px #F4F1DE",
  },
});
export const Dropdown: ComponentStyleConfig = {
  parts: ["dropdown", "item"],
  // 各部件基础样式
  baseStyle: {
    dropdown: {
      position: "relative",
      display: "inline-block",
      width: "100px",
      cursor: "pointer",
      fontSize: "calc(35px, 0.87vw)",
      h: "100%",
      zIndex: "10",
    },
    item: {
      h: "100%",
      display: "flex",
      justifyContent: "center",
      alignItems: "center",
      _hover: { bg: "main.violetLt", borderRadius: "15px 0 0 15px" },
      fontWeight: "600",
      bg: "orange",
    },
  },
  // 尺寸样式
  sizes: {},
  // 变体样式
  variants: {},
  // 默认参数
  defaultProps: {},
};

排查过程

  • 通过 React Devtools 查看组件树,<List> 对应内部 ListElement 是最后一个能接收到正确 __css 属性的组件,它渲染出的 <li> 真实子节点上 __css 属性直接消失。
  • 将 DropdownItem 内的 <ListItem> 替换为 <chakra.li> 后,__css 属性可正常传递,样式成功应用,但未第一时间定位到该现象的根本原因。

根本原因

问题来自 Chakra UI 内置多部分组件的样式上下文隔离逻辑:

  1. <ListItem> 是官方 List 多部分组件的内置子部件,内部默认绑定 List 组件的独立样式上下文,会优先读取 List 自身 StylesProvider 下的 item 样式,外部传入的 __css 属性会被内部逻辑覆盖。
  2. 自定义 Dropdown 组件通过 createStylesContext 创建了全新的独立样式上下文,<ListItem> 不会读取这个上下文里的 styles.item 配置,最终传入的 __css 在 ListItem 内部被丢弃,没有传递到最终渲染的 DOM 节点。
  3. <chakra.li> 是最基础的 Chakra DOM 包装标签,没有内置多部分组件的上下文读取逻辑,会直接透传并应用传入的 __css 属性,因此替换后样式可正常生效。

修复方案

两种方案均可解决问题,按需选择即可:

  • 方案一:直接将 <ListItem> 替换为 <chakra.li>,脱离 List 组件的内置样式逻辑,现有 __css={styles.item} 写法无需修改即可正常生效,是侵入性最低的方案。
  • 方案二:如果需要保留 <ListItem> 的其他内置特性,将 __css 属性替换为优先级更高的 sx 属性传入,即写成 <ListItem sx={styles.item} {...props} />,sx 属性不会被组件内置样式覆盖。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.27 16:27:47