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

Tailwind Merge 与 CSS Modules 兼容异常问题求助

问题:Tailwind Merge 与 CSS Modules @apply 样式不兼容

在Next.js项目中使用Tailwind CSS时,尝试通过Tailwind Merge处理组件样式优先级,但发现当CSS Modules中用@apply整合Tailwind类时,Tailwind Merge无法正确合并样式,导致传入的自定义className无法覆盖组件默认样式。


解决方案

方案1:用原生Tailwind类替代CSS Modules @apply

直接在组件内定义默认样式映射,让Tailwind Merge能识别所有原生Tailwind类,正确处理优先级:

import type { FC, PropsWithChildren } from 'react';
import type { TextProps } from './props';
import { twMerge } from "tailwind-merge";

// 定义默认样式映射
const variantStyles = {
  h1: 'text-6xl font-semibold text-text-hover sm:text-2xl',
  h2: 'text-4xl font-semibold text-text-hover sm:text-xl',
  h3: 'text-3xl font-semibold sm:text-base',
  h4: 'text-xl font-semibold',
  h5: 'text-lg font-semibold',
  h6: 'text-base font-semibold',
  p: 'text-base text-text-main',
  span: 'text-base text-text-main',
};

const colorStyles = {
  primary: 'text-primary-main',
  text: 'text-text-main',
};

const Text: FC<PropsWithChildren & TextProps> = ({
  color,
  variant = 'p',
  className,
  children,
}) => {
  const HTMLTAG = variant;
  return (
    <HTMLTAG
      className={twMerge(variantStyles[variant], color && colorStyles[color], className)}
    >
      {children}
    </HTMLTAG>
  );
};

export default Text;

此方案可直接删除原styles.module.scss文件,避免CSS Modules与Tailwind Merge的兼容性问题。


方案2:扩展Tailwind Merge配置识别CSS Modules类

若必须保留CSS Modules,可通过自定义Tailwind Merge配置,映射CSS Modules类到对应的Tailwind规则:

  1. 创建自定义merge函数:
import { extendTailwindMerge } from 'tailwind-merge';

const customTwMerge = extendTailwindMerge({
  extend: {
    classGroups: {
      'text-size': [
        { 'h1': ['text-6xl', 'sm:text-2xl'] },
        { 'h2': ['text-4xl', 'sm:text-xl'] },
        { 'h3': ['text-3xl', 'sm:text-base'] },
        { 'h4': ['text-xl'] },
        { 'h5': ['text-lg'] },
        { 'h6': ['text-base'] },
        { 'p': ['text-base'] },
        { 'span': ['text-base'] },
      ],
      'text-color': [
        { 'primary': ['text-primary-main'] },
        { 'text': ['text-text-main'] },
        { 'h1': ['text-text-hover'] },
        { 'h2': ['text-text-hover'] },
      ],
      'font-weight': [
        { 'h1': ['font-semibold'] },
        { 'h2': ['font-semibold'] },
        { 'h3': ['font-semibold'] },
        { 'h4': ['font-semibold'] },
        { 'h5': ['font-semibold'] },
        { 'h6': ['font-semibold'] },
      ],
    },
  },
});

export default customTwMerge;
  1. 在组件中使用自定义merge函数:
import classes from './styles.module.scss';
import type { FC, PropsWithChildren } from 'react';
import type { TextProps } from './props';
import customTwMerge from './customTwMerge';

const Text: FC<PropsWithChildren & TextProps> = ({
  color,
  variant = 'p',
  className,
  children,
}) => {
  const HTMLTAG = variant;
  return (
    <HTMLTAG
      className={customTwMerge(`${classes[variant]} ${classes[color || '']}`, className)}
    >
      {children}
    </HTMLTAG>
  );
};

export default Text;

需手动维护CSS Modules类与Tailwind类的映射,适合必须保留CSS Modules的场景。


方案3:降低CSS Modules样式优先级

利用:where()伪类降低CSS Modules样式的优先级,让传入的className自然覆盖默认样式:

修改styles.module.scss:

:where(.h1) {
    @apply text-6xl font-semibold text-text-hover sm:text-2xl;
}

:where(.h2) {
    @apply text-4xl font-semibold text-text-hover sm:text-xl;
}

:where(.h3) {
    @apply text-3xl font-semibold sm:text-base;
}

:where(.h4) {
    @apply text-xl font-semibold;
}

:where(.h5) {
    @apply text-lg font-semibold;
}

:where(.h6) {
    @apply text-base font-semibold;
}

:where(.p),
:where(.span) {
    @apply text-base text-text-main;
}

:where(.primary){
    @apply text-primary-main;
}

:where(.text) {
    @apply text-text-main;
}

:where()会将选择器优先级降至0,传入的Tailwind类(优先级为1)可直接覆盖,组件代码无需修改。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.27 05:44:55