如何使用普通 CSS 类名覆盖 Chakra UI(或 Emotion CSS-in-JS)样式?

sga*_*dev 5 css emotion reactjs webpack chakra-ui

问题

我编写的任何 CSS 类名都不会覆盖 Chakra UI 组件样式,即使将它们直接作为类名传递,例如:<Button className="my-class-that-wont-work">

复制步骤

我使用他们的CRA 指南创建了一个简单的新 Chakra-UI 项目

npx create-react-app my-app --template @chakra-ui
Run Code Online (Sandbox Code Playgroud)

我继续添加一个文件并使用简单的类名将index.css其导入src/index.js(或):src/App.jsx

npx create-react-app my-app --template @chakra-ui
Run Code Online (Sandbox Code Playgroud)

但是,当我尝试使用 CSS 类覆盖任何 Chakra UI 的组件样式时,CSS 类样式会被 Chakra 的样式覆盖。这是一个简单的例子,试图使模态页脚具有弹性+空间,以便按钮展开。

<ModalFooter className="my-class-name">
Run Code Online (Sandbox Code Playgroud)

开发工具截图

这似乎是因为 Chakra UI在运行时<style>末尾使用标签注入由 Emotion CSS-in-JS 生成的 CSS <head>,这使得 Chakra 组件 CSS 有权覆盖 JSX 组件中导入的自定义 CSSimport "./index.css";

Chakra UI CSS 加载顺序

我的问题

有没有什么方法可以强制 Chakra UI CSS 在运行时在元素中提前加载,<head>以便我能够使用普通 CSS 类覆盖它?

实现这一点不仅可以让我更轻松地在现有代码库中实现 Chakra UI,还可以让像 Tailwind CSS 这样依赖实用程序类的框架正常工作。

编辑:似乎为了响应这个特定问题,Emotion 添加了对“prepend”标志的支持,该标志允许在注入样式的所选 DOM 元素的开头而不是末尾添加样式标签。这似乎是这个问题的完美解决方案,但我不知道如何将其传递到 Chakra UI

sga*_*dev 6

由于 Chakra UI 使用Emotion CSS作为开箱即用的样式解决方案,因此我能够按照此线程使用 Emotion 的CacheProvider<head>来提前加载 Chakra UI样式,而不是最后加载;

import createCache from '@emotion/cache';
import { CacheProvider } from '@emotion/react';
import { ChakraProvider } from '@chakra-ui/react';

const emotionCache = createCache({
  key: 'emotion-css-cache',
  prepend: true, // ensures styles are prepended to the <head>, instead of appended
});

export default function App() {
  return (
    <CacheProvider value={emotionCache}>
      <ChakraProvider>
      </ChakraProvider>
    </CacheProvider>
  );
}
Run Code Online (Sandbox Code Playgroud)

这解决了我的问题,但我不确定这个解决方案有多强大,因为 Chakra UI 文档没有正式记录它。现在暂时保留问题,以防有人对如何实现这一点有更好的想法。