Back

On Tailwind & @apply

Published on

January 1, 2024

Time to Read

Unknown

TODO:

  • Flesh out the rest of my points

  • Figure out post structure

  • Give examples

  • Test performance of both approaches

  • Post

  • commonly pushed arguments against @apply

    • Tailwind documentation says NO!!

Addressing each point of the Tailwind Apply Docs

  • You have to think up class names all the time

    • If you’re going to components your layout and styles using your Framework of choice as recommended by the same docs, you’ve already chosen the name for your classes
      • Eg. CompanyStatusCard === .company-status-card
  • You have to jump between multiple files to make changes

    • Same issue if you use Tailwind doc’s suggested method of moving CSS components to the tailwind global.css @layout module:

    • ![[Pasted image 20240612152328.png]]

    • If you use Svelte style tags, all your styles for an associated component are in the same file anyway, removing this issue in general.

  • Changing styles is scarier

    • As classnames using a methodology such as BEM, CSS Modules or Svelte native style tags already abstract away your layout from the implementation of your styles, its actually safer to change your styles because there will be no cascading and thus no global style overriding.
    • In fact, I’d be more worried about Tailwind as a library going out of fashion and then getting stuck with your Layout layer being peppered with an out of date and out of style (pun intended) style library. Which would be actually more reworking than just changing the implementation of a classname
  • Your CSS bundle will be bigger

    • As mentioned above, it’s much more of a problem if your HTML takes longer to load than your CSS as your HTML is the one that requests the CSS in the first place.
    • If you’re using a framework such as Svelte and Astro or SvelteKit, this should be handled at compile time and your CSS for a given page should be much smaller than a potentially bloated HTML page with inline tailwind styles all over.
  • don’t use @apply just to make things look “cleaner”.

    • Seems like tailwind devs want your code to be tightly coupled with their system
    • It’s not about looking cleaner it’s about being more maintainable
    • No one says “don’t use interfaces just to make things look cleaner”. No, we use interfaces (class names in this instance) as a way to abstract implementation details away from different parts of your application so when you need to swap out implementation details, you don’t break other parts of the system (HTML Layout code here)
    • Better developer debugging experience - CSS inspector is much more suited to classnames
    • Classnames are a layer of abstraction over the implementation of CSS. If you were to migrate away from Tailwind, you dont need to scrap all your components, you can just change your CSS inside the class
  • If you start using @apply for everything, you are basically just writing CSS again and throwing away all of the workflow and maintainability advantages Tailwind gives you

    • This is very odd to me, it sounds like Tailwind team is selling themselves short, as if Tailwind isn’t useful at all unless it’s inline, which is patently false.
    • Maybe they don’t realise that part of Tailwinds inherent ease of use comes from the fact that they made very nice shorthand’s for commonly used CSS. at the very least, I personally find myself messing around a lot less with which property I need to set in raw CSS because Tailwind has sensible defaults already defined for you
    • If Tailwind is really just a replacement for class names to avoid the common footguns of cascading style sheets, why not move back to inline styles on the elements?
      • Because it bloats your HTML
      • it’s very hard to read when styles get long
      • note: these pitfalls are also applicable to Tailwind at scale
  • Not pushing a particular CSS naming methodology, although I use BEM loosely when developing websites myself

  • If you’re targeting SSR, you need to be optimising for HTML page load size/performance

    • The bigger your HTML, the longer it will take for your user to download the page
    • The more inline CSS classnames, the longer it takes to compile your SSR page for rendering
    • Offloading CSS to build time speeds up performance per page
    • In SSR, each page will have its own CSS file, likely to be much smaller than a whole Tailwind distro even with trimming anyway
      • Argument that CSS file size is smaller is offset by how much bigger the HTML is
      • Browsers are much better at downloading and parsing many small files than a single large HTML page or CSS file
  • Performance Comparison

    • As close to Apples to Apples as possible
    • Inline Tailwind in Components vs BEM style Tailwind Components (Svelte + Astro )
  • Take away:

    • The key to frontend development in my opinion, you need to strike the balance between maintainability on the developers side and quality of experience for the end users
    • However, the performance and size differences between the 2 approaches barely differs, so in this case it’s best to lean towards maintainability and separation of concerns on the developers side. Use CSS modules or BEM (or both!) to keep your styles abstracted. It will make it easier to debug your styles in the DOM as well as changing your styles without modifying your layout layer in future

Structure

  • Background
  • Developer benefits
    • Looking at CSS Classnames as a matter of abstracting your layout from your styles
      • CSS Modules
      • BEM
      • Debuggability
      • Maintenance
  • User Experience Benefits
    • HTML size