Tables

Purpose and Scope

This page is a focused reference for Tailwind CSS table utilities: table layout, border collapsing, caption placement, and border spacing. These utilities are small, composable class candidates that let markup express table behavior without leaving the utility-first model. Use this page when you are styling semantic HTML tables and need to decide whether columns should size from content, whether adjacent borders should merge, where captions should appear, or how much space should exist between separated cell borders.

Tailwind’s official table documentation presents these APIs as utilities for the CSS table formatting model rather than as a separate component system. That distinction matters: Tailwind does not require a table component wrapper, JavaScript data grid, or runtime state manager for these features. You add classes directly to table-related elements, and the compiler turns the detected class candidates into CSS. The same table utility names can be used through the npm package, CLI, browser runtime, Vite/PostCSS integrations, or Node-powered build integrations because they flow through the shared compiler entry point.

Sources: packages/tailwindcss/src/index.ts, packages/tailwindcss/package.json

Relevant Source Files

  • packages/tailwindcss/src/index.ts — Defines the core compiler-facing package surface, including compile options, feature tracking, CSS parsing, imports, theme handling, variants, and candidate compilation paths that ultimately make documented utilities available to integrations.
  • packages/tailwindcss/package.json — Declares the tailwindcss package metadata and exports for index.css, preflight.css, theme.css, utilities.css, plugin compatibility, colors, and the primary TypeScript/JavaScript entry point.
  • package.json — Defines repository-level build, lint, test, integration-test, UI-test, and playground scripts used to validate packages and examples across the monorepo.
  • packages/@tailwindcss-browser/src/index.ts — Shows how the browser runtime creates a Tailwind compiler from style[type="text/tailwindcss"], injects @import "tailwindcss" when needed, loads virtual package CSS assets, and builds CSS for classes found on the page.
  • packages/@tailwindcss-cli/src/index.ts — Defines the command-line entry point, build command dispatch, help behavior, and canonicalization command used when table utilities are generated from local files in a CLI workflow.
  • packages/@tailwindcss-node/src/index.ts — Re-exports Node integration APIs for compile, optimization, instrumentation, normalization, and source maps, and installs ESM cache hooks where supported.

Utility Reference

Utility familyClasses and patternsCSS behaviorTypical element
Table layouttable-auto, table-fixedtable-layout: auto; or table-layout: fixed;table
Border collapseborder-collapse, border-separateborder-collapse: collapse; or border-collapse: separate;table
Caption sidecaption-top, caption-bottomPlaces a table caption above or below the table boxcaption
Border spacingborder-spacing-<number>, border-spacing-x-<number>, border-spacing-y-<number>, arbitrary values, and custom-property formsSets border-spacing, or one axis while preserving the other through Tailwind variablestable with separated borders

table-auto asks the browser to size columns from the contents of table cells. It is a good default for content-first tables where labels, names, dates, or short values should determine how space is distributed. table-fixed asks the browser to use fixed column widths, which is useful when predictable layout matters more than content-driven expansion. With fixed layout, you normally pair the table utility with width utilities on columns or cells so long text can wrap, truncate, or overflow according to the rest of your design.

border-collapse and border-separate control whether adjacent cell borders are merged or drawn independently. The official border-collapse examples show border-collapse combining adjacent borders into a single border when possible, including borders on the top-level table element. Use border-separate when each cell needs its own box and when border spacing should be visible. Border spacing only has an observable effect with separated borders, so the common pattern is to combine border-separate with border-spacing-2, border-spacing-x-3, or a related spacing value.

Caption utilities belong to the same table group because captions participate in table layout but are applied to the caption element, not the table element. Use caption-top when the caption is part of the table’s heading context and should appear before tabular data. Use caption-bottom when the caption behaves more like a note, explanation, or source label. The utilities remain intentionally narrow: they set placement, while typography, color, spacing, and alignment are composed with other Tailwind utilities.

System-to-Code Mapping

The table utilities are consumed as class candidates by Tailwind’s compiler. In the core package source, packages/tailwindcss/src/index.ts imports candidate compilation, CSS parsing, theme handling, function substitution, @apply, @import, compatibility hooks, variants, and AST-to-CSS output helpers. The file also defines compile options for base, from, polyfills, loadModule, and loadStylesheet, which are the hooks integrations use to provide stylesheets, plugins, and configuration. Table utilities are therefore not tied to one build tool; they are part of the shared utility generation pipeline used wherever the compiler runs.

Sources: packages/tailwindcss/src/index.ts

The package manifest makes that shared model visible to consumers. tailwindcss exports the primary package entry, index.css, preflight.css, theme.css, and utilities.css, plus compatibility entry points such as plugin, defaultTheme, colors, and flattenColorPalette. For table utilities, the important practical export is utilities.css through the main stylesheet import path, because documented classes such as table-fixed and border-separate are generated as utilities in the Tailwind build. Consumers can import the all-in-one stylesheet or the separated layers depending on their integration.

Sources: packages/tailwindcss/package.json

The root workspace scripts show how these behaviors are maintained across the monorepo. Repository-level build delegates to Turbo, test runs Rust tests and Vitest, test:integrations runs the integration test suite, and test:ui runs UI tests for the core and browser packages. For this page’s reader, those scripts are useful operational signals: table utilities are not a standalone package feature, so validation happens through the same compiler, package, integration, and browser workflows that validate all utility families.

Sources: package.json

Execution Flow Across Runtimes

In a standard build-tool or Node-backed integration, table classes begin as text in source files or generated markup. The integration calls into the Tailwind compiler, supplies CSS input and loading hooks, and receives generated CSS for the candidate set. The Node package entry point re-exports compile, optimization, instrumentation, source map, and path normalization APIs, and it registers ESM cache behavior on supported Node versions. This makes table utilities available to higher-level integrations without each integration reimplementing compilation or module loading.

Sources: packages/@tailwindcss-node/src/index.ts

In the CLI workflow, the executable entry point parses command-line arguments, dispatches tailwindcss build, prints help for interactive or --help usage, and exposes a canonicalize command for candidate lists. A project that uses the CLI can include table classes in templates, run a build with input and output CSS options, and receive the same generated declarations as a framework integration. The CLI is therefore a thin operational wrapper around the compiler model rather than a separate implementation of table utilities.

Sources: packages/@tailwindcss-cli/src/index.ts

The browser runtime supports Play CDN-style experimentation. It looks for style elements whose type is text/tailwindcss, concatenates their CSS, injects @import "tailwindcss" automatically when no import is present, creates a compiler with virtual stylesheet loading, and tracks classes seen on the page so builds can focus on new candidates. This means a prototype table can use table-auto, border-separate, and border-spacing-2 directly in HTML while the runtime compiles and injects the corresponding CSS into the document.

Sources: packages/@tailwindcss-browser/src/index.ts

Practical Patterns

Use automatic layout when the data itself should control column width. A compact song list, address table, or simple report often works well with table-auto because short values stay narrow and long labels can claim more room. Use fixed layout when column predictability matters, such as dashboards, comparison tables, or interfaces where headers define expected widths. The fixed model is especially useful with width, overflow, text wrapping, and truncation utilities because those utilities can then operate inside a more predictable column grid.

Use collapsed borders for dense, spreadsheet-like tables where adjacent cell boundaries should read as one grid. This is the pattern shown by the official border-collapse examples using borders on the table, header cells, and body cells. Use separated borders when the design calls for cards, tiles, row gaps, or visible breathing room between cells. In that case, add border-separate first, then choose border-spacing-*, border-spacing-x-*, or border-spacing-y-* depending on whether both axes or only one axis should change.

When combining border spacing with responsive or state variants, treat the table utility as a normal Tailwind candidate. For example, a table can use a tighter default spacing and a wider spacing at larger breakpoints, or use dark-mode border colors alongside the same spacing classes. The compiler path imported in packages/tailwindcss/src/index.ts includes the variant engine and candidate compilation, so table utilities participate in the same composition rules as display, spacing, color, and typography utilities.

Sources: packages/tailwindcss/src/index.ts

Example Markup

<table class="table-fixed border-separate border-spacing-y-2 w-full">
  <caption class="caption-bottom text-sm text-gray-500">
    Release history for selected songs.
  </caption>
  <thead>
    <tr>
      <th class="w-1/2 border px-3 py-2 text-left">Song</th>
      <th class="w-1/3 border px-3 py-2 text-left">Artist</th>
      <th class="w-1/6 border px-3 py-2 text-left">Year</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td class="border px-3 py-2">The Sliding Mr. Bones</td>
      <td class="border px-3 py-2">Malcolm Lockyer</td>
      <td class="border px-3 py-2">1961</td>
    </tr>
  </tbody>
</table>

This example intentionally composes table utilities with width, border, spacing, text, and color utilities. Tailwind’s table APIs do not try to own all visual styling for tabular data; they expose the underlying table-specific CSS switches and let the rest of the design come from the broader utility system. If the same markup is built through the CLI, browser runtime, or Node-based integration, the relevant classes still resolve through the shared package surface and compiler.

Sources: packages/tailwindcss/package.json, packages/@tailwindcss-cli/src/index.ts, packages/@tailwindcss-browser/src/index.ts, packages/@tailwindcss-node/src/index.ts

Next Steps

If you are documenting or implementing a table-heavy design, start by choosing table-auto or table-fixed, then decide whether borders should collapse or remain separate. Add caption utilities only to the caption element, and apply border spacing only when using separated borders. For deeper adjacent topics, continue to the borders and outlines page for border width, style, color, and radius utilities; the spacing page for padding and margin composition; and the typography pages for readable table headings, captions, and cell content.