Text Layout and Decoration
Purpose and Scope
This page is a focused reference for Tailwind CSS text-layout and text-decoration utilities: classes that affect inline text alignment, decoration lines and colors, wrapping, overflow, transformation, indentation, and letter or line spacing. The reader problem is practical: when a template contains classes like underline, no-underline, decoration-red-500, or responsive state-prefixed text utilities, how do those strings become CSS in the different Tailwind runtimes? The answer is that the utility classes are candidates discovered by a Tailwind integration, sent to the core compiler, and emitted through one of the package entry points used by your project.
Sources: packages/tailwindcss/src/index.ts, packages/tailwindcss/package.json
Tailwind’s first-party docs describe text-decoration-line utilities as direct mappings from class names to CSS declarations: underline emits text-decoration-line: underline, overline emits text-decoration-line: overline, line-through emits text-decoration-line: line-through, and no-underline emits text-decoration-line: none. The docs also show decoration color utilities such as decoration-current, decoration-transparent, decoration-black, decoration-white, and palette-backed classes like decoration-red-500. Treat these as part of the typography utility family: they are authored in markup, may be combined with variants like hover: and md:, and are generated only when the compiler sees the candidate.
The scope here is intentionally the public workflow, not a line-by-line inventory of every text-related utility implementation. The requested source paths expose the compiler API, package exports, command entry point, browser runtime, Node integration layer, and repository scripts. Together they show how text utilities travel through Tailwind CSS as a product: the core package owns compilation, integrations feed it stylesheet input and candidate classes, and build tools decide where the generated CSS is written or injected. Use the utility examples as authoring guidance and the source mapping as an implementation guide.
Relevant Source Files
packages/tailwindcss/src/index.ts— Defines the core package entry point, compile options, feature flags, CSS parsing flow, imports, theme handling, candidate compilation, variant substitution, and the public compiler surface used by integrations.packages/tailwindcss/package.json— Declares thetailwindcsspackage metadata, the CSS framework description, package exports for JavaScript and CSS entry points, and published files such asindex.css,theme.css,preflight.css, andutilities.css.package.json— Defines root workspace scripts for formatting, linting, building, testing, integration tests, UI tests, and playground commands that validate behavior across the monorepo.packages/@tailwindcss-browser/src/index.ts— Implements the browser runtime used by browser/CDN workflows, including stylesheet discovery, compiler creation, class caching, and scheduled builds.packages/@tailwindcss-cli/src/index.ts— Provides thetailwindcsscommand entry point, command parsing, help behavior, build dispatch, and thecanonicalizecommand for candidate lists.packages/@tailwindcss-node/src/index.ts— Re-exports Node-facing compile, optimization, source-map, normalization, instrumentation, and environment helpers, and registers module-resolution hooks when available.
Core Model: Text Utilities as Compiler Candidates
A Tailwind class in markup is best understood as a candidate: a string that might correspond to one or more CSS rules after parsing variants, resolving theme values, and checking utility definitions. Text-layout and decoration classes use that same model. underline is a simple static candidate; hover:underline adds a state variant; md:underline adds a responsive breakpoint variant; decoration-red-500 resolves a theme color token into a text-decoration color. The requested source shows the core entry point importing compileCandidates, buildDesignSystem, Theme, substituteAtVariant, and CSS parsing helpers, which is the public path by which candidates become generated CSS.
Sources: packages/tailwindcss/src/index.ts
The compiler entry point also exposes compile-time concepts that matter when debugging text utilities. Compile options include a base, an optional from path, polyfill settings, and async loaders for modules and stylesheets. The parser records feature flags such as @apply, @import, JavaScript plugin compatibility, theme(…), utilities, variants, and @theme. Those features explain why a typography class can be affected by more than its own name: imported stylesheets can add layers, theme declarations can provide color and spacing tokens, and variants can wrap the generated declaration in selectors or media conditions.
Because Tailwind v4 emphasizes CSS-first configuration, text utility authoring usually starts in template markup and theme customization usually starts in CSS. For decoration colors, the official docs express palette values through CSS variables such as var(--color-red-500), which means the generated utility depends on the active theme variables. When a project changes theme variables or imports different Tailwind entry files, the same decoration-* class can resolve against the project’s design system while keeping the class name stable. That separation is the key to using text utilities consistently across frameworks and build tools.
Utility Reference
The following reference summarizes the text utility areas covered by this page. Use it as an authoring guide, then rely on the compiler and integration pages for implementation details. Decoration examples are backed by the official docs snippets supplied for this page; the broader families are the standard typography-text areas named by this wiki outline and are compiled through the same Tailwind candidate pipeline.
| Area | Example classes | CSS responsibility | Notes |
|---|---|---|---|
| Text decoration line | underline, overline, line-through, no-underline | Sets text-decoration-line | Compose with hover:, focus:, responsive variants, and link states. |
| Text decoration color | decoration-current, decoration-transparent, decoration-black, decoration-white, decoration-red-500 | Sets text-decoration-color | Palette-backed classes resolve through Tailwind color variables. |
| Text alignment | text-left, text-center, text-right, logical alignment classes | Controls inline text alignment | Often paired with responsive variants for layout changes. |
| Text wrapping and overflow | wrapping, truncation, and overflow-related text classes | Controls line breaking and clipped text | Prefer explicit width constraints when testing truncation behavior. |
| Text transform and indentation | transform and indent classes | Controls casing and first-line indentation | Useful for headings, prose snippets, and editorial layouts. |
| Line and letter spacing | leading and tracking classes | Controls line height and character spacing | Usually token-driven, so theme changes affect the emitted values. |
<p class='underline decoration-red-500 hover:no-underline md:overline'>
The quick brown fox jumps over the lazy dog.
</p>This example shows three important composition rules. First, the base class underline applies immediately. Second, decoration-red-500 controls the decoration color independently from the line itself, so the underline and color can be changed separately. Third, hover:no-underline and md:overline are not special typography APIs; they are normal variant-prefixed candidates. The variant engine wraps or conditions the generated rule, while the underlying utility still maps to a text-decoration declaration. This is why the same mental model works for text alignment, wrapping, overflow, and spacing utilities.
Execution Flow Across Package Entry Points
In a build-tool setup, the tailwindcss package is the center of the workflow. Its package metadata describes Tailwind as a utility-first CSS framework and publishes both JavaScript and CSS entry points. The root export points to the compiler source in development and to built library files for published packages, while CSS exports expose index.css, preflight.css, theme.css, and utilities.css. For text utilities, the practical implication is that a project can import the complete framework or specific CSS entry files, and generated typography rules are emitted as part of the utilities layer when matching candidates are present.
Sources: packages/tailwindcss/package.json
The browser runtime follows the same core model but performs it inside the page. It looks for <style type='text/tailwindcss'> tags, concatenates their contents, injects @import 'tailwindcss' when the user has not supplied an import, and creates a compiler with base: '/' plus browser-specific stylesheet and module loaders. It also keeps a set of classes already seen on the page so scheduled builds can pass only new classes to the compiler. In a Play CDN-style workflow, this is what lets adding underline or decoration-red-500 to markup result in updated CSS without a traditional build step.
Sources: packages/@tailwindcss-browser/src/index.ts
The CLI entry point exposes the same capability for local builds and automation. The command accepts root-level build options, supports tailwindcss build, displays help in interactive or --help cases, and dispatches to the build command handler. It also includes a canonicalize command, which is useful when working with candidate lists because it normalizes how class candidates are represented by the toolchain. For teams debugging typography output, the CLI path is the most direct way to reproduce generated CSS from an input stylesheet and a known set of source files.
Sources: packages/@tailwindcss-cli/src/index.ts
The Node package is the integration-facing layer for JavaScript tooling. It re-exports compile, optimization, instrumentation, source-map, path-normalization, and environment helpers, then registers ESM resolution hooks when the current runtime supports them. This matters for text utilities because framework adapters and build plugins need more than raw CSS generation: they need dependency tracking, stable module loading, optimization, and source-map behavior. When a text utility appears incorrectly in a bundled app, the Node layer is often where integration authors inspect compile options and emitted artifacts.
Sources: packages/@tailwindcss-node/src/index.ts
Authoring Patterns and Debugging Tips
When authoring text-decoration utilities, start with the smallest class that expresses the visual requirement, then add variants only where the state or breakpoint changes. A link that is normally undecorated but underlined on hover should use no-underline hover:underline, matching the official docs’ example. A link that becomes underlined on medium screens and above should use a breakpoint prefix such as md:underline. The compiler treats both as variant-prefixed candidates, so the important debugging question is whether the candidate string appears in scanned source and whether the integration is sending it to the compiler.
For decoration color, keep the line and color decisions separate. underline decoration-current intentionally follows the current text color, while underline decoration-transparent can reserve decoration behavior without making the line visible. Palette classes like decoration-red-500 depend on Tailwind’s theme variables, so unexpected color output should be investigated through theme CSS and imports before assuming the class is invalid. Because the core parser tracks @theme, imports, and theme functions, text color and decoration color behavior can legitimately change when the project’s CSS entry file changes.
For wrapping, overflow, transform, indentation, leading, and tracking utilities, debug from layout constraints outward. Many of these classes only become visible when the element has a width, display behavior, or inherited typography context that makes the property observable. For example, overflow-oriented text utilities often need constrained inline size; line-height utilities interact with font size; and letter-spacing changes are easier to inspect on longer strings. Tailwind’s role is to emit the declaration for the candidate, while the browser still applies normal CSS layout rules.
Build and Testing Signals
The root workspace scripts show how this repository verifies changes across the system. pnpm lint runs formatting checks and package lint tasks through Turbo, pnpm build builds packages while excluding playgrounds, pnpm test combines Rust tests with Vitest, pnpm test:integrations runs integration tests under the integrations root, and pnpm test:ui runs UI tests for the core and browser packages. These commands are not typography-specific, but they are the operational signals to use when changing compiler behavior that could affect generated text utilities.
Sources: package.json
For package-level work, packages/tailwindcss/package.json adds lint, build, dev, and test:ui scripts for the core package. That distinction is useful when deciding how much validation a typography-related change needs. A documentation-only update might only require formatting, while a compiler change affecting variants, theme resolution, or utility generation should run core tests and relevant integration tests. Browser-runtime changes should include UI validation because class discovery and scheduled rebuild behavior are observable in the page rather than only in generated files.
Next Steps
If you are using text utilities in an application, continue with the pages on variants, responsive design, theme customization, and detecting classes in source files. Those topics explain why a class may only apply in a state, why a breakpoint-prefixed text utility is conditional, how design tokens affect generated values, and how candidate scanning determines whether CSS is emitted. If you are integrating Tailwind into tooling, read the package API, Node API, CLI reference, browser build, and plugin pages next; they describe the public entry points that feed candidate classes into the compiler and deliver generated CSS to users.