TailwindCSS 3 类不会覆盖以前的类

我面临着一个在 CSS 世界中令人麻木的问题。 TailwindCSS 3 类只是不会覆盖以前的类。

例如,有这个组件,我创建了:

import * as React from "react";

const TextBox = ({ addClassName, children }) => {
  const className = `text-xl leading-7.5 font-lato font-normal ${addClassName}`;
  return <div className={className}>{children}</div>;
};

export default TextBox;

然后我继续在另一个地方使用上面的这个组件,如下所示:

<TextBox addClassName="text-4xl">My New Text</TextBox>

现在,当我在浏览器中检查它时,它显示了两个字体大小: Screenshot from the browser inspect

class="text-xl leading-7.5 font-lato font-normal text-4xl"

正如您所看到的,这两个类都存在,都指的是字体大小,并且较大的类在之后较小的类。

并且仍然小(原始)字体大小将占主导地位。

(作为旁注,我确实尝试将 addClassName 变量也放在前面,没有帮助)

为什么是这样?

我很感激任何帮助。谢谢

stack overflow TailwindCSS 3 classes doesn't override previous classes
原文答案

答案:

作者头像

我从 dev.to 中找到了答案。您的代码不起作用的原因是:

原来,class HTML 属性接受的空格分隔的 CSS 类列表在浏览器计算 CSS 规则优先级时并没有被当做列表。 class 属性实际上包含元素具有的类集,因此顺序无关紧要。

由于类出现在 class 属性中的顺序无关紧要,CSS 样式表中稍后出现的规则胜出。

此外,不保证 'text-4xl' 是在 CSS 样式表中的 'text-xl' 之后定义的。

所以为了解决这个问题,我推荐使用 tailwind-merge 覆盖以前的类。

Tailwind-merge 是一个实用功能,可以在 JS 中高效合并 Tailwind CSS 类而不会出现样式冲突。

它的特点之一是:最后一个冲突的班级获胜

twMerge('p-5 p-2 p-4') // → 'p-4'

作者头像

引自 redit

在 CSS 中,如果你有两个具有相同特性的选择器,那么在 CSS 结构中最后的一个优先。类属性中的顺序没有影响。

建议的解决方案是在 tailwindcss import 语句之后编写自己的类,或使用内联样式对其进行编辑。

我的个人提示:不要使用针对相同 css 属性的两个类text-lgtext-4xg 都针对 font-size ,您需要一种方法(建议 clsx lib)只放置一个类名而不是另一个

import clsx from 'clsx';

let condition = false;

function Component(){

  return (
    <div>
     <p className={clsx({
       "text-lg": condition,
       "text-4xl": !condition,
     })}>
     ...
     </p>
    </div>
  );
}
作者头像

我建议您尝试使用 clsxclsssnames 以更好地使用顺风类而不是字符串插值

作者头像

我找到了一个解决方案。在原始组件中设置 props 与默认 CSS 值,然后在使用上述组件时,如果我们需要不同的样式,我们只是在 props 中给出。

作者头像

超级最小覆盖解决方案

// tailwindMerge(defaultClasses, overrideClasses)
tailwindMerge('bg-slate-100 flex-1', 'bg-red-200')
// >> 'bg-red-200 flex-1'

这适用于 v3.2.4 及更高版本。我这样做是因为考虑到 [the setting]-[the value] 的模式也可以与伪选择器一起使用,它看起来很简单。

const normalize = (str) => str.replace(/n+/gi, '').trim()

const makeMap = (val) => {
  const vals = normalize(val).split(/s+/)
  return vals.reduce((obj, item) => ({...obj, [item.split('-')[0]]: item}), {})
}

const tailwindMerge = (defaultVal, overrideVal) => {
  return Object.values({ ...makeMap(defaultVal), ...makeMap(overrideVal) }).join(' ')
}

console.log(tailwindMerge('bg-red-100 text-blue-200 flex-1', 'bg-slate-200'))