Tailwind CSS 开发的 6 个技巧(附资源!)

2025-05-25

Tailwind CSS 开发的 6 个技巧(附资源!)

在我之前的文章中,我列举了无数理由,说明为什么 Tailwind CSS 是新项目和现有项目的理想之选。刚开始学习时,学习每个实用类名,并了解哪个类最适合当前和未来的情况,可能会让人望而生畏。因此,在这篇文章中,我将分享我在学习 Tailwind 过程中学到的一些技巧。这些技巧并非千篇一律,但我发现它们确实让我的开发过程更加轻松,代码也更具可读性。

1. 使用 'clsx' 加入课程

让我们从每个项目都强烈推荐使用的功能开始:用于clsx连接类名。Clsx是一个简单的 JavaScript 实用程序,用于按条件连接类。它通过提供语法糖来处理 CSS 解决方案(例如 CSS 模块或 Tailwind CSS)的复杂样式,使我们的工作更加轻松。

💡 这个库与Classnames相同,但包大小更小,性能更好。

它的语法根据开发者的偏好和用例而有所不同。它的语法范围从数组到对象。让我们来看看所有的可能性:

// EXTRACTED FROM https://github.com/lukeed/clsx 
import clsx from 'clsx';

// Strings (variadic)
clsx('foo', true && 'bar', 'baz');
//=> 'foo bar baz'

// Objects
clsx({ foo:true, bar:false, baz:isTrue() });
//=> 'foo baz'

// Objects (variadic)
clsx({ foo:true }, { bar:false }, null, { '--foobar':'hello' });
//=> 'foo --foobar'

// Arrays
clsx(['foo', 0, false, 'bar']);
//=> 'foo bar'

// Arrays (variadic)
clsx(['foo'], ['', 0, false, 'bar'], [['baz', [['hello'], 'there']]]);
//=> 'foo bar baz hello there'

// Kitchen sink (with nesting)
clsx('foo', [1 && 'bar', { baz:false, bat:null }, ['hello', ['world']]], 'cya');
//=> 'foo bar hello world cya'
Enter fullscreen mode Exit fullscreen mode

在处理复杂的 UI 时,这种多样性非常强大且有用。

我选择了两种语法来编写 Tailwind CSS 类:用于处理条件的对象符号和用于前缀的逗号分隔值。

我最初使用基本的字符串内联求值,但很快发现我的类变得过于拥挤。请看以下示例:

clsx('classes', cond1 && 'classes classes1 classes2', cond2 && cond3 && cond4 && '...') 
Enter fullscreen mode Exit fullscreen mode

这被认为是 Tailwind 的缺点之一。它很快就会变得难以阅读且难以维护。所以我选择用 JavaScript 对象来处理条件类名。

无论有多少条件,它都更容易阅读和跟踪。让我们看一下上面的相同代码,但使用新的语法:

clsx('classes', {
    'classes classes1 classes2': cond1,
    '...': cond2 && cond3 && cond4
})
Enter fullscreen mode Exit fullscreen mode

人们可以立即注意到它是多么容易阅读,并且可以避免被指责的长类名列表。

此外,当使用响应式类名和暗模式等前缀时,我们会:

<div class="block bg-white text-left space-y-1 py-2 w-full sm:w-1/2 sm:space-y-0 md:w-1/3 md:space-x-6 dark:bg-gray-700" />
Enter fullscreen mode Exit fullscreen mode

对于这种长类名,我的解决方案是在 clsx 中使用逗号分隔的值。像这样:

<div
  class={clsx(
    'block bg-white text-left space-y-1 py-2 w-full',
    'sm:w-1/2 sm:space-y-0',
    'md:w-1/3 md:space-x-6',
    'dark:bg-gray-700',
  )}
/>
Enter fullscreen mode Exit fullscreen mode

如果需要,并且你使用了像 Prettier 这样的代码格式化程序,它会将每个值发送到新的一行。正如你所见,这使得类在将来更易于阅读和修改。

💡如果类名很少,比如 4 或 5,那么我会使用纯字符串,因为否则不会提高可读性。

您可能会问,使用像 这样的 JavaScript 库会有什么性能损失呢clsx?它会影响性能,但影响很小,可以忽略不计。该库非常(311 字节)且速度很快,用户在运行时不会注意到任何性能差异。

2. 分解成小部分

Tailwind 的内联类允许元素不依赖于实现的上下文。这意味着样式可以移植——在任何上下文中移动而不会丢失其含义。

我们应该充分利用它,尽可能多地创建组件。这样可以通过更好的组合来提高代码的可读性,并且从长远来看也更易于维护。

以下面的代码片段为例:

const Post = ({
  content,
  frontmatter,
  slug,
  nextPost,
  previousPost,
}: Props) => (
    <div className="px-10 pt-40 pb-24 space-y-40 md:pt-48">      
      <article className="prose prose-lg xl:prose-2xl">
        <header>
          <h1 className="text-center">
            {frontmatter.title}
          </h1>
          <Image
            className="rounded-lg"
            src={frontmatter.cover_image}
            alt="cover image"
          />
        </header>
        <ReactMarkdown
          escapeHtml={false}
          source={content}
          renderers={{
            code: CodeBlock,
            inlineCode: InlineCode,
            image: InlineImage,
          }}
        />
      </article>
      <hr className="max-w-4xl mx-auto text-center border-black mb-20"/>     
      <section className="flex flex-col items-center mx-auto space-y-20">
        <header>
          <h1 className="text-5xl font-bold">You may also like</h1>
        </header>
        <div className="flex flex-col space-y-10 sm:flex-row sm:space-y-0 sm:space-x-20">
          {previousPost && <RecommendedPostCard post={previousPost} />}
          {nextPost && <RecommendedPostCard post={nextPost} />}
        </div>
      </section>      
      <hr className="max-w-4xl mx-auto text-center bg-black border-black" />
      <Subscribe className="w-full p-0 mx-auto" />
    </div>
);
Enter fullscreen mode Exit fullscreen mode

当您第一次阅读本文时,您可能甚至不知道每个元素的作用,除了那些已经有特定名称的元素,如ReactMarkdownImage

由于我们的样式不依赖于上下文,我们可以创建新的更小的组件,这将使我们更容易推理我们的代码。

const Post = ({
  content,
  frontmatter,
  slug,
  nextPost,
  previousPost,
}) => (
    <div className="px-10 pt-40 pb-24 space-y-40 md:pt-48">      
      <article className="prose prose-lg xl:prose-2xl">
        <PostHeader frontmatter={frontmatter} />
        <ReactMarkdown
          escapeHtml={false}
          source={content}
          renderers={{
            code: CodeBlock,
            inlineCode: InlineCode,
            image: InlineImage,
          }}
        />
      </article>
      <Divider className="mb-20" />

      <RecommendedPosts previousPost={previousPost} nextPost={nextPost} />

      <Divider className="bg-black" />
      <Subscribe
        vertical
        showLottie={false}
        className="w-full p-0 mx-auto"
      />
    </div>
);

const PostHeader = ({ frontmatter }) => (
  <header>
    <h1 className="text-center">
      {frontmatter.title}
    </h1>
    <Image
      className="rounded-lg"
      src={frontmatter.cover_image}
      alt="cover image"
    />
  </header>
);

const RecommendedPosts = ({
  previousPost,
  nextPost,
}) => (
  <section className="flex flex-col items-center mx-auto space-y-20">
    <header>
      <h1 className="text-5xl font-bold">You may also like</h1>
    </header>
    <div className="flex flex-col space-y-10 sm:flex-row sm:space-y-0 sm:space-x-20">
      {previousPost && <RecommendedPostCard post={previousPost} />}
      {nextPost && <RecommendedPostCard post={nextPost} />}
    </div>
  </section>
);

const Divider: React.FC<DividerProps> = ({ className, ...other }) => (
  <hr className={clsx("max-w-4xl mx-auto text-center border-black", className)} {...other} />
);
Enter fullscreen mode Exit fullscreen mode

通过分离这些组件,我们可以确保我们的代码易于阅读并且具有更好的组合。

此外,将来修改这些组件将变得轻而易举。每个组件都有其用途,并且与外部逻辑隔离。这意味着开发人员可以确保他们修改的是特定元素,而不会影响其他功能。

根据经验法则,网站中构成特定角色的每个元素都可以分离为一个组件。这包括版块、导航、卡片、按钮,甚至页面本身。

这并不意味着所有东西都应该放在组件里。最好是寻找那些能提高可读性的组件。

只要你的代码不像普通书籍或文章那样容易阅读,就意味着这种分离可能对你有益。虽然这非常主观,但客观识别的方法之一是查找重复的类名及其在网站上的作用。

例如,<hr />未重构的 Page 组件中的两个类几乎完全相同。它们唯一的区别是mb-20第一个标签和bg-black第二个标签中的类名不同。

<hr className="max-w-4xl mx-auto text-center border-black mb-20"/>
// ...
<hr className="max-w-4xl mx-auto text-center border-black bg-black" />
Enter fullscreen mode Exit fullscreen mode

因此,为了避免重复,我们创建了一个组件并发送了classNameprop 来扩展类。

const Divider: React.FC<DividerProps> = ({ className, ...other }) => (
  <hr className={clsx("max-w-4xl mx-auto text-center border-black", className)} {...other} />
);
Enter fullscreen mode Exit fullscreen mode

3. 获取 VS Code 扩展

由于 Tailwind CSS 非常可预测,它为扩展开辟了无限的可能性,从而提高了开发效率并降低了学习曲线。

以下是我最喜欢的五个:

Tailwind CSS IntelliSense

Tailwind CSS IntelliSense通过提供自动完成、语法突出显示和 linting 等高级功能极大地改善了 Tailwind 开发体验。

我认为这是必备的。它对于学习 Tailwind 和记住类名非常有用。

此外,它可以读取你的tailwind.config.js值并进行调整。这在添加颜色或官方插件时非常有用。

Tailwind IntelliSense 的实际应用

重构 CSS

Refactor CSS是一个简洁的扩展,可以让你识别标记中重复出现的 CSS 类名。这是一个很好的指示器,可以帮助你判断何时应该创建组件。

重构显示重复类的 CSS。

逆风

这个功能太棒了!Headwind是 Tailwind CSS 的一个自定类排序器。它强制执行特定的类排序顺序。它能为你的组件创建一种无缝衔接的组织方式,让人一眼就能看出。在我看来,它是必不可少的。

头翼分类课程

💡 最近,Tailwind 发布了一个新的Prettier 插件,用于对类进行排序。建议大家关注一下,如果可以的话可以尝试一下。它非常适合帮助使用其他编辑器或没有扩展程序的同事强制执行类排序。

顺风遮阳帘

有时,为特定的十六进制颜色生成不同的色调非常有用。Tailwind Shades允许你在编辑器中快速直接地完成此操作。

Tailwind Shades 为特定十六进制生成阴影

Tailwind 文档

Tailwind docs 是一款工具,可以在命令面板上查看 Tailwind CSS 文档。当需要记住某个概念或学习框架时,这非常有用。它还能让你避免在 Google 上搜索文档链接。

Tailwind Docs 搜索并打开 Tailwind CSS 文档

4.依赖插件

Tailwind CSS 的可扩展性并不令人意外,插件可以帮助开发者通过 JavaScript 为 Tailwind CSS 注册新的样式。

关于插件的具体功能,人们可能会深究不解。但简而言之,对于希望通过组织共享样式的团队,或希望为动画等复杂用例生成类名的开发人员来说,插件非常有用。

不仅可以出于个人或组织原因创建插件,而且社区也创建了非常有用的插件,使开发人员的生活变得更加轻松。

以下是一些可用于加速开发的最佳插件:

顺风表格

Tailwind Forms是由 Tailwind CSS 官方团队开发的插件。它提供了表单元素的样式重置功能,方便用户轻松覆盖样式。如果您要创建自定义表单,那么 Tailwind Forms 插件是必不可少的。

展示 Tailwind 表单样式的简单表单

顺风字体

Tailwind Typography是 Tailwind 团队开发的另一款高质量插件。它提供了一组类,可以像Typography.js一样添加排版默认值。

有必要对任何无法控制的 HTML 元素进行样式设置,例如从 Markdown 生成的元素。

对于开发使用 CMS 并通过解析器生成元素的网站来说,这是必需的。

使用 Tailwind Typography 样式的博客文章

💡 我在nextjs-starter-blog 模板中使用了这个插件。如果你想或需要创建一个博客,可以看看这个插件!

Tailwind CSS 调试屏幕

Tailwind CSS 调试屏幕是一个简洁的小工具,可以显示当前活动的响应式断点。它在布局时非常有用,因为无需使用开发工具即可查看当前尺寸。

Tailwind CSS 调试屏幕显示当前屏幕断点

Tailwind CSS 主题

Tailwind CSS Theming是一款解决 Tailwind 中多主题问题的插件。它非常适合依赖CSS 变量动态更改主题的应用程序。如果您的项目包含多个主题,或者需要快速处理主题,我强烈推荐这款插件。

它的主要优点是其语法易读且简单。

// Extracted from: 
// https://github.com/innocenzi/tailwindcss-theming/blob/master/docs/quick-start.md
// theme.config.js

const { ThemeManager, Theme } = require('tailwindcss-theming/api');

const base = new Theme()
  .addColors({
    brand: '#44b3ac',             // Your brand color
    'on-brand': '#ffffff',        // For everything that goes on your brand color
    background: '#f7fafc',        // A background color
    'on-background': '#1a202c'    // For everything that goes on your background color
  });

const dark = new Theme()
  .addColors({
    brand: '#44b3ac',             // Your brand color
    'on-brand': '#ffffff',        // For everything that goes on your brand color
    background: '#1c1e26',        // A background color
    'on-background': '#d5d8da'    // For everything that goes on your background color
  });

module.exports = new ThemeManager()
  .setDefaultTheme(base)          // Sets the `base` theme as the default theme.
  .setDefaultDarkTheme(dark);     // Sets the `dark` theme as the default theme for users that prefer the `dark` scheme.
Enter fullscreen mode Exit fullscreen mode

5. 使用预构建组件

由于在 Tailwind 中拆分成小组件非常容易,因此它的社区用它创建了许多漂亮的组件抽象也就不足为奇了。甚至还有专门的网站致力于此。

以下是一些可用于获取预构建组件的网站或库:

Tailwindcomponents

Tailwindcomponents是一个免费的开源组件库,由社区创建。这个网站非常棒,因为几乎可以找到任何你需要的东西。

每个人都可以提交自己的组件,帮助其他开发者使用 Tailwind 构建或学习布局。就连 Tailwind 的创始人 Adam Wathan 也提交了布局!

Tailwind Components 登陆页面

Tailwind 工具箱

Tailwind Toolbox与 Tailwindcomponents 类似,包含许多实用的组件以及额外的模板、插件、工具和生成器。不过,它只允许用户推荐资源,而不允许上传自己的资源。这意味着内容不会像 Tailwindcomponents 那样丰富多样,但仍然非常实用。

Tailwind Components 登陆页面

Tailwind 用户界面

Tailwind UI是一个精美的 UI 库,由 Adam Wathan 和《重构 UI》的作者 Steve Schoger 创建。它包含大量组件,尽管大部分都需要付费。不过,免费示例的质量非常高,可以帮助你了解如何实现 UI。

Tailwind UI 登陆页面

尾块

Tailblocks是一个包含使用 Tailwind CSS 完成的常用布局的网站。它们对于快速启动网站非常有用。

Tailblocks 网站

风向用户界面

Gust UI是一个使用 Tailwind 构建的非常简单的组件库。如果你需要快速学习一些常见组件(例如滑块、切换开关等)的 React 逻辑,我推荐这个网站。

Gust UI 网站

梅拉基用户界面

Meraki UI是一个与 Tailwind UI 类似的 Tailwind 组件库。它提供常用的布局和组件,适用于身份验证、导航、页脚等常见用例。值得一试,尤其因为它完全免费。

Meraki UI 登陆页面

到达用户界面

对于希望创建易于访问的设计系统,又不想手动创建每个组件的开发者来说,Reach UI简直是救星。虽然这些组件并非由 Tailwind 制作,但由于其精细的样式,它们仍然可以由 Tailwind 进行样式设置。

它唯一的缺点是必须通过外部样式表或在 Tailwind 的配置中设置全局的 important来覆盖其样式。尽管如此,这些方法可以节省大量时间。

到达 UI 登陆页面

6. 使用其他造型解决方案

虽然考虑到 Tailwind CSS 本身就是一种解决方案,这似乎适得其反,但建议使用 CSS Modules 或 Styled Components 等其他解决方案来处理繁重的工作。90% 的时间你应该使用 Tailwind,但任何复杂的动画或新属性最好通过前者来处理。

例如,假设我们想max-width为某篇博客文章设置一个特殊组件。我们不想只为一个用例创建一个 Tailwind 类,而且由于个人偏好,内联对象可能不太合适。

将 CSS 模块与 Tailwind 结合起来可以解决这个难题。因为 Tailwind 的类可以直接与 CSS 属性一起编写。这使得它非常强大,并且使样式表更简单、更易于维护。

.root {
  @apply h-full bg-primary mx-auto transition-colors duration-150;

  max-width: 590px;
} 

// Called in our code as:
import s from "./styles.module.css"

<section className={s.root}></section> 
Enter fullscreen mode Exit fullscreen mode

另一种流行的 Tailwind 搭配方式是通过 CSS-in-JS 库,例如 Styled Components。最近,一个名为twin.macro的库在开发者中引起了广泛关注。它允许开发者将 Tailwind 与 CSS-in-JS 库集成到现有代码库中。这意味着它拥有 CSS-in-JS 的所有优点:构建时间短、JavaScript 集成等。它的语法如下:

import tw, { styled } from 'twin.macro'

const Input = styled.input`
  color: purple;
  ${tw`border rounded`}
`

const Component = () => <Input />
Enter fullscreen mode Exit fullscreen mode

如果您喜欢 CSS-in-JS 并且希望开始享受 Tailwind CSS 的一些好处,请查看它。

结论

Tailwind 是一个非常棒的 CSS 框架,我希望在可预见的未来继续使用它。通过运用这些技巧,我发现我的代码库更易于阅读,并且易于维护。希望这些技巧对你有所帮助。如果你认为任何技巧或资源与本文相关,请在下方评论区留言。

想要了解更多最新的 Web 开发内容,请在TwitterDev.to上关注我!感谢阅读!😎


你知道我有一份新闻通讯吗?📬

如果您想在我发布新博客文章时收到通知并收到精彩的每周资源以保持网络开发领先地位,请访问https://jfelix.info/newsletter

文章来源:https://dev.to/joserfelix/6-tips-for-tailwind-css-development-with-resources-33i4
PREV
React 中的页面转换
NEXT
40+ 优质免费 Web 开发资源