https://nuejs.org/blog/tailwind-vs-semantic-css/ [logo] Tools Why FAQ Docs Blog [github] [menu] [tero] Tero Piirainen @tipiirai October 23, 2023 Tailwind CSS vs. Semantic CSS This study compares two websites with a similar design: A commercial Tailwind "spotlight" template, and the same site crafted with semantic CSS and Nue server components. We'll take a deep look at what is under the hood and how the sites are built. Tailwind UI version - Semantic version - Gist The semantic version is 8 x smaller, renders faster, and is easier to modify and extend. Front page HTML The main difference is that Tailwind uses "utility" class names and Nue uses semantic class names. That is: Nue gives meaning to the elements like nav, button, and .gallery and styles them with an external stylesheet. Tailwind styles elements inline -- directly on the markup. We can easily see the difference in the HTML markup by drilling down to the first element on the main navigation: Drilling down to the first element on the main navigation The semantic version is smaller because it utilizes high-level, semantic components like .nav and the external CSS can target elements with CSS selectors like body > header. Tailwind needs significantly more markup because the utility-first approach lacks the power of CSS selectors. You are forced to wrap divs inside divs inside divs and fill the elements with Tailwind-specific class syntax. Here is the full HTML source code of the front page. Full HTML coding on the front page Tailwind is 75K of unminified HTML, while the semantic version is 8K. That is: Tailwind and Next.js require [DEL:nine times more HTML:DEL] to render the same design than the semantic version. With Tailwind the Text to HTML Ratio is only 2.3%, which is "Very low" according to SiteGuru. Nue ratio, however, is 20.3% which is "Good". Front page CSS Let's study the difference in CSS coding: Full CSS coding on the front page Blue is semantic CSS, gray is utility classes, and black-bordered is primary CSS (which makes your pages render faster). Some key takes: 1. Tailwind CSS is seven times larger: 33K vs 4.6K. Overall you need eight times more HTML/CSS code with Tailwind to render the page (108K vs 12.6K). The most surprising thing is that Tailwind uses more global/semantic CSS than the semantic approach itself -\_ (tsu)_/- 2. Most of the semantic CSS is re-usable on other pages and only a fraction of the CSS is specific to the front page. It's easy to create new pages when the groundwork is already done. 3. "Spotlight" is just a theme extending a base design. There is an extremely minimalistic base-version of the website that can be used to create new themes, like our Spotlight theme. Creating a new design by extending a semantic base design Theming or "skinning" is a powerful concept in semantic CSS. You can alter your design by swapping parts of your CSS with another one or overriding a base version. CSS theming is impossible with Tailwind because the design is coupled to the markup. If you want a new design, you must edit your markup and override your earlier work. Rendering speed The two metrics that measure page rendering speed are first contentful paint (FCP) and largest contentful paint (LCP). The semantic version is faster than in both metrics and in both mobile and PC. Here's LCP on mobile for example: Largest Contentful Paint (LCP) rendering speed on mobile Please compare Tailwind metrics with Semantic CSS metcis . Two reasons why the semantic version is faster: 1. The primary CSS is inlined on the HTML page so that all the assets for the first viewport are fetched in the initial request. This is probably the most important performance optimization for the perceived page loading experience. 2. The first request is less than 14K, which is the maximum size of the first TCP packet. The Preview tab on the Developer console is a great way to debug FCP: Previewing the first paint on the developer console Best practices The key best practice of Tailwind is tight coupling. That is: the structure and styling are tied together. The semantic approach is the opposite: the structure and styling are loosely coupled**. Let's see what that means by studying the gallery component on the front page: Tight coupling vs Loose coupling The semantic version, allows you to change the design of the gallery freely. You name the component and style it externally. With Tailwind the style cannot be separated from the structure. Here's a better example. Let's look at the "Uses" or "Setup" page on both implementations: Tailwind UI version - Semantic version - With Tailwind you must create a JavaScript component to construct a suitable HTML structure for the design. With the semantic version, we can use Markdown in place of the custom JSX component because the generated HTML is semantic and can be styled externally with CSS selectors: Tight vs loose coupling from a different angle Loose coupling makes you think content first. There is no need to write a component for every situation because you can use external CSS to do the heavy lifting. But ... But naming things is unnecessary Naming things is a skill. You name things that repeat. Think of function names in JavaScript or component names in Figma. The same goes for CSS class names. Be good at naming, and you can move from repeating things to re-using things. That is: you can move from this: