如果在 className 中使用变量,React/Next.js 中的 Tailwind 不会为 text-*xl 类 生成 css

Tailwind in React/Next.js doesn't generate css for text-*xl classes if variable is used in className

我想使用 Tailwind 创建 React Title 组件,您可以在其中传递级别(H1-H6 或如果为空则设为 DIV)并传递大小(text-xl 为 1-9 至text-9xl).

例如,我可以有这样的可重用组件:

// Reusable component:
<Title level={2} size={4}>Test title</Title>
// Which renders to:
<h2 className="text-4xl">Test title</h2>

我可以在 Inspector 中看到那些 类,我还可以看到没有为项目生成 .font-4xl css。所以标题保持默认 font-size。 但是,如果我添加 <div class="text-4xl">test</div> 之类的任何测试文本,那么它将生成 css 并且还将其应用于组件。这可以重复所有 9 种尺寸。

有没有办法让 Tailwind 仅在使用时生成 css(非常适合最小文件大小),同时还为组件提供某种干净的代码?

现在,我的想法是将所有常见的 类 应用到可重复使用的标题组件中,但始终仅在使用时添加所需的大小 (text-*xl)。

const Title = ({ children, className, style, level, size }) => {
  const commonClass = 'font-extrabold uppercase mb-4';

  const fontSize = size ? `text-${size}xl` : `text-${level}xl`;

  switch (level) {
    case 1:
      return (
        <h1 className={`${fontSize} ${commonClass}`} style={style}>
          {children}
        </h1>
      );
    case 2:
      return (
        <h2 className={`${fontSize} ${commonClass}`} style={style}>
          {children}
        </h2>
      );
    case 3:
      return (
        <h3 className={`${fontSize} ${commonClass}`} style={style}>
          {children}
        </h3>
      );
    case 4:
      return (
        <h4 className={`${fontSize} ${commonClass}`} style={style}>
          {children}
        </h4>
      );
    case 5:
      return (
        <h5 className={`${fontSize} ${commonClass}`} style={style}>
          {children}
        </h5>
      );
    case 6:
      return (
        <h6 className={`${fontSize} ${commonClass}`} style={style}>
          {children}
        </h6>
      );
    default:
      return (
        <div className={`${fontSize} ${commonClass}`} style={style}>
          {children}
        </div>
      );
  }
};

export default Title;

来自 JIT mode 关于动态值的 Tailwind 文档

Dynamic values

Note that you still need to write purgeable HTML when using arbitrary values, and your classes need to exist as complete strings for Tailwind to detect them correctly.

Don't use string concatenation to create class names

<div className={`mt-[${size === 'lg' ? '22px' : '17px' }]`}></div>

Tailwind doesn’t include any sort of client-side runtime, so class names need to be statically extractable at build-time, and can’t depend on any sort of arbitrary dynamic values that change on the client. Use inline styles for these situations, or combine Tailwind with a CSS-in-JS library like Emotion if it makes sense for your project

所以你应该使用类似的东西,或者 switchif 语句可以正常工作。

const sizeArg = size ? size : level;
const fontSize = textSize === 1 ? 'text-1xl' : (sizeArg === 2 ? 'text-2xl' : (...))