The convention was never won
In 2003, the Web Standards Project pushed separation of concerns as orthodoxy: HTML for structure, CSS for presentation. The argument was partly practical — inline styles were hard to maintain — and partly ideological, shaped by the same decade that gave us XML. It settled into convention before most of its adopters had considered the alternatives.

Tailwind CSS, first released by Adam Wathan and Steve Schoger in 2017, does not write styles into the style attribute. It writes them as utility classes — flex, pt-4, text-gray-700 — directly in the markup. The distinction matters: the browser treats them identically to any other class selector, but the authoring experience lands them squarely beside the element they affect.
That proximity is the whole argument. When a component's styles live in a separate file, changing one requires tracking the relationship between selector and element. When they live on the element itself, that relationship is immediate and local. Tailwind's bet is that co-location, not separation, is what makes styles maintainable at scale — the same bet React made about HTML, four years earlier, when JSX arrived in 2013.
— has no single correct answer, only tradeoffs that were hidden while the convention held.
The counterargument is readability: a class attribute carrying fifteen tokens is harder to scan than a named selector. Whether that cost is worth paying depends on whether your project is component-driven. In a design system with small, isolated components, a long class string stays local and therefore legible. In a templating system where the same markup renders a hundred contexts, a named class still buys more than it costs.

Tailwind's own documentation frames utility-first as a pragmatic choice, not a philosophical position. That framing is honest. The question it reopened — where do styles belong? — has no single correct answer, only tradeoffs that were hidden while the convention held.
