如何在CSS中分组类 - Tailwind

3
我想将类分组以使代码更清洁易读。在Tailwind的文档中提到了"@apply",可以用于此目的,但我正在使用CDN,因此这对我不起作用。所以我的问题是,有没有什么方法可以实现我想要的效果?也许可以使用SASS/SCSS或LESS?

以下是我想要的示例:

<ul class="md:flex md:items-center z-[-1] md:z-auto md:static absolute bg-gray-800 w-full left-0 md:w-auto md:py-0 py-4 md:pr-0 pr-7 md:pl-0 pl-7 md:opacity-100 opacity-0 top-[-400px] transition-all ease-in duration-200">
  <li class="nav-element">
    <a href="#" class="text-x1 md:hover:text-yellow-300 duration-500">Home</a>
  </li>
  <li class="px-4 py-6 md:py-0 hover:bg-yellow-500 md:hover:bg-transparent text-white duration-500">
    <a href="#" class="text-x1 md:hover:text-yellow-300 duration-500">About Us</a>
  </li>
  <li class="px-4 py-6 md:py-0 hover:bg-yellow-500 md:hover:bg-transparent text-white duration-500">
    <a href="#" class="text-x1 md:hover:text-yellow-300 duration-500">Services</a>
  </li>
  <li class="px-4 py-6 md:py-0 hover:bg-yellow-500 md:hover:bg-transparent text-white duration-500">
    <a href="#" class="text-x1 md:hover:text-yellow-300 duration-500">Contact Us</a>
  </li>
  <button class="md:w-auto w-full bg-transparent text-white font-[Poppins] duration-500 px-6 py-2 hover:bg-white hover:text-gray-800 border border-white border-dotted rounded-lg">
    Log In
  </button>
  <button class="md:w-auto w-full bg-yellow-500 text-white font-[Poppins] duration-500 px-6 py-2 md:mx-4 hover:bg-yellow-600 rounded-lg">
    Sign In
  </button>
</ul>

<ul class="nav-elemnts">
  <li class="nav-element">
    <a href="#" class="nav-link">Home</a>
  </li>
  <li class="nav-element">
    <a href="#" class="nav-link">About Us</a>
  </li>
  <li class="nav-element">
    <a href="#" class="nav-link">Services</a>
  </li>
  <li class="nav-element">
    <a href="#" class="nav-link">Contact Us</a>
  </li>
  <button class="button-login">
    Log In
  </button>
  <button class="button-signin">
    Sign In
  </button>
</ul>
7个回答

6
Tailwind鼓励您使用组件。不要在各处复制粘贴类,而应使用允许您创建和使用组件的系统。
由于您的问题只涉及HTML+CSS,因此您实际上没有正确的工具来执行此操作。但是,如果您使用像JS、Python、PHP等脚本语言,您可以从元素创建组件并重复使用它们。由于我熟悉React框架,我可以展示一个例子:
function NavElement(props) {
  return (
    <li class="px-4 py-6 md:py-0 hover:bg-yellow-500 md:hover:bg-transparent text-white duration-500">
      <a href={props.href} class="text-x1 md:hover:text-yellow-300 duration-500">{props.children}</a>
    </li>
  )
}

然后将其用作

function NavElements() {
  return (
    <ul class="md:flex md:items-center z-[-1] md:z-auto md:static absolute bg-gray-800 w-full left-0 md:w-auto md:py-0 py-4 md:pr-0 pr-7 md:pl-0 pl-7 md:opacity-100 opacity-0 top-[-400px] transition-all ease-in duration-200">
      <NavElement href="/">Home</NavElement>
      <NavElement href="/services">Services</NavElement>
      <NavElement href="/about-us">About us</NavElement>
    </ul>
  )
}

通过这种方法,您可以将大量的修饰符提取到一个小型组件中,使得您可以在代码中多次重复使用而无需重复编写。

您可以自由选择任何工具、语言或系统,以实现组件化。这也是Tailwind所期望的。


2
我明白你想告诉我的,但情况是我想将类分组,然后再按照你说的做。我的意思是,在样式表中有一些类别,每个类别都是Tailwind类别的一组。因此最终我将使用Tailwind创建自定义类别。如果你不理解我在寻找什么,请告诉我,我会尝试改进问题。 - Hello There
2
这不是在Tailwind中应该做的事情。如果你在CSS中分组你的类(即使使用@apply),你基本上回到了普通的CSS - 不得不想出类名,管理选择器等。Tailwind就是为了让你不必这样做。如果你不喜欢它的基本构建块之一 - 使用实用程序令牌,那么请考虑Tailwind可能并不适合你个人使用,这完全没问题,很多人都不喜欢它。 - Jakub Kotrs
所以这不是一个“问题”,如果我有一长串的类也不会有什么问题吗?我对Tailwind还很新,当我开始编码时,我认为这样堆积类并不像“好的做法”。 - Hello There
2
不,这不是问题。如果您必须手动维护它们,那么这可能会成为维护的问题,这就是为什么我们创建小型可重用组件而不是在各处复制粘贴类,但列表本身绝对不是问题。你要么“习惯”它,要么你会不喜欢它,所以主观感受在其中起着很大的作用。 - Jakub Kotrs
谢谢您的帮助,现在我更好地理解如何使用Tailwind以及它的目标。 - Hello There

1

我知道您要求使用SASS/LESS类型的方法,但我认为这会增加您可能不需要的额外复杂性。我认为一些简单的JS将是一个很好的解决方案。

我所做的是用一个类名的JSON对象和一个实用函数来替换CSS或StyledComponents,并将它们转换为一个大字符串。

首先,是这个实用程序。将其放在共享位置:

// turns a JSON object's values into a single string (keys are irrelevant)

