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

ChakraUI自定义字体无法覆盖默认字体问题求助

Chakra UI 自定义主题字体不生效问题

问题描述

按照Chakra UI自托管字体设置指南完成所有步骤后,Text和Heading组件仍显示默认字体,但自定义颜色(brand.tm)正常生效;且显式设置fontFamily为"Open Sans"、"Raleway"或"Roboto"时字体可正常加载(注释字体包导入则失效)。

已执行步骤

  • 使用npm install @fontsource/open-sans @fontsource/raleway安装字体包
  • 在theme.ts中导入字体包
  • 配置heading和body字体族
  • 将自定义主题传入ChakraProvider

项目环境

  • React + Vite 构建
  • 未使用其他CSS框架

疑问:能否仅通过ChakraProvider和自定义主题配置解决该问题,而非使用“字体包装器”?


相关代码

theme.ts

import '@fontsource/roboto';
import '@fontsource/raleway/400.css';
import '@fontsource/open-sans/700.css';
import { ThemeConfig, extendTheme } from '@chakra-ui/react';

const config: ThemeConfig = {
    initialColorMode: 'dark',
    useSystemColorMode: true,
};

const fonts = {
    heading: `'Open Sans', sans-serif`,
    body: `Raleway, sans-serif`,
};

const colors = {
    brand: {
        tm: 'tomato',
        tl: 'teal',
    },
};

const theme = extendTheme({
    config,
    fonts,
    colors,
});

export default theme;

main.tsx

import React from 'react';
import ReactDOM from 'react-dom/client';
import theme from './theme';
import App from './App.tsx';
import { ToastContainer } from './utils/toastHandler.ts';
import { ChakraProvider, ColorModeScript } from '@chakra-ui/react';
import { BrowserRouter } from 'react-router-dom';

ReactDOM.createRoot(document.getElementById('root') as HTMLElement).render(
    <React.StrictMode>
        <ChakraProvider theme={theme}>
            <BrowserRouter>
                <App />
                <ColorModeScript initialColorMode={theme.config.initialColorMode} />
                <ToastContainer />
            </BrowserRouter>
        </ChakraProvider>
    </React.StrictMode>
);

依赖项

"dependencies": {
    "@chakra-ui/react": "^2.7.0",
    "@emotion/react": "^11.11.0",
    "@emotion/styled": "^11.11.0",
    "@fontsource/open-sans": "^5.0.2",
    "@fontsource/raleway": "^5.0.2",
    "@fontsource/roboto": "^5.0.2",
    "framer-motion": "^10.12.16",
    "react": "^18.2.0",
    "react-dom": "^18.2.0",
    "react-icons": "^4.9.0",
    "react-router-dom": "^6.11.2"
  },
  "devDependencies": {
    "@types/react": "^18.0.28",
    "@types/react-dom": "^18.0.11",
    "@typescript-eslint/eslint-plugin": "^5.57.1",
    "@typescript-eslint/parser": "^5.57.1",
    "@vitejs/plugin-react": "^4.0.0",
    "eslint": "^8.38.0",
    "eslint-plugin-react-hooks": "^4.6.0",
    "eslint-plugin-react-refresh": "^0.3.4",
    "typescript": "^5.0.2",
    "vite": "^4.3.2"
  }

解决方案

问题源于字体导入覆盖不全、字体族格式错误及组件渲染顺序问题,按以下步骤修复即可通过主题配置解决:

1. 补充字体字重导入

当前仅导入了Raleway 400和Open Sans 700,但Chakra UI组件默认会使用多种字重,需补充对应字重的字体文件:

// theme.ts中更新导入
import '@fontsource/roboto';
import '@fontsource/raleway/400.css';
import '@fontsource/raleway/700.css'; // 补充粗体字重
import '@fontsource/open-sans/400.css'; // 补充常规字重
import '@fontsource/open-sans/700.css';

2. 修正字体族引号格式

Raleway作为字体名需添加单引号(统一格式避免潜在问题):

const fonts = {
    heading: `'Open Sans', sans-serif`,
    body: `'Raleway', sans-serif`, // 补全单引号
};

3. 调整ColorModeScript位置

ColorModeScript必须放在ChakraProvider内部最顶层,否则会导致主题样式加载顺序错误:

// main.tsx修正后的渲染结构
ReactDOM.createRoot(document.getElementById('root') as HTMLElement).render(
    <React.StrictMode>
        <ChakraProvider theme={theme}>
            <ColorModeScript initialColorMode={theme.config.initialColorMode} />
            <BrowserRouter>
                <App />
                <ToastContainer />
            </BrowserRouter>
        </ChakraProvider>
    </React.StrictMode>
);

4. 全局强制字体继承(可选)

若以上步骤仍不生效,可在主题中添加全局样式强制所有元素继承主题字体:

// theme.ts中新增styles配置
const styles = {
    global: {
        body: {
            fontFamily: 'body',
        },
        '*': {
            fontFamily: 'inherit',
        },
    },
};

const theme = extendTheme({
    config,
    fonts,
    colors,
    styles, // 加入全局样式配置
});

完成以上调整后,Text和Heading组件会自动应用主题配置的字体,无需额外包装组件。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.19 13:13:15