概述

传统上,每当您需要在网络上设置样式时,您都会编写 CSS。

使用传统方法,其中自定义设计需要自定义 CSS

ChitChat

您有新消息!

<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

您有新消息!

<div class="p-6 max-w-sm mx-auto bg-white rounded-xl shadow-lg flex items-center space-x-4">
  <div class="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-slate-500">You have a new message!</p>
  </div>
</div>

在上面的示例中,我们使用了

  • Tailwind 的 flexboxpadding 实用工具(flexshrink-0p-6)来控制整体卡片布局
  • max-widthmargin 实用工具(max-w-smmx-auto)来限制卡片宽度并将其水平居中
  • background colorborder radiusbox-shadow 实用工具(bg-whiterounded-xlshadow-lg)来设置卡片的外观
  • widthheight 实用工具(w-12h-12)来调整徽标图像的大小
  • space-between 实用工具(space-x-4)来处理徽标和文本之间的间距
  • font sizetext colorfont-weight 实用工具(text-xltext-blackfont-medium 等)来设置卡片文本样式

这种方法使我们能够实现完全自定义的组件设计,而无需编写一行自定义 CSS。

现在我知道你在想什么,“这简直是暴行,真是个糟糕的烂摊子!”你说得对,它有点丑。事实上,当你第一次看到它时,几乎不可能认为这是一个好主意——你必须实际尝试一下

但是一旦你真的以这种方式构建了一些东西,你就会很快注意到一些非常重要的优点

  • 你不会浪费精力去发明类名。不再添加诸如 sidebar-inner-wrapper 之类的愚蠢类名,只是为了能够对某些东西进行样式化,也不再为真正只是一个 flex 容器的东西纠结于完美的抽象名称。
  • 你的 CSS 停止增长。使用传统方法,每次添加新功能时,你的 CSS 文件都会变大。使用实用程序,所有内容都是可重用的,因此你很少需要编写新的 CSS。
  • 进行更改感觉更安全。CSS 是全局性的,当你进行更改时,你永远不知道自己会破坏什么。HTML 中的类是本地的,因此你可以更改它们,而不用担心其他东西会损坏。

当你意识到仅使用具有预定义实用程序类的 HTML 就能提高多少工作效率时,其他任何工作方式都会让你感觉像是在受折磨。


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

对这种方法的常见反应是疑惑,“这不就是内联样式吗?”在某些方面确实如此——你直接对元素应用样式,而不是为它们分配类名,然后对该类进行样式化。

但是使用实用程序类比内联样式有一些重要的优势

  • 使用约束进行设计。使用内联样式,每个值都是一个神奇数字。使用实用程序,你从预定义的 设计系统 中选择样式,这使得构建视觉上一致的 UI 变得更加容易。
  • 响应式设计。你无法在内联样式中使用媒体查询,但你可以使用 Tailwind 的 响应式实用程序 轻松构建完全响应式的界面。
  • 悬停、焦点和其他状态。内联样式无法针对悬停或焦点等状态,但 Tailwind 的状态变体可轻松使用实用程序类对这些状态进行样式化。

此组件完全响应,并包含带有悬停和焦点样式的按钮,并且完全使用实用程序类构建

Woman's Face

Erin Lindford

产品工程师

<div class="py-8 px-8 max-w-sm mx-auto bg-white rounded-xl shadow-lg 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: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-slate-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>

除此之外,维护一个实用程序优先的 CSS 项目比维护一个大型 CSS 代码库要容易得多,仅仅是因为 HTML 比 CSS 更容易维护。GitHub、Netflix、Heroku、Kickstarter、Twitch、Segment 等大公司都在成功地使用这种方法。

如果您想听听其他人对这种方法的体验,请查看以下资源

更多内容,请查看原子/实用程序优先 CSS 的案例,由John Polacek策划。