export const classify = (classes) => Object.values(classes).join(' ')

那么在与index.js相邻的styles.js文件中,我会有如下内容:

import { classify } from 'shared/utils'

export const nav = classify({
  base: 'absolute bg-gray-800 w-full left-0 pr-7 pl-7 py-4 opacity-0 top-[-400px] z-[-1]',
  animation: 'transition-all ease-in duration-200',
  larger: 'md:flex md:items-center md:z-auto md:static md:w-auto md:py-0  md:pr-0 md:pl-0 md:opacity-100'
})

export const navItem = classify({
  base: 'px-4 py-6 hover:bg-yellow-500 text-white',
  resp: 'md:py-0 md:hover:bg-transparent',
  anim: 'duration-500'
})

这就像你的CSS文件一样。是的,你必须给变量命名,但是如果用另一种方式,你也必须给组件命名,而这种方式可以使文件少得多。你还可以看到你的HTML结构,而不是一堆组件名称(它们很可能只是divs)。此外,你可以在你的JSON中有任意数量的键值,以任何你认为合适的方式进行组织,以减轻认知负荷。

然后,是HTML/JSX代码:

import * as styles from './styles'

export default Component = (props) => (
  <ul className={styles.nav}>
    <li className={styles.navItem}> ... </li>
    <li className={styles.navItem}> ... </li>
    <li className={styles.navItem}> ... </li>
  </ul>
)

我喜欢这种方法的原因是它非常类似于CSS的工作流程,而JSON对象允许您以任何想要的方式组织您的类名(最好不要嵌套,否则您将需要更复杂的classify())。使用组件,您仍然需要处理大量的长字符串,当应用了数十个类时会很烦人。您甚至可以在同一个文件中完成这些操作,因为它只是JavaScript。
您甚至可以通过模板字符串创建实用的样式/类,并将它们与其他内容连接起来:
import * as utilStyles from 'utils/styles'
import * as styles from './styles'

<section className={`${utilStyles.shadowPanel} ${styles.mainSection}`>
...
</section>

1

我理解当你阅读长串的CSS类和重复将它们写入某些组件时的头痛。

感谢TailwindCSS有一种方法来组织组件的类别,使您可以重用CSS类。以下是方法:

创建名为main.css的文件。

    @tailwind base;
    @tailwind components;
    @tailwind utilities;
    
    @layer components {
      .card {
        background-color: theme('colors.white');
        border-radius: theme('borderRadius.lg');
        padding: theme('spacing.6');
        box-shadow: theme('boxShadow.xl');
      }
      /* ... */
    }

然后,您可以在组件中使用它:

<!-- Will look like a card, but with square corners -->
<div class="card rounded-none">
  <!-- ... -->
</div>

官方文档:link 优秀的文章描述了它:link

0

你尝试过这样做吗:

<style type="text/tailwindcss">
    @layer components {
      .some-class {
        @apply px-4 py-6 md:py-0 hover:bg-yellow-500 md:hover:bg-transparent text-white duration-500;
      }
    }
</style>

我尝试了一下,vs code 给我显示了这个警告:“Unknown at rule @layercss(unknownAtRules)”,并且它没有将任何东西应用到具有我所建立的类的元素上。 - Hello There

0

有两种方法可以对Tailwind类进行分组。一种是使用Node.js,另一种是不使用Node.js,即使用CDN。使用脚本非常简单,您只需创建一个包含多个Tailwind类的变量,并将其插入DOM中。

您可以使用Vanilla JS对这些类进行分组并应用于DOM。按照以下示例,在HTML代码末尾插入脚本即可。

<body>
<ul class="nav-elemnts">
  <li class="nav-element">
    <a href="#" class="nav-link">Home</a>
  </li>
  <li class="nav-element">
    <a href="#" class="nav-link">About Us</a>
  </li>
  <li class="nav-element">
    <a href="#" class="nav-link">Services</a>
  </li>
  <li class="nav-element">
    <a href="#" class="nav-link">Contact Us</a>
  </li>
  <button class="button-login">
    Log In
  </button>
  <button class="button-signin">
    Sign In
  </button>
</ul>
<script>
let nav-link="text-x1 md:hover:text-yellow-300 duration-500"
Array.from(document.getElementsByClassName("nav-link")).forEach((el)=>el.className=nav-link)
</script>
</body>


@apply方法并不是很有用,因为伪类无法被包含在内。 - R_Ganga

0
我发现在我的nextjs/tailwind项目中,"@layer components" + "@apply" 的组合效果很好。
@tailwind base;
@tailwind components;
@tailwind utilities;

@layer components {
    .login-page {
        @apply bg-gray-50 dark:bg-gray-900;      
    }
    .login-container {
        @apply flex flex-col items-center justify-center px-6 py-8 mx-auto;
    }
    .login-title {
        @apply flex items-center mb-6 text-2xl font-semibold;
    }
    .login-card {
        @apply w-full bg-white rounded-lg shadow dark:border md:mt-0;
    }
}

HTML如下:

export default function Login() {
return (
    <section className="login-page">
        <div className="login-container">
            <a href="#" className="login-title">
                SineWave Engineering
            </a>
            <div className="login-card">
                <div className="p-6 space-y-4 md:space-y-6 sm:p-8">

-3

你应该给父元素添加“group”类,然后再处理组子类:

<div class="group p-4">
  <p class="group-hover:bg-red-400">lorem ipsum</p>
</div>

在这段代码之后,如果你将鼠标悬停在 div 元素上,p 元素的背景颜色将会变成红色。


我认为他的意思是如何像@apply那样(但在cdn上)分组tailwindcss类,而不是如何使用group类。 - joshxfi

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接