# Utility Draft — full text
> Utility Draft is an independent educational publication about Tailwind CSS layout patterns and build behavior.
# Tailwind Container Queries: A Reusable Card Example
> In Tailwind CSS v4, add @container to a wrapper and put container-query variants on its descendants. The component then responds to the wrapper's available width instead of the page's viewport. Start with a usable stacked layout and add a wider arrangement only when the container meets your chosen threshold. Verify the installed version and browser requirements, work on a branch, and review the built result before deployment.
Source: https://tailwind-tools.com/tailwind-container-query-card/
Publisher: Utility Draft
Published: 2026-09-07
Updated: 2026-09-07
## How do you use Tailwind container queries?
In Tailwind CSS v4, add `@container` to a wrapper and put container-query variants on its descendants. The component then responds to the wrapper's available width instead of the page's viewport. Start with a usable stacked layout and add a wider arrangement only when the container meets your chosen threshold. Verify the installed version and browser requirements, work on a branch, and review the built result before deployment.
This guide uses syntax checked against the official documentation labeled v4.3 and utilities compiled with Tailwind CSS 4.3.0. It assumes an existing working Tailwind build and horizontal writing mode. It is not an installation or migration procedure.
## What changes when the parent sets the breakpoint?
A page can have a wide main column and a narrow sidebar at the same viewport width. A reusable card does not necessarily have enough room for two columns in both locations.
Tailwind's [container-query documentation](https://tailwindcss.com/docs/responsive-design#container-queries) supports minimum-size variants, named containers and arbitrary thresholds. The example here uses `@min-[30rem]` to make the chosen threshold explicit.
The comparison is between the container and `30rem`, not the entire browser window. MDN explains that size queries use an eligible ancestor's dimensions; declaring `container-type: inline-size` establishes the relevant containment context. [MDN's container-query guide](https://developer.mozilla.org/en-US/docs/Web/CSS/Guides/Containment/Container_queries) covers that underlying CSS model.
Use viewport breakpoints for page-level changes, such as moving a sidebar below the main content. Use a container query when a component's arrangement should follow its own allocated space. The existing [responsive design guide](/tailwind-responsive-design/) covers the viewport side of that distinction.
## What does the minimal card look like?
The following is an original demonstration, not a production component or a report of user testing. It has two content blocks, no external assets and no JavaScript.
Place the markup in a source file already detected by your existing Tailwind build:
```html
Utility notes
Layout example
A card that follows its available space
The content remains in document order at both sizes.
```
The outer wrapper is the query container. The inner article is the grid whose columns change. Keep those roles separate: the article's query variant needs an eligible ancestor, not a query of its own size.
The base `grid-cols-1` creates one grid track. At the threshold, the arbitrary grid definition creates a `10rem` first track and a second track that can use the remaining space. Tailwind documents arbitrary track definitions in its [grid-template-columns reference](https://tailwindcss.com/docs/grid-template-columns). The underscore inside the class token represents the separation between these track definitions.
There are no visual order utilities here. The introductory block precedes the main text in the HTML at both widths.
The wrapper's `w-[22rem]` makes a narrow demonstration slot. Its `max-w-full` caps that width at the available containing width. These are ordinary width constraints, separate from the query itself. See Tailwind's [width reference](https://tailwindcss.com/docs/width) and [maximum-width reference](https://tailwindcss.com/docs/max-width) for those utilities.
## How do you demonstrate both layouts on one page?
Duplicate the complete wrapper and article in a local preview. In the second copy, change only `w-[22rem]` to `w-[42rem]`. Keep the component's article classes identical.
If the surrounding layout offers sufficient space, the first wrapper is narrower than the `30rem` threshold and the second is wider. The first article stacks its blocks; the second uses the two-track definition.
This isolates the intended variable: the width allocated to each component. Do not simultaneously change the text, grid classes and parent padding, because you then have several explanations for a difference.
For numerical inspection, assume a root font size of 16 CSS pixels. The demonstration widths are then:
| Wrapper content width | Calculation | Expected article layout |
| --- | --- | --- |
| 22rem | 22 × 16 = 352 CSS pixels | One column |
| Just below 30rem | Less than 480 CSS pixels | One column |
| 30rem | 30 × 16 = 480 CSS pixels | Two tracks |
| 42rem | 42 × 16 = 672 CSS pixels | Two tracks |
These are calculated expectations under the stated font-size assumption, not measurements from a browser test. A narrower containing layout can reduce the wrapper through `max-w-full`. Inspect the actual width rather than assuming the requested `42rem` was available.
The example puts padding on the inner article, not on the query wrapper. MDN's [`@container` reference](https://developer.mozilla.org/en-US/docs/Web/CSS/Reference/At-rules/@container) specifies that size comparisons measure the container's content box. Keeping the wrapper unpadded makes this first inspection easier to interpret.
## What CSS should the build produce?
The example's query and arbitrary grid utilities were compiled with Tailwind CSS 4.3.0 using the package's default stylesheet. Compilation verifies that the tokens are recognized and emit the intended declarations; it does not verify browser rendering, accessibility or your application's source detection.
The relevant generated rule contains this condition and declaration:
```css
@container (width >= 30rem) {
grid-template-columns: 10rem minmax(0,1fr);
}
```
This is an excerpt from inside the utility's selector, not a complete stylesheet to paste into a project. The selector and other generated rules have been omitted for readability.
The wrapper utility also emits:
```css
container-type: inline-size;
```
If your browser receives no relevant query rule, the first problem is generation or stylesheet loading. If the rule exists but does not apply, examine the ancestor and its measured width. Those are different failure paths.
Keep the full class token literal. Do not assemble the threshold or track values from string fragments. The [dynamic class-name guide](/tailwind-dynamic-class-names/) handles the separate source-detection problem in detail.
## How do named containers change nested behavior?
A nested query container can become the ancestor used by an unnamed query. When the component intentionally follows a particular outer wrapper, name that wrapper and name it in the variant.
This small example was also checked with the 4.3.0 compiler:
```html
```
Here `preview` identifies the intended ancestor. The compiled condition is `@container preview (width >= 30rem)`. The inner unnamed container does not replace that name requirement.
MDN documents how a container name filters the candidate containers in its [`@container` reference](https://developer.mozilla.org/en-US/docs/Web/CSS/Reference/At-rules/@container). Choose a component-specific name when nesting makes the relationship ambiguous. Naming every wrapper is unnecessary for the first, single-container example.
Do not add a name solely to hide an unexpected ancestor. Inspect the markup first and decide which allocation of space the component is meant to follow.
## Why is `container` different from `@container`?
Tailwind's `container` utility constrains an element's maximum width according to the current breakpoint. It does not serve the same purpose as the query-container utility.
Tailwind's [maximum-width documentation](https://tailwindcss.com/docs/max-width#using-breakpoints-container) also notes that `container` does not automatically add centering or horizontal padding. Neither that utility nor `max-w-full` substitutes for `@container` in this example.
This distinction matters during review: a wrapper called "container" in a component file may have a sizing class but no query containment declaration. Inspect the computed `container-type`, not the variable name.
## What should you check before using the pattern?
Use a local preview or branch and check the following cases. These are editorial acceptance checks for this demonstration, not an exhaustive accessibility or compatibility test.
1. **Narrow and wide placements together.** Confirm both copies use the same article classes while their wrapper widths differ.
2. **Threshold boundaries.** Inspect just below, at and above the measured threshold. Confirm that the wider grid appears at the intended boundary.
3. **Restricted outer space.** Narrow the page until the wider wrapper is capped. Confirm the component returns to its base layout.
4. **Long and sparse content.** Replace the demonstration text with your longest real heading and with a short entry. Review wrapping and overflow.
5. **Actual nesting.** Insert the component into its intended parent structure and confirm which ancestor the query uses.
6. **Zoom and text settings.** Recheck readability and the available width rather than relying solely on the calculated pixel table.
Do not infer full browser compatibility from one successful container query. Tailwind's [compatibility documentation](https://tailwindcss.com/docs/compatibility) lists framework-level browser requirements and notes that individual modern features may have additional support limitations. Check the browsers your project actually supports.
The compiler check here did not run your build integration or render the component. Your final verification must include both generated output and the application preview. No dependency upgrade, cache deletion or production deployment is necessary to inspect this pattern.
More component arrangements belong in [Layout Patterns](/layout-patterns/). For this one, the acceptance condition is specific: identical card markup changes columns when its intended ancestor crosses the chosen width, independently of another copy elsewhere on the same page.
## Sources
- [Tailwind CSS: container queries](https://tailwindcss.com/docs/responsive-design#container-queries) — v4.3 syntax, arbitrary thresholds and named variants.
- [MDN: container queries](https://developer.mozilla.org/en-US/docs/Web/CSS/Guides/Containment/Container_queries) — containment and ancestor-based size queries.
- [Tailwind CSS: grid-template-columns](https://tailwindcss.com/docs/grid-template-columns) — arbitrary grid tracks.
- [Tailwind CSS: width](https://tailwindcss.com/docs/width) — width utilities.
- [Tailwind CSS: max-width](https://tailwindcss.com/docs/max-width) — maximum widths and the separate `container` utility.
- [MDN: @container](https://developer.mozilla.org/en-US/docs/Web/CSS/Reference/At-rules/@container) — named queries and content-box comparisons.
- [Tailwind CSS: compatibility](https://tailwindcss.com/docs/compatibility) — framework and feature support boundaries.
## Frequently asked questions
**Does this example require an extra container-query plugin?**
The demonstrated utilities compiled with the Tailwind CSS 4.3.0 package and its default stylesheet, without an additional plugin. That result does not establish the setup required by an older project. Identify the installed version and follow its matching documentation rather than adding or removing dependencies to imitate this example.
**Can the same card have two layouts at one viewport width?**
Yes. In the example, one copy sits in a wrapper requesting 22rem and another in a wrapper requesting 42rem. When sufficient outer space is available, the first remains below the 30rem query threshold and the second exceeds it. Both article elements can retain exactly the same utility classes.
**Why does my 42rem wrapper still show the stacked layout?**
The requested width is not necessarily the available width. In this example, max-w-full can cap the wrapper inside a narrower parent. Inspect its actual content width and the relevant generated rule. Also confirm the article has the intended query-container ancestor and that another rule is not overriding the grid definition.
**Are the pixel values fixed across every project?**
No. The worked table explicitly assumes a root font size of 16 CSS pixels: 30rem then equals 480 CSS pixels. Inspect the actual root font size and container dimensions in your preview. Do not convert the table into a universal device breakpoint or assume that a requested wrapper width was achieved.
**Does a successful compiler check prove the card is ready to deploy?**
No. The reported check establishes that Tailwind CSS 4.3.0 recognized the demonstrated tokens and generated the expected declarations. It does not test your application, browser rendering, content or accessibility. Work on a branch, inspect generated output and test the component in its real placements and supported browsers before deployment.
---
# Tailwind Dynamic Class Names: Why Builds Miss Them
> Tailwind can miss dynamic class names when code assembles fragments such as `bg-${color}-500`, because source detection looks for complete class tokens rather than evaluating every runtime expression. Replace interpolation with a validated lookup whose values contain full literal classes, verify that the file is included in the installed project’s source detection, rebuild with the project’s actual command, and confirm the selector appears in generated CSS.
Source: https://tailwind-tools.com/tailwind-dynamic-class-names/
Publisher: Utility Draft
Published: 2026-07-19
Updated: 2026-08-26
## Tailwind needs complete class tokens in detectable source
Tailwind dynamic class names fail when source code constructs fragments such as `bg-${color}-500` at runtime. Tailwind scans source as text and cannot reliably infer every finished token that a programming language might assemble. Map dynamic values to complete, literal class strings instead, then confirm the source path is detected by the installed build setup.
The debugging guides in [build workflows](/build-workflows/) begin with the token, not with random cache demolition.
## See the difference between values and class fragments
This pattern hides the final utilities from static detection:
```jsx
function Badge({ color }) {
return ...
}
```
At runtime, the browser may receive a plausible class. During the build, however, the source contains fragments rather than complete tokens such as `bg-blue-500`. CSS for the assembled result may never be generated.
Use a lookup whose values contain complete classes:
```jsx
const badgeClasses = {
blue: "bg-blue-500 text-blue-950",
amber: "bg-amber-500 text-amber-950",
}
function Badge({ color }) {
return ...
}
```
Validate `color` before lookup and provide an intentional fallback or error behavior. The mapping is both detectable and reviewable: every allowed visual choice appears in source.
## Diagnose a missing class in five checks
### 1. Inspect the rendered token
Use browser tools to confirm the element received the class you expected. A typo, empty lookup, conditional branch, or component prop can fail before Tailwind enters the story.
### 2. Search the generated CSS
Confirm whether the selector exists in the built output. If it exists, investigate cascade, variant conditions, or invalid markup. If it does not, continue toward source detection.
### 3. Search source for the complete token
Use exact search. If only fragments exist, replace construction with complete strings. Do not assume the scanner evaluates JavaScript, template code, or a content database.
### 4. Verify the source location
Check the official documentation for how the installed Tailwind version detects source files and how the project’s integration supplies them. Monorepos, external packages, generated templates, unusual extensions, and ignored paths may require explicit handling.
### 5. Run the real build
Use the project’s documented command and inspect its output. Development and production pipelines can differ. Work on a branch and review configuration changes before deployment; a broad source rule can increase output or include files that were never intended as templates.
## Do not turn user input into utility names
Mapping user-controlled values directly into class strings is unreliable and can create unreviewed presentation behavior. Validate input and translate it through a finite mapping of approved complete classes.
When a value is genuinely continuous—an arbitrary measured position, for example—a CSS custom property or inline style may represent the data more honestly than trying to manufacture limitless utility tokens. Review security and content policies for the framework and application context.
## Keep variants complete too
Responsive and state variants must remain part of the literal token:
```jsx
const layouts = {
compact: "grid-cols-1 md:grid-cols-2",
wide: "grid-cols-1 md:grid-cols-3 xl:grid-cols-4",
}
```
The [responsive design guide](/tailwind-responsive-design/) explains how those variants cascade, and [layout patterns](/layout-patterns/) keeps the base layout visible.
## Treat configuration as the last scoped fix
Sometimes a class must originate outside ordinary source files. Follow the installed version’s official source-registration or explicit-inclusion mechanism rather than copying an option from an older tutorial. Tailwind’s configuration surface has changed across releases.
Before changing it, record the missing token, its true source, why a literal mapping is insufficient, and how the generated output will be tested. A fix should make a defined content source visible—not invite every file on the machine to the CSS build like an open-ended reunion.
## Frequently asked questions
**Why does Tailwind not generate my dynamic class?**
The source may contain fragments rather than a complete token, or the file may not be included in source detection. Inspect the rendered class, search generated CSS, search source for the exact full token, and verify the installed version’s source configuration. Tailwind does not generally execute application code to discover every string that could exist at runtime.
**Can I use template literals with Tailwind classes?**
Yes when each possible Tailwind token still appears as a complete literal in detectable source. A template literal that concatenates utility fragments can hide the final token. Prefer a mapping from application values to complete class strings. Ordinary interpolation for non-class text is a separate issue; the important boundary is what the Tailwind source scanner can detect.
**How should I map component props to Tailwind classes?**
Validate the prop and map each allowed value to a complete, reviewed class string. Provide intentional fallback or error behavior for unknown values. This makes the generated possibilities visible to Tailwind, code review, and tests. Avoid placing unrestricted user input directly into class names, especially when a finite set of visual variants is what the component actually supports.
**Should I add every missing Tailwind class to a safelist?**
Do not begin with a broad inclusion rule. First determine whether the token can live as a complete literal mapping and whether the source file is detected correctly. When classes truly originate outside ordinary source, use the explicit inclusion mechanism documented for the installed Tailwind version and keep the scope finite, reviewed, and tested against generated output.
**How do I check whether Tailwind generated a class?**
Run the project’s documented build, then search the generated CSS for the expected escaped selector or inspect it through browser developer tools. First confirm the rendered element received the intended token. If the selector exists, investigate cascade and variant conditions; if it does not, inspect literal token detection, source paths, version-specific configuration, and build differences.
---
# Tailwind Responsive Design: A Mobile-First Guide
> Tailwind responsive design is mobile-first: unprefixed utilities define the base style, and breakpoint-prefixed variants apply from their configured minimum width upward until another rule overrides the same property. Build the narrow layout first, add only necessary wider changes, and test continuously around every breakpoint. Verify breakpoint names and values in the installed project because Tailwind versions and project themes can differ from current defaults.
Source: https://tailwind-tools.com/tailwind-responsive-design/
Publisher: Utility Draft
Published: 2026-07-19
Updated: 2026-08-26
## Write the base layout first, then add breakpoint changes
Tailwind responsive design is mobile-first: unprefixed utilities apply at the base, while breakpoint variants apply from their breakpoint upward unless another variant overrides them. Start with the smallest practical layout, then add only the changes needed at wider widths. Check the breakpoint definitions in the installed project rather than assuming every codebase uses the framework defaults.
The patterns in [layout patterns](/layout-patterns/) focus on that cascade, not on collecting prefixes like souvenir magnets.
## Read a responsive class list from left to right
Consider a card grid:
```html
```
The base is one column. At the project’s `md` breakpoint, it becomes two columns. At `xl`, it becomes three. The variants do not describe isolated devices; they describe minimum-width conditions defined by the project.
Do not read `md:` as “tablet only.” It continues applying above that breakpoint until a later rule with suitable precedence changes the same property.
## Design around content, not device nicknames
Resize the actual interface and note where content becomes cramped, lines become excessively long, controls collide, or empty space becomes awkward. Those are useful breakpoint signals. A catalog of current phone widths will age faster than the layout.
Use the smallest number of breakpoint changes that preserves a readable structure. When every utility receives three variants, the markup becomes a tiny weather map and future changes require forecasting.
## Override only the property that changes
Tailwind variants participate in normal CSS behavior. If the base element has padding and a wider layout changes only column count, do not repeat the padding at every breakpoint.
```html
...
```
Here padding changes once. Other base utilities remain in effect. Group related layout utilities in a consistent order chosen by the project so reviewers can see the base and its overrides together.
## Test the range between named breakpoints
Do not test only at the exact breakpoint values or a few familiar device presets. Drag through the entire available range and inspect:
- just below and just above each change;
- long headings and translated text;
- zoom and larger text settings;
- keyboard focus and reordered layouts;
- empty, short, and unusually dense content;
- nested components inside narrow containers.
Viewport breakpoints do not know how wide a nested component actually is. When a component’s behavior should follow its container, review whether the project’s installed Tailwind version and browser-support requirements make container queries appropriate, then follow the current official documentation.
## Debug from generated behavior backward
When a responsive utility appears inactive:
1. confirm the viewport or container condition is actually met;
2. inspect the computed style and winning rule;
3. confirm the complete class token exists in source;
4. verify the project’s breakpoint configuration;
5. check whether another variant changes the same property;
6. rebuild using the project’s documented command.
Do not delete caches, rewrite configuration, or upgrade dependencies as a first reflex. Those actions broaden the problem before you have described it.
If a token never reaches generated CSS, the [dynamic class-name guide](/tailwind-dynamic-class-names/) explains source detection. More diagnostics live in [build workflows](/build-workflows/).
## Keep the installed version in the conversation
Official Tailwind documentation reflects its current supported release, while a project may use another version or customized theme. Before copying an example, identify the installed version, build integration, and theme variables. Use the project’s lockfile and configuration as evidence.
Responsive utilities are concise because the cascade does the carrying. Treat the base as the real design, variants as deliberate amendments, and breakpoint labels as configurable names—not prophecies about the hardware on the other side of the screen.
## Frequently asked questions
**Is Tailwind CSS mobile-first?**
Yes. Unprefixed utilities apply at the base, and minimum-width breakpoint variants add or override styles at wider conditions. This does not mean every unprefixed design must resemble a phone; it means the cascade starts with the base rule. Confirm the exact variant behavior in the official documentation for the Tailwind version installed in your project.
**Does a Tailwind breakpoint apply only at one screen size?**
No. A standard minimum-width variant applies at its breakpoint and continues above it unless another matching rule overrides the same property. A label such as `md` is not a tablet-only zone. Its value can also be customized, so inspect the project theme or configuration instead of attaching permanent device meaning to the name.
**How many Tailwind breakpoints should a component use?**
Use as few changes as the content and interaction require. Resize through the full range and add a breakpoint where the layout becomes cramped, excessively wide, or hard to use. There is no universal count. Repeating every utility at every breakpoint increases markup and maintenance without automatically improving responsiveness.
**Why is my responsive Tailwind class not working?**
Confirm the condition is met, inspect computed styles, verify the complete class token appears in a detected source file, and check the project’s breakpoint definitions. Another utility or variant may be winning the same property. Use the installed project’s documented build command before changing configuration, deleting files, or upgrading dependencies as a speculative fix.
**Should Tailwind breakpoints match specific devices?**
Prefer breakpoints driven by where the content or interaction needs a layout change. Device catalogs and viewport sizes evolve, while readable line length, available space, focus order, and control usability remain relevant. Named variants are configurable minimum-width conditions, not promises about a visitor’s device type. Test zoom, long content, and widths between presets.
---