Styling với utility classes

Xây dựng các thành phần phức tạp từ một tập hợp hạn chế các tiện ích nguyên thủy.

Tổng quan

Bạn style các thành phần với Tailwind bằng cách kết hợp nhiều class trình bày đơn mục đích (utility classes) trực tiếp trong markup của bạn:

ChitChat

You have a new message!

<div class="mx-auto flex max-w-sm items-center gap-x-4 rounded-xl bg-white p-6 shadow-lg outline outline-black/5 dark:bg-slate-800 dark:shadow-none dark:-outline-offset-1 dark:outline-white/10">  <img class="size-12 shrink-0" src="/img/logo.svg" alt="ChitChat Logo" />  <div>    <div class="text-xl font-medium text-black dark:text-white">ChitChat</div>    <p class="text-gray-500 dark:text-gray-400">You have a new message!</p>  </div></div>

Ví dụ, trong UI ở trên chúng tôi đã sử dụng:

  • Các tiện ích displaypadding (flex, shrink-0, và p-6) để kiểm soát bố cục tổng thể
  • Các tiện ích max-widthmargin (max-w-smmx-auto) để giới hạn chiều rộng thẻ và căn giữa nó theo chiều ngang
  • Các tiện ích background-color, border-radius, và box-shadow (bg-white, rounded-xl, và shadow-lg) để style giao diện của thẻ
  • Các tiện ích widthheight (size-12) để đặt chiều rộng và chiều cao của hình ảnh logo
  • Các tiện ích gap (gap-x-4) để xử lý khoảng cách giữa logo và văn bản
  • Các tiện ích font-size, color, và font-weight (text-xl, text-black, font-medium, v.v.) để style văn bản của thẻ

Việc style theo cách này mâu thuẫn với nhiều best practice truyền thống, nhưng một khi bạn thử nó, bạn sẽ nhanh chóng nhận thấy một số lợi ích thực sự quan trọng:

  • Bạn hoàn thành công việc nhanh hơn — bạn không tốn thời gian nghĩ ra tên class, đưa ra quyết định về selector, hoặc chuyển đổi giữa các file HTML và CSS, vì vậy các thiết kế của bạn được hoàn thiện rất nhanh.
  • Thực hiện thay đổi cảm thấy an toàn hơn — thêm hoặc xóa một utility class vào một phần tử chỉ ảnh hưởng đến phần tử đó, vì vậy bạn không bao giờ phải lo lắng về việc vô tình làm hỏng thứ gì đó ở trang khác đang sử dụng cùng một CSS.
  • Bảo trì các dự án cũ dễ dàng hơn — thay đổi một cái gì đó chỉ có nghĩa là tìm phần tử đó trong dự án của bạn và thay đổi các class, không phải cố gắng nhớ cách tất cả CSS tùy chỉnh đó hoạt động mà bạn đã không chạm vào trong sáu tháng.
  • Code của bạn dễ di chuyển hơn — vì cả cấu trúc và kiểu dáng đều nằm cùng một nơi, bạn có thể dễ dàng sao chép và dán toàn bộ các đoạn UI xung quanh, ngay cả giữa các dự án khác nhau.
  • CSS của bạn ngừng phát triển — vì các utility class có khả năng tái sử dụng cao, CSS của bạn không tiếp tục phát triển tuyến tính với mỗi tính năng mới bạn thêm vào dự án.

Những lợi ích này tạo ra sự khác biệt lớn trên các dự án nhỏ, nhưng chúng thậm chí còn có giá trị hơn đối với các nhóm làm việc trên các dự án dài hạn ở quy mô lớn.

Tại sao không chỉ sử dụng inline styles?

Một phản ứng phổ biến đối với cách tiếp cận này là tự hỏi, "đây không phải chỉ là inline styles sao?" và theo một số cách thì đúng là vậy — bạn đang áp dụng các kiểu trực tiếp vào các phần tử thay vì gán cho chúng một tên class và sau đó style class đó.

