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

如何让基于Antd的网站适配用户深色模式设置且切换无需刷新?

适配系统深色模式自动切换(无需页面刷新)

要实现跟随系统设置自动切换主题且无需刷新页面,核心是监听系统的颜色模式偏好变化,再同步更新Antd的主题配置:

  • 用window.matchMedia('(prefers-color-scheme: dark)')检测当前系统模式,同时通过addEventListener监听模式切换事件
  • 结合React状态管理与Antd的ConfigProvider,实时更新主题配置

示例代码:

import { useState, useEffect } from 'react';
import { ConfigProvider } from 'antd';
import { darkTheme, lightTheme } from '@ant-design/cssinjs';

function App() {
  const [isDarkMode, setIsDarkMode] = useState(() => {
    // 初始加载时检测系统当前模式
    return window.matchMedia('(prefers-color-scheme: dark)').matches;
  });

  useEffect(() => {
    const mediaQuery = window.matchMedia('(prefers-color-scheme: dark)');
    const handleChange = (e) => {
      setIsDarkMode(e.matches);
    };
    // 添加监听
    mediaQuery.addEventListener('change', handleChange);
    // 清理监听
    return () => mediaQuery.removeEventListener('change', handleChange);
  }, []);

  return (
    <ConfigProvider theme={isDarkMode ? darkTheme : lightTheme}>
      {/* 你的应用内容 */}
    </ConfigProvider>
  );
}

export default App;

如果需要自定义主题,而非使用官方预设的darkTheme/lightTheme,可以通过切换明暗算法实现:

import { useState, useEffect } from 'react';
import { ConfigProvider } from 'antd';
import { theme } from 'antd';
const { defaultAlgorithm, darkAlgorithm } = theme;

function App() {
  const [currentAlgorithm, setCurrentAlgorithm] = useState(() => {
    return window.matchMedia('(prefers-color-scheme: dark)').matches 
      ? darkAlgorithm 
      : defaultAlgorithm;
  });

  useEffect(() => {
    const mediaQuery = window.matchMedia('(prefers-color-scheme: dark)');
    const handleChange = (e) => {
      setCurrentAlgorithm(e.matches ? darkAlgorithm : defaultAlgorithm);
    };
    mediaQuery.addEventListener('change', handleChange);
    return () => mediaQuery.removeEventListener('change', handleChange);
  }, []);

  return (
    <ConfigProvider theme={{ algorithm: currentAlgorithm }}>
      {/* 你的应用内容 */}
    </ConfigProvider>
  );
}
关于Antd 5.x CSS-in-JS下的主题色与@media查询问题

你的部分理解有误,具体说明:

  1. 普通CSS中使用主题色:
    Antd 5.x的主题色默认仅在CSS-in-JS上下文可用,普通CSS无法直接访问,但可以通过注入CSS变量桥接:在ConfigProvider中将主题色挂载到根元素的CSS变量上,之后普通CSS即可引用这些变量。

    示例:

    import { useState, useEffect } from 'react';
    import { ConfigProvider, theme } from 'antd';
    
    function App() {
      const { token } = theme.useToken();
      // 挂载CSS变量到根元素
      useEffect(() => {
        document.documentElement.style.setProperty('--primary-color', token.colorPrimary);
        document.documentElement.style.setProperty('--text-color', token.colorText);
      }, [token]);
    
      return (
        <ConfigProvider>
          {/* 你的应用内容 */}
        </ConfigProvider>
      );
    }
    

    之后在普通CSS中就能使用:

    .custom-btn {
      background-color: var(--primary-color);
      color: var(--text-color);
    }
    
  2. @media查询依然适用:

    • 在CSS-in-JS的样式中,可直接结合@media (prefers-color-scheme: dark)编写适配逻辑,同时还能访问主题token:
      import { css } from '@ant-design/cssinjs';
      
      const customStyle = css(({ token }) => ({
        '.custom-card': {
          backgroundColor: token.colorBgContainer,
          '@media (prefers-color-scheme: dark)': {
            backgroundColor: token.colorBgContainer, // 自动适配深色主题下的token值
          },
        },
      }));
      
    • 普通CSS中的@media查询也完全不受影响,依然可用于编写系统模式适配样式。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.13 00:53:14