Dynamic UI Styling with Tailwind CSS Arbitrary Values
Learn how Tailwind’s arbitrary values let you inject any CSS value directly into class names, solve repetition, and keep theme changes easy.
05 Dec 2025, 18:30 UTC

The Problem of Hard‑Coded Classes
When you start a Tailwind CSS project, you define a palette, spacing scale, and typography in tailwind.config.js. The system works well until you need a color that isn’t in the palette or a width that doesn’t match any utility. Hard‑coding a hex code directly in a class name, for example bg-[#ff5733], works for a single element but leads to duplication across components. Changing the brand color later requires a search‑and‑replace in many places, which is error‑prone and clutters the markup.
Arbitrary Values in Tailwind 3
Tailwind 3 introduced the arbitrary value syntax using square brackets []. The JIT compiler parses the content inside the brackets and emits the exact CSS rule at build time, so you can write bg-[#123456], top-[117px], or text-[var(--brand-primary)] without adding the value to the config.
Because the arbitrary value is resolved during the JIT compile step, it only appears in the final CSS if the element using the class is present in the files listed in the content array of your configuration. If you forget to include a newly added component, the generated rule may be omitted, leading to unexpected missing styling.
Dynamic Card Example and Practical Steps
Consider a dashboard card that needs a border color derived from a user‑selected theme variable and a background that follows a global CSS variable.
<div class="p-6 rounded-lg shadow-md border-2 border-[var(--user-accent)] bg-[var(--card-bg)]">
<h3 class="text-xl font-bold text-[#2d3748]">Status</h3>
<p class="mt-2 text-[14px] leading-relaxed">
Your account is active.
</p>
</div>
The class border-[var(--user-accent)] pulls the border color from a CSS custom property, while bg-[var(--card-bg)] lets the background adapt to runtime theme logic. The specific hex text-[#2d3748] keeps the header visually distinct.
Verify the JIT Output
- Confirm Tailwind version is 3.0 or newer:
npm list tailwindcss - Run the build and inspect the output file:
npx tailwindcss -i ./src/input.css -o ./dist/output.cssSearch
output.cssfor the exact value you used (e.g.,#ff5733or--user-accent) to verify the JIT engine emitted the rule. - Run watch mode to see if bundle size grows disproportionately:
npx tailwindcss -o ./dist/output.css --watch
Trade‑Offs and Limitations
- Arbitrary classes are not purged unless they appear in the
contentscan, which can inflate the final CSS bundle and risk unused‑class warnings. - Because the classes are generated dynamically, the JIT optimizer may include more utilities, increasing bundle size.
- If the same arbitrary value appears in multiple places, specificity clashes can arise, affecting styling precedence.
- Only valid CSS syntax works inside brackets; malformed values may be ignored or cause runtime errors.
Actionable Checklist
- Use arbitrary values only when a reusable token isn’t practical; otherwise add the value to
theme.extendintailwind.config.js. - Validate the generated CSS by searching the output file for the exact value.
- Monitor bundle size with the watch command and adjust usage if the CSS grows beyond expected limits.
- Regularly audit your CSS bundle to ensure the added rules stay minimal.
By leveraging arbitrary values you keep HTML clean, avoid polluting the config, and change themes without a massive refactor. The key is to use the feature judiciously and verify its impact on the final stylesheet. Developers should treat arbitrary values as a temporary bridge rather than a long‑term solution; whenever the same value recurs, extract it into the theme extension to keep the stylesheet maintainable and to benefit from automatic purging. Regularly audit your CSS bundle to ensure the added rules stay minimal.
0 replies
A thoughtful contribution can make all the difference. Be the first to share one.