Nhưng sử dụng utility classes có nhiều lợi thế quan trọng so với inline styles, ví dụ:

  • Thiết kế với các ràng buộc — sử dụng inline styles, mọi giá trị đều là một con số ma thuật. Với các tiện ích, bạn đang chọn các kiểu từ một hệ thống thiết kế được xác định trước, điều này giúp xây dựng các UI nhất quán về mặt hình ảnh dễ dàng hơn nhiều.
  • Hover, focus, và các trạng thái khác — inline styles không thể nhắm mục tiêu các trạng thái như hover hoặc focus, nhưng các biến thể trạng thái của Tailwind giúp dễ dàng style các trạng thái đó bằng utility classes.
  • Media queries — bạn không thể sử dụng media queries trong inline styles, nhưng bạn có thể sử dụng các biến thể phản hồi của Tailwind để xây dựng các giao diện phản hồi hoàn toàn một cách dễ dàng.

Thành phần này hoàn toàn phản hồi và bao gồm một nút với các kiểu hover và active, và được xây dựng hoàn toàn bằng các utility classes:

Woman's Face

Erin Lindford

Product Engineer

<div class="flex flex-col gap-2 p-8 sm:flex-row sm:items-center sm:gap-6 sm:py-4 ...">  <img class="mx-auto block h-24 rounded-full sm:mx-0 sm:shrink-0" src="/img/erin-lindford.jpg" alt="" />  <div class="space-y-2 text-center sm:text-left">    <div class="space-y-0.5">      <p class="text-lg font-semibold text-black">Erin Lindford</p>      <p class="font-medium text-gray-500">Product Engineer</p>    </div>    <button class="border-purple-200 text-purple-600 hover:border-transparent hover:bg-purple-600 hover:text-white active:bg-purple-700 ...">      Message    </button>  </div></div>

Tư duy theo utility classes

Style trạng thái hover và focus

Để style một phần tử trên các trạng thái như hover hoặc focus, hãy thêm tiền tố tên trạng thái vào bất kỳ tiện ích nào, ví dụ hover:bg-sky-700:

Hover over this button to see the background color change

<button class="bg-sky-500 hover:bg-sky-700 ...">Save changes</button>

Các tiền tố này được gọi là biến thể trong Tailwind, và chúng chỉ áp dụng các kiểu từ một utility class khi điều kiện cho biến thể đó khớp.

Dưới đây là CSS được tạo trông như thế nào cho class hover:bg-sky-700:

Generated CSS
.hover\:bg-sky-700 {  &:hover {    background-color: var(--color-sky-700);  }}

Lưu ý cách class này không làm gì cả trừ khi phần tử được hover? Công việc duy nhất của nó là cung cấp các kiểu hover — không gì khác.

Điều này khác với cách bạn viết CSS truyền thống, nơi một class đơn lẻ thường sẽ cung cấp các kiểu cho nhiều trạng thái:

HTML
<button class="btn">Save changes</button><style>  .btn {    background-color: var(--color-sky-500);    &:hover {      background-color: var(--color-sky-700);    }  }</style>

Bạn thậm chí có thể xếp chồng các biến thể trong Tailwind để áp dụng một tiện ích khi nhiều điều kiện khớp, giống như kết hợp hover:disabled:

<button class="bg-sky-500 disabled:hover:bg-sky-500 ...">Save changes</button>

Tìm hiểu thêm trong tài liệu về style các phần tử trên hover, focus, và các trạng thái khác.

Media queries và breakpoints

Cũng giống như các trạng thái hover và focus, bạn có thể style các phần tử ở các breakpoint khác nhau bằng cách thêm tiền tố breakpoint vào bất kỳ tiện ích nào:

Resize this example to see the layout change

01
02
03
04
05
06
<div class="grid grid-cols-2 sm:grid-cols-3">  <!-- ... --></div>

Trong ví dụ trên, tiền tố sm: đảm bảo rằng grid-cols-3 chỉ kích hoạt ở breakpoint sm và lớn hơn, mặc định là 40rem:

Generated CSS
.sm\:grid-cols-3 {  @media (width >= 40rem) {    grid-template-columns: repeat(3, minmax(0, 1fr));  }}

Tìm hiểu thêm trong tài liệu thiết kế phản hồi.

Nhắm mục tiêu dark mode

Style một phần tử trong chế độ tối chỉ là vấn đề thêm tiền tố dark: vào bất kỳ tiện ích nào bạn muốn áp dụng khi chế độ tối được kích hoạt:

Light mode

Writes upside-down

The Zero Gravity Pen can be used to write in any orientation, including upside-down. It even works in outer space.

Dark mode

Writes upside-down

The Zero Gravity Pen can be used to write in any orientation, including upside-down. It even works in outer space.

<div class="bg-white dark:bg-gray-800 rounded-lg px-6 py-8 ring shadow-xl ring-gray-900/5">  <div>    <span class="inline-flex items-center justify-center rounded-md bg-indigo-500 p-2 shadow-lg">      <svg        class="h-6 w-6 text-white"        fill="none"        viewBox="0 0 24 24"        stroke="currentColor"        aria-hidden="true"      >        <!-- ... -->      </svg>    </span>  </div>  <h3 class="text-gray-900 dark:text-white mt-5 text-base font-medium tracking-tight ">Writes upside-down</h3>  <p class="text-gray-500 dark:text-gray-400 mt-2 text-sm ">    The Zero Gravity Pen can be used to write in any orientation, including upside-down. It even works in outer space.  </p></div>

Cũng giống như với các trạng thái hover hoặc media queries, điều quan trọng cần hiểu là một utility class đơn lẻ sẽ không bao giờ bao gồm cả kiểu sáng và tối — bạn style mọi thứ trong chế độ tối bằng cách sử dụng nhiều class, một cho kiểu chế độ sáng và một cho kiểu chế độ tối.

Generated CSS
.dark\:bg-gray-800 {  @media (prefers-color-scheme: dark) {    background-color: var(--color-gray-800);  }}

Tìm hiểu thêm trong tài liệu chế độ tối.

Sử dụng class composition

Rất nhiều lần với Tailwind, bạn thậm chí sẽ sử dụng nhiều class để xây dựng giá trị cho một thuộc tính CSS duy nhất, ví dụ như thêm nhiều bộ lọc vào một phần tử:

HTML
<div class="blur-sm grayscale">  <!-- ... --></div>

Cả hai hiệu ứng này đều dựa vào thuộc tính filter trong CSS, vì vậy Tailwind sử dụng các biến CSS để có thể kết hợp các hiệu ứng này lại với nhau:

Generated CSS
.blur-sm {  --tw-blur: blur(var(--blur-sm));  filter: var(--tw-blur,) var(--tw-brightness,) var(--tw-grayscale,);}.grayscale {  --tw-grayscale: grayscale(100%);  filter: var(--tw-blur,) var(--tw-brightness,) var(--tw-grayscale,);}

CSS được tạo ở trên đã được đơn giản hóa một chút, nhưng thủ thuật ở đây là mỗi tiện ích đặt một biến CSS chỉ cho hiệu ứng mà nó định áp dụng. Sau đó, thuộc tính filter xem xét tất cả các biến này, quay lại không có gì nếu biến chưa được đặt.

Tailwind sử dụng cùng một cách tiếp cận này cho gradients, màu bóng, biến đổi, và nhiều hơn nữa.

Sử dụng giá trị tùy ý

Nhiều tiện ích trong Tailwind được điều khiển bởi các biến theme, như bg-blue-500, text-xl, và shadow-md, ánh xạ tới bảng màu, thang đo kiểu chữ và bóng của bạn.

Khi bạn cần sử dụng một giá trị một lần nằm ngoài theme của mình, hãy sử dụng cú pháp ngoặc vuông đặc biệt để chỉ định các giá trị tùy ý:

HTML
<button class="bg-[#316ff6] ...">  Sign in with Facebook</button>

Điều này có thể hữu ích cho các màu một lần nằm ngoài bảng màu của bạn (như màu xanh Facebook ở trên), nhưng cũng khi bạn cần một giá trị tùy chỉnh phức tạp như một lưới rất cụ thể:

HTML
<div class="grid grid-cols-[24rem_2.5rem_minmax(0,1fr)]">  <!-- ... --></div>

Nó cũng hữu ích khi bạn cần sử dụng các tính năng CSS như calc(), ngay cả khi bạn đang sử dụng các giá trị theme của mình:

HTML
<div class="max-h-[calc(100dvh-(--spacing(6)))]">  <!-- ... --></div>

Thậm chí còn có một cú pháp để tạo CSS hoàn toàn tùy ý bao gồm tên thuộc tính tùy ý, có thể hữu ích để đặt các biến CSS:

HTML
<div class="[--gutter-width:1rem] lg:[--gutter-width:2rem]">  <!-- ... --></div>

Tìm hiểu thêm trong tài liệu về sử dụng giá trị tùy ý.

Làm thế nào nó hoạt động?

Tailwind CSS không phải là một stylesheet tĩnh lớn như bạn có thể quen thuộc với các framework CSS khác — nó tạo ra CSS cần thiết dựa trên các class bạn thực sự đang sử dụng khi bạn biên dịch CSS của mình.

Nó thực hiện điều này bằng cách quét tất cả các file trong dự án của bạn để tìm bất kỳ ký hiệu nào trông giống như tên class:

Button.jsx
export default function Button({ size, children }) {  let sizeClasses = {    md: "px-4 py-2 rounded-md text-base",    lg: "px-5 py-3 rounded-lg text-lg",  }[size];  return (    <button type="button" className={`font-bold ${sizeClasses}`}>      {children}    </button>  );}

Sau khi tìm thấy tất cả các class tiềm năng, Tailwind tạo ra CSS cho mỗi class và biên dịch tất cả thành một stylesheet chỉ chứa các kiểu bạn thực sự cần.

Vì CSS được tạo dựa trên tên class, Tailwind có thể nhận ra các class sử dụng giá trị tùy ý như bg-[#316ff6] và tạo ra CSS cần thiết, ngay cả khi giá trị không phải là một phần của theme của bạn.

Tìm hiểu thêm về cách hoạt động này trong phát hiện class trong file nguồn.

Các selector phức tạp

Đôi khi bạn cần style một phần tử dưới sự kết hợp của các điều kiện, ví dụ như trong chế độ tối, tại một breakpoint cụ thể, khi được hover, và khi phần tử có một thuộc tính dữ liệu cụ thể.

Dưới đây là ví dụ về cách nó trông như thế nào với Tailwind:

HTML
<button class="dark:lg:data-current:hover:bg-indigo-600 ...">  <!-- ... --></button>
Simplified CSS
@media (prefers-color-scheme: dark) and (width >= 64rem) {  button[data-current]:hover {    background-color: var(--color-indigo-600);  }}

Tailwind cũng hỗ trợ những thứ như group-hover, cho phép bạn style một phần tử khi một phần tử cha cụ thể được hover:

HTML
<a href="#" class="group rounded-lg p-8">  <!-- ... -->  <span class="group-hover:underline">Read more…</span></a>
Simplified CSS
@media (hover: hover) {  a:hover span {    text-decoration-line: underline;  }}

Cú pháp group-* này cũng hoạt động với các biến thể khác, như group-focus, group-active, và nhiều hơn nữa.

Đối với các kịch bản thực sự phức tạp (đặc biệt là khi style HTML mà bạn không kiểm soát), Tailwind hỗ trợ biến thể tùy ý cho phép bạn viết bất kỳ selector nào bạn muốn, trực tiếp trong tên class:

HTML
<div class="[&>[data-active]+span]:text-blue-600 ...">  <span data-active><!-- ... --></span>  <span>This text will be blue</span></div>
Simplified CSS
div > [data-active] + span {  color: var(--color-blue-600);}

Khi nào nên sử dụng inline styles

Inline styles vẫn rất hữu ích trong các dự án Tailwind CSS, đặc biệt là khi một giá trị đến từ một nguồn động như cơ sở dữ liệu hoặc API:

branded-button.jsx
export function BrandedButton({ buttonColor, textColor, children }) {  return (    <button      style={{        backgroundColor: buttonColor,        color: textColor,      }}      className="rounded-md px-3 py-1.5 font-medium"    >      {children}    </button>  );}

Bạn cũng có thể sử dụng inline style cho các giá trị tùy ý rất phức tạp khó đọc khi được định dạng dưới dạng tên class:

HTML
<div class="grid-[2fr_max(0,var(--gutter-width))_calc(var(--gutter-width)+10px)]"><div style="grid-template-columns: 2fr max(0, var(--gutter-width)) calc(var(--gutter-width) + 10px)">  <!-- ... --></div>

Một mẫu hữu ích khác là đặt các biến CSS dựa trên các nguồn động bằng cách sử dụng inline styles, sau đó tham chiếu các biến đó bằng các utility class:

branded-button.jsx
export function BrandedButton({ buttonColor, buttonColorHover, textColor, children }) {  return (    <button      style={{        "--bg-color": buttonColor,        "--bg-color-hover": buttonColorHover,        "--text-color": textColor,      }}      className="bg-(--bg-color) text-(--text-color) hover:bg-(--bg-color-hover) ..."    >      {children}    </button>  );}

Quản lý sự trùng lặp

Khi bạn xây dựng toàn bộ dự án chỉ với các utility class, bạn chắc chắn sẽ thấy mình lặp lại các mẫu nhất định để tạo lại cùng một thiết kế ở những nơi khác nhau.

Ví dụ, ở đây các utility class cho mỗi hình ảnh avatar được lặp lại năm lần riêng biệt:

Contributors

204
<div>  <div class="flex items-center space-x-2 text-base">    <h4 class="font-semibold text-slate-900">Contributors</h4>    <span class="bg-slate-100 px-2 py-1 text-xs font-semibold text-slate-700 ...">204</span>  </div>  <div class="mt-3 flex -space-x-2 overflow-hidden">    <img class="inline-block h-12 w-12 rounded-full ring-2 ring-white" src="https://images.unsplash.com/photo-1491528323818-fdd1faba62cc?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=facearea&facepad=2&w=256&h=256&q=80" alt="" />    <img class="inline-block h-12 w-12 rounded-full ring-2 ring-white" src="https://images.unsplash.com/photo-1550525811-e5869dd03032?ixlib=rb-1.2.1&auto=format&fit=facearea&facepad=2&w=256&h=256&q=80" alt="" />    <img class="inline-block h-12 w-12 rounded-full ring-2 ring-white" src="https://images.unsplash.com/photo-1500648767791-00dcc994a43e?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=facearea&facepad=2.25&w=256&h=256&q=80" alt="" />    <img class="inline-block h-12 w-12 rounded-full ring-2 ring-white" src="https://images.unsplash.com/photo-1472099645785-5658abf4ff4e?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=facearea&facepad=2&w=256&h=256&q=80" alt="" />    <img class="inline-block h-12 w-12 rounded-full ring-2 ring-white" src="https://images.unsplash.com/photo-1517365830460-955ce3ccd263?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=facearea&facepad=2&w=256&h=256&q=80" alt="" />  </div>  <div class="mt-3 text-sm font-medium">    <a href="#" class="text-blue-500">+ 198 others</a>  </div></div>

Đừng hoảng sợ! Trong thực tế, đây không phải là vấn đề bạn có thể lo lắng, và các chiến lược để giải quyết nó là những điều bạn đã làm hàng ngày.

Sử dụng vòng lặp

Rất nhiều lần một phần tử thiết kế xuất hiện nhiều hơn một lần trong trang được hiển thị thực sự chỉ được tác giả viết một lần vì markup thực tế được hiển thị trong một vòng lặp.

Ví dụ, các avatar trùng lặp ở đầu hướng dẫn này gần như chắc chắn sẽ được hiển thị trong một vòng lặp trong một dự án thực tế:

Contributors

204
<div>  <div class="flex items-center space-x-2 text-base">    <h4 class="font-semibold text-slate-900">Contributors</h4>    <span class="bg-slate-100 px-2 py-1 text-xs font-semibold text-slate-700 ...">204</span>  </div>  <div class="mt-3 flex -space-x-2 overflow-hidden">    {#each contributors as user}      <img class="inline-block h-12 w-12 rounded-full ring-2 ring-white" src={user.avatarUrl} alt={user.handle} />    {/each}  </div>  <div class="mt-3 text-sm font-medium">    <a href="#" class="text-blue-500">+ 198 others</a>  </div></div>

Khi các phần tử được hiển thị trong một vòng lặp như thế này, danh sách class thực tế chỉ được viết một lần nên không có vấn đề trùng lặp thực sự nào để giải quyết.

Sử dụng chỉnh sửa đa con trỏ

Khi sự trùng lặp được bản địa hóa cho một nhóm các phần tử trong một file duy nhất, cách dễ nhất để giải quyết nó là sử dụng chỉnh sửa đa con trỏ để nhanh chóng chọn và chỉnh sửa danh sách class cho mỗi phần tử cùng một lúc:

<nav class="flex justify-center space-x-4">  <a href="/dashboard" class="font-medium rounded-lg px-3 py-2 text-gray-700 hover:bg-gray-100 hover:text-gray-900">    Home  </a>  <a href="/team" class="font-medium rounded-lg px-3 py-2 text-gray-700 hover:bg-gray-100 hover:text-gray-900">    Team  </a>  <a href="/projects" class="font-medium rounded-lg px-3 py-2 text-gray-700 hover:bg-gray-100 hover:text-gray-900">    Projects  </a>  <a href="/reports" class="font-medium rounded-lg px-3 py-2 text-gray-700 hover:bg-gray-100 hover:text-gray-900">    Reports  </a></nav>

Bạn sẽ ngạc nhiên về mức độ thường xuyên mà điều này trở thành giải pháp tốt nhất. Nếu bạn có thể nhanh chóng chỉnh sửa tất cả các danh sách class trùng lặp cùng một lúc, không có lợi ích gì khi giới thiệu thêm bất kỳ sự trừu tượng nào.

Sử dụng components

Nếu bạn cần tái sử dụng một số kiểu trên nhiều file, chiến lược tốt nhất là tạo một component nếu bạn đang sử dụng một framework front-end như React, Svelte, hoặc Vue, hoặc một template partial nếu bạn đang sử dụng một ngôn ngữ tạo mẫu như Blade, ERB, Twig, hoặc Nunjucks.

Beach
Private Villa
$299 USD per night
export function VacationCard({ img, imgAlt, eyebrow, title, pricing, url }) {  return (    <div>      <img className="rounded-lg" src={img} alt={imgAlt} />      <div className="mt-4">        <div className="text-xs font-bold text-sky-500">{eyebrow}</div>        <div className="mt-1 font-bold text-gray-700">          <a href={url} className="hover:underline">            {title}          </a>        </div>        <div className="mt-2 text-sm text-gray-600">{pricing}</div>      </div>    </div>  );}

Bây giờ bạn có thể sử dụng component này ở bao nhiêu nơi tùy thích, trong khi vẫn có một nguồn sự thật duy nhất cho các kiểu để chúng có thể dễ dàng được cập nhật cùng nhau ở một nơi.

Sử dụng custom CSS

Nếu bạn đang sử dụng một ngôn ngữ tạo mẫu như ERB hoặc Twig thay vì một cái gì đó như React hoặc Vue, việc tạo một template partial cho một cái gì đó nhỏ như một nút có thể cảm thấy quá mức cần thiết so với một class CSS đơn giản như btn.

Mặc dù chúng tôi thực sự khuyên bạn nên tạo các template partial thích hợp cho các thành phần phức tạp hơn, việc viết một số CSS tùy chỉnh là hoàn toàn ổn khi một template partial cảm thấy nặng nề.

Dưới đây là một class btn-primary có thể trông như thế nào, sử dụng các biến theme để giữ cho thiết kế nhất quán:

HTML
<button class="btn-primary">Save changes</button>
CSS
@import "tailwindcss";@layer components {  .btn-primary {    border-radius: calc(infinity * 1px);    background-color: var(--color-violet-500);    padding-inline: --spacing(5);    padding-block: --spacing(2);    font-weight: var(--font-weight-semibold);    color: var(--color-white);    box-shadow: var(--shadow-md);    &:hover {      @media (hover: hover) {        background-color: var(--color-violet-700);      }    }  }}

Tuy nhiên, một lần nữa, đối với bất cứ điều gì phức tạp hơn chỉ là một phần tử HTML đơn lẻ, chúng tôi thực sự khuyên bạn nên sử dụng các template partial để các kiểu và cấu trúc có thể được đóng gói ở một nơi.

Quản lý xung đột kiểu

Xung đột utility classes

Khi bạn thêm hai class nhắm mục tiêu cùng một thuộc tính CSS, class xuất hiện sau trong stylesheet sẽ thắng. Vì vậy, trong ví dụ này, phần tử sẽ nhận display: grid mặc dù flex đứng cuối cùng trong thuộc tính class thực tế:

HTML
<div class="grid flex">  <!-- ... --></div>
CSS
.flex {  display: flex;}.grid {  display: grid;}

Nói chung, bạn không bao giờ nên thêm hai class xung đột vào cùng một phần tử — chỉ thêm class mà bạn thực sự muốn có hiệu lực:

example.jsx
export function Example({ gridLayout }) {  return <div className={gridLayout ? "grid" : "flex"}>{/* ... */}</div>;}

Sử dụng các thư viện dựa trên component như React hoặc Vue, điều này thường có nghĩa là hiển thị các prop cụ thể cho các tùy chỉnh kiểu thay vì để người tiêu dùng thêm các class bổ sung từ bên ngoài component, vì các kiểu đó thường sẽ xung đột.

Sử dụng modifier important

Khi bạn thực sự cần buộc một utility class cụ thể có hiệu lực và không có cách nào khác để quản lý độ đặc hiệu, bạn có thể thêm ! vào cuối tên class để làm cho tất cả các khai báo trở thành !important:

HTML
<div class="bg-teal-500 bg-red-500!">  <!-- ... --></div>
Generated CSS
.bg-red-500\! {  background-color: var(--color-red-500) !important;}.bg-teal-500 {  background-color: var(--color-teal-500);}

Sử dụng cờ important

Nếu bạn đang thêm Tailwind vào một dự án có CSS phức tạp hiện có với các quy tắc độ đặc hiệu cao, bạn có thể sử dụng cờ important khi nhập Tailwind để đánh dấu tất cả các tiện ích là !important:

app.css
@import "tailwindcss" important;
Compiled CSS
@layer utilities {  .flex {    display: flex !important;  }  .gap-4 {    gap: 1rem !important;  }  .underline {    text-decoration-line: underline !important;  }}

Sử dụng tùy chọn prefix

Nếu dự án của bạn có tên class xung đột với các tiện ích Tailwind CSS, bạn có thể thêm tiền tố cho tất cả các class và biến CSS do Tailwind tạo ra bằng cách sử dụng tùy chọn prefix:

app.css
@import "tailwindcss" prefix(tw);
Compiled CSS
@layer theme {  :root {    --tw-color-red-500: oklch(0.637 0.237 25.331);  }}@layer utilities {  .tw\:text-red-500 {    color: var(--tw-color-red-500);  }}
Copyright © 2025 Tailwind Labs Inc.·Chính sách thương hiệu