Tailwind CSS on GitHub

工具类优先

从一组受约束的基本工具类构建复杂组件。

Overview

传统写法,每当需要在web上设置样式时,就需要编写CSS。

使用传统方法,定制设计需要定制CSS

ChitChat

You have a new message!

<div class="chat-notification">
  <div class="chat-notification-logo-wrapper">
    <img class="chat-notification-logo" src="/img/logo.svg" alt="ChitChat Logo">
  </div>
  <div class="chat-notification-content">
    <h4 class="chat-notification-title">ChitChat</h4>
    <p class="chat-notification-message">You have a new message!</p>
  </div>
</div>

<style>
  .chat-notification {
    display: flex;
    max-width: 24rem;
    margin: 0 auto;
    padding: 1.5rem;
    border-radius: 0.5rem;
    background-color: #fff;
    box-shadow: 0 20px 25px -5px rgba(0, 0, 0, 0.1), 0 10px 10px -5px rgba(0, 0, 0, 0.04);
  }
  .chat-notification-logo-wrapper {
    flex-shrink: 0;
  }
  .chat-notification-logo {
    height: 3rem;
    width: 3rem;
  }
  .chat-notification-content {
    margin-left: 1.5rem;
    padding-top: 0.25rem;
  }
  .chat-notification-title {
    color: #1a202c;
    font-size: 1.25rem;
    line-height: 1.25;
  }
  .chat-notification-message {
    color: #718096;
    font-size: 1rem;
    line-height: 1.5;
  }
</style>

有了Tailwind,你可以通过直接在HTML中应用预先存在的类来添加样式。

使用工具类来构建定制设计,而不需要编写CSS

ChitChat

You have a new message!

<div class="p-6 max-w-sm mx-auto bg-white rounded-xl shadow-md flex items-center space-x-4">
  <div class="flex-shrink-0">
    <img class="h-12 w-12" src="/img/logo.svg" alt="ChitChat Logo">
  </div>
  <div>
    <div class="text-xl font-medium text-black">ChitChat</div>
    <p class="text-gray-500">You have a new message!</p>
  </div>
</div>

上面的例子,我们使用了:

这种方法允许我们实现一个完全定制的组件设计,而不需要编写任何定制的CSS。

现在我知道你在想什么,“this is an atrocity, what a horrible mess!”,没错,这是有点丑陋。事实上,当你第一次看到它时,你绝对不会认为它是一个好主意——你必须真正地去尝试它。

但一旦你真的用这种方式构建了一些东西,你很快就会注意到一些真正重要的好处:

  • 你没有浪费精力去想类名。不再需要添加像sidebar-inner-wrapper这样愚蠢的类名,只是为了能够对某些东西进行样式化,也不再需要为真正只是flex容器的东西的完美抽象名称而烦恼。
  • 你的css文件不会再变大了。使用传统方法,每次添加新特性时,CSS文件都会变大。有了Tailwind,一切都可以重用,所以你很少需要编写新的CSS。
  • 更安全的改动。CSS是全局的,当你做更改时,你永远不知道你破坏了什么。HTML中的类是本地的,所以可以更改它们,而不必担心其他东西会破坏。

当你意识到只使用HTML和预定义的工具类可以提高工作效率时,使用其他任何方式都将是一种折磨!!!


为什么不直接使用内联样式呢?

对于这种方法,一个常见的反应是:“这不就是内联样式吗?”,在某些方面确实是这样——你直接将样式应用到元素上,而不是:给它们指定一个类名,然后给这个类添加样式。

但是与内联样式相比,使用工具类有几个重要的优点:

  • 设计约束。使用内联样式,每个值都是一个魔法数字。使用工具类,你可以从预定义的设计系统中选择样式,这使得构建视觉上一致的ui变得更加容易。
  • 响应式设计. 你不能使用内联样式的媒体查询,但是你可以使用Tailwind的响应式类组轻松地构建完全响应的接口。
  • Hover, focus以及其他变体. 内联样式不能设置hover或者focus,但Tailwind的变体可以很轻松实现。

下面这个组件是完全响应的,包括一个带有hover和focus样式的按钮,并且完全是用工具类构建的:

Woman's Face

Erin Lindford

Product Engineer

<div class="py-8 px-8 max-w-sm mx-auto bg-white rounded-xl shadow-md space-y-2 sm:py-4 sm:flex sm:items-center sm:space-y-0 sm:space-x-6">
  <img class="block mx-auto h-24 rounded-full sm:mx-0 sm:flex-shrink-0" src="/img/erin-lindford.jpg" alt="Woman's Face">
  <div class="text-center space-y-2 sm:text-left">
    <div class="space-y-0.5">
      <p class="text-lg text-black font-semibold">
        Erin Lindford
      </p>
      <p class="text-gray-500 font-medium">
        Product Engineer
      </p>
    </div>
    <button class="px-4 py-1 text-sm text-purple-600 font-semibold rounded-full border border-purple-200 hover:text-white hover:bg-purple-600 hover:border-transparent focus:outline-none focus:ring-2 focus:ring-purple-600 focus:ring-offset-2">Message</button>
  </div>
</div>

可维护性问题

当使用工具类组的方法时,最大的可维护性问题是管理常见的重复工具类组合。

通过提取组件可以很轻松实现。

<!-- PrimaryButton.vue -->
<template>
  <button class="bg-blue-500 hover:bg-blue-700 text-white font-bold py-2 px-4 rounded">
    <slot/>
  </button>
</template>

你还可以使用Tailwind的@apply指令来围绕公共样式创建CSS抽象。

<!-- Using utilities -->
<button class="py-2 px-4 font-semibold rounded-lg shadow-md text-white bg-green-500 hover:bg-green-700">
  Click me
</button>

<!-- Extracting classes using @apply -->
<button class="btn btn-green">
  Button
</button>

<style>
  .btn {
    @apply py-2 px-4 font-semibold rounded-lg shadow-md;
  }
  .btn-green {
    @apply text-white bg-green-500 hover:bg-green-700;
  }
</style>

除此之外,维护一个工具类优先的CSS项目比维护一个大型CSS代码库要容易得多,因为HTML比CSS容易维护得多。像GitHub, Heroku, Kickstarter, Twitch, Segment等大公司都在使用这种方法并取得了巨大的成功。

如果你想了解其他人使用这种方法的经验,请查看以下资源:

更多的可以阅读The Case for Atomic/Utility-First CSS, curated by John Polacek.