[HN Gopher] Tailwind vs. Semantic CSS
       ___________________________________________________________________
        
       Tailwind vs. Semantic CSS
        
       Author : tipiirai
       Score  : 59 points
       Date   : 2023-10-23 07:05 UTC (1 hours ago)
        
 (HTM) web link (nuejs.org)
 (TXT) w3m dump (nuejs.org)
        
       | tipiirai wrote:
       | Author here. I implemented the commercial Tailwind "Spotlight"
       | template with Semantic CSS and compared the differences in
       | weight, amount of HTML and CSS, rendering speed, and best
       | practices. I was surprised to find _that_ much overhead in
       | Tailwind. Curious to hear your thoughts.
        
         | pcthrowaway wrote:
         | Thanks for the thought-provoking comparison! I have a few
         | questions:
         | 
         | - Did you compare both versions of the page for feature parity
         | across multiple browsers, devices, and breakpoints?
         | 
         | - _what_ exactly accounted for so much bloat with the tailwind
         | version of the site? Was it the CSS itself, or the classes that
         | accounted for most of the difference? If it was the CSS, did
         | you optimize it as per Tailwind 's docs[1] so that unused
         | styles weren't included in the final page styles?
         | 
         | - How much longer (if at all) did you take to design your
         | selectors for the semantic version in order to reduce
         | repetition, than you might have taken for creating the template
         | with tailwind?
         | 
         | - How did the final sizes compare after brotli compression?
         | 
         | [1]: https://tailwindcss.com/docs/optimizing-for-production
        
           | tipiirai wrote:
           | 1. Only tested with a handful of browsers and devices
           | 
           | 2. I did not optimize the Tailwind version. The Tailwind
           | developers did.
           | 
           | 3. I have no idea. I only did the semantic version. It was
           | quick, because I have done so much CSS in my life
           | 
           | 4. You can check that out yourself. Both sites are brotli
           | compressed
        
         | progx wrote:
         | Did or can you publish a small snippet of how Nue-CSS would be
         | implemented in or with Nue?
         | 
         | Can't wait to use Nue for my next project, currently wait for
         | CSS implementation (even if it is not necessary for Nue).
         | Project is currently in design phase, so i have luckily time.
        
           | tipiirai wrote:
           | Glad to hear this! I'm updating the create-nue project next.
           | It will clarify a lot of things. CSS pre-processor is the
           | next project to be published. I don't want to give ETA,
           | because I'll likely disappoint.
        
       | k4runa wrote:
       | I find Tailwind really good for prototyping designs and iterating
       | quickly, and as the design becomes more crystallised then I moved
       | to semantic css and start to clean up the complexity. Once I've
       | figure out that patterns and components required...
        
         | tipiirai wrote:
         | Makes perfect sense. Prototypes are all about doing something
         | very fast and all hacks allowed. Cleanup later.
        
           | k4runa wrote:
           | Yeah, cause I end up with like 5 different buttons designs
           | using Tailwind, and they all have different classes but when
           | I clean up the code later I reduce it down to one button
           | design that fits the final theme.
        
         | progx wrote:
         | But who really work like this? The most people and company
         | would not do this extra work and use tailwind for finished
         | products too.
        
           | k4runa wrote:
           | I figure most startups would build an MVP in two weeks and
           | then rebuilt it later or move onto the next version and clean
           | it up a bit in each version that follows.
        
         | thom wrote:
         | I've found myself wanting a Tailwind compiler that makes it
         | easier to work like this. Iterate fast with maximum verbosity,
         | but later extract common patterns to classes when things are
         | more stable. Anyone aware of any tooling like this?
        
           | k4runa wrote:
           | That would be nice, like a Webstorm / editor feature that
           | detects when you re-use code and recommends abstracting it. I
           | would love that to be able to detect that like "Hey these
           | buttons all share these features, let's refactor it for you"
        
       | gherkinnn wrote:
       | This is one of the first Tailwind vs * articles that isn't bad.
       | It makes a good case in the analysis.
       | 
       | For a lot of applications (like a blog), what the author calls
       | "semantic CSS" is the right thing to do. But there comes a point
       | at which it is no longer feasible. We have a long history of
       | SMACSS, object oriented CSS, BEM, CSS Modules, scoped CSS, and
       | now Tailwind to make it work.
       | 
       | > Because mastering CSS requires practice. It takes several
       | failed attempts before you get it.
       | 
       | Explaining the popularity of something by simply proclaiming "git
       | gud" isn't a very strong point. For newer CSS devs, it does take
       | away the woes of clashing naming and a badly structured cascade.
       | The rest remains and the results remain shite. Similarly, I
       | haven't seen a pattern where good CSS authors do not like
       | Tailwind.
        
         | sbergot wrote:
         | No this article is flawed. It fails to recognize the fact that
         | css and html are _always_ coupled in one direction or another.
         | With tailwind the css is fixed and the html is designed around
         | it. With semantic the html is first created and then you write
         | your css around it.
         | 
         | The fact is that updating css in a big project and a big team
         | is very difficult. Rules are scoped globally. It only takes a
         | junior making a few design mistakes and now you don't what you
         | are going to break if you update anything.
         | 
         | With tailwind the css is fixed and will never change. So you
         | just change your html and you know what to check/what to test
         | again. For any medium to large project this is a big QA & time
         | boon.
         | 
         | "just use code review, naming convention, xxx best practice".
         | This argument is similar to "just don't make mistakes".
         | Mistakes will be made. With semantic css you will suffer.
        
           | gherkinnn wrote:
           | > "just don't make mistakes". Mistakes will be made.
           | 
           | Is kinda what I said.
        
           | tipiirai wrote:
           | Author here. You are right: HTML and CSS are always coupled.
           | The major difference is that Tailwind embraces tight coupling
           | and semantic CSS embraces loose coupling. Please check the
           | "Best practises" section:
           | 
           | https://nuejs.org/blog/tailwind-vs-semantic-css/#best-
           | practi...
        
             | sbergot wrote:
             | This section is what I am talking about. You compare two
             | methods of writing components and then declare that the
             | tailwind version is tightly coupled but the semantic
             | version is loosely coupled. In programming lingo this means
             | tailwind is bad and semantic is good.
             | 
             | But you don't explain why the tailwind version is tightly
             | coupled and the semantic version is loosely coupled. And
             | you don't do it because it is simply not the case. The
             | coupling between html and css is not tighter or looser. It
             | just goes in a different direction.
             | 
             | > 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.
             | 
             | Same with tailwind. You update your component to update its
             | style. With semantic you can update the css rules without
             | touching the html, but you don't know if this css change
             | won't break another part of your design. If you have a
             | simple html structure like a blog with very few components,
             | then semantic works (but so does anything really). If you
             | have lots of components and you need to update them in
             | order to add new features, then semantic will bring more
             | issues.
        
               | tipiirai wrote:
               | Okay. So `<div class="gallery">` is loose coupling,
               | because the styling is not coupled into the component.
        
       | politelemon wrote:
       | The Nue server components link leads to a 404.
        
         | tipiirai wrote:
         | Fixed. Thanks!
        
       | earthnail wrote:
       | I just moved our website from semantic to tailwind after I didn't
       | understand the semantic bits anymore.
       | 
       | Main problem was: the semantic css was elegant, but understanding
       | it again after half a year of not editing the page took super
       | long.
       | 
       | Tailwind is clear. The code looks uglier but I instantly know
       | what's going on. No hidden things. And no fear in editing a piece
       | of html that it will break sth else.
       | 
       | Huge upside.
        
         | amjnsx wrote:
         | > but understanding it again after half a year of not editing
         | the page took super long.
         | 
         | Longer than converting the entire website to Tailwind?
        
           | earthnail wrote:
           | I wrote a new part of the website in tailwind to see what all
           | the fuzz is about. Then I decided to rewrite the rest of it.
           | 
           | It's a small website, but it's complex with desktop and
           | mobile layouts, audio players etc etc. There's a design
           | system behind it, but many small exceptions to it to make it
           | look really nice. Writing the new part of the website was so
           | fast with Tailwind that I just thought I'd give the rewrite a
           | go. It wasn't that painful, and while it definitely took
           | longer than understanding the existing bits just to edit sth,
           | it also allowed me to clean up the CSS mess that had
           | accumulated over two years.
           | 
           | If I had just sat down and tried to clean up the CSS mess, it
           | probably would've taken longer if I hadn't converted it to
           | Tailwind at the same time. And I needed to do some cleanup as
           | we were trying to tie different sub pages into a coherent
           | experience.
           | 
           | Just to clarify: please don't take this as advice of "go and
           | rewrite your code". Rewrites are almost always bad. But in my
           | case here, it was a good decision. My personal learning is
           | that a startup landing page just changes too much to be able
           | to fit into semantic classes nicely.
        
         | tipiirai wrote:
         | Indeed. This is a matter of taste. I personally find semantic
         | CSS much clearer. I move faster with it because I need less
         | code to achieve the same thing, and the resulting site is
         | leaner.
        
         | quickthrower2 wrote:
         | Copy paste for styling isn't as bad as it sounds. Obviously
         | with React you get components you can reuse. But manually
         | chucking out mb-2, mx-2, my-3 to get it to look nice to the eye
         | and having the same things repeat in different spots without a
         | "meaning" or "semantics" can be quite nice. For small-medium
         | size projects of course.
        
         | tuyiown wrote:
         | Yep ! This is the huge problem with css and <<meaningful>>
         | selectors, no matter how much you try to make things clear,
         | nuances and details fades and you end up going back end forth
         | between css code, inspector and HTML to figure out what's
         | happening.
         | 
         | Utility based css selectors that do one and single thing are
         | clear and explicit, removing most (but not all) that hassle.
        
           | tipiirai wrote:
           | Not all developers have experienced these problems. There are
           | people who prefer the semantic approach. I'm definitely one.
        
       | Loeffelmann wrote:
       | I don't understand why tailwind would force you to write more
       | divs then CSS. How do selectors solve the problem of how many
       | elements you need to use to achieve the same design?
        
         | tipiirai wrote:
         | Extra divs are wrappers that help you style the parent element
         | to add flex layouts for example. Or why do you think the
         | official Tailwind template has so many nested divs with utility
         | classes?
        
       | komali2 wrote:
       | For Tailwind all I ever do is copy big blobs of tailwind
       | "styling" text (classnames) into my components from someone
       | else's "tailwind components." Tailwind themselves even offer a
       | component library.
       | 
       | I always thought semantic css was easier and made more sense, and
       | when we were using Style Components we could still go ahead and
       | have the styling right there in the javascript code if we wanted,
       | best of both worlds, really.
       | 
       | But right now the whole industry loves tailwind so I use
       | tailwind. So I use react, er, nextjs. So I use webpack. So I use
       | yarn, or wait we're back on npm now right?
        
         | xoac wrote:
         | choo choo! all aboaard!
        
       | amjnsx wrote:
       | Thanks for confirming my suspicions regarding Tailwind. Their
       | marketing loves talking about how small the CSS file size is vs
       | semantic, but that code still has to go somewhere - and it's a
       | bait and switch of "smaller css" with the cost of an inflated
       | html file
       | 
       | * The irony being in this article is that the CSS file is also
       | larger
        
         | AmazingTurtle wrote:
         | tbf the examples brought up in the blog post omitted semantic
         | attributes such as lang and the whole dom structure (all the
         | divs!) and the other data- attributes just to make it look even
         | worse. OP is severely opinionated.
        
           | tipiirai wrote:
           | Sorry, which data- attributes? And what do you mean about the
           | semantic DOM structure?
        
       | oldnet wrote:
       | I never understood why use tailwind when I can have semantic css
       | without any extra unusable content.
       | 
       | Btw Bootstrapt is still there
       | 
       | EDIT: Semantic css is also bandwidth friendly for mobile
       | connection.
        
       | reddalo wrote:
       | I don't agree with this post at all. It seems like it's been
       | written by someone who never actually used Tailwind CSS: I had
       | the same doubts before using it.
        
         | progx wrote:
         | The post say not that tailwind is bad, it shows only that using
         | tailwind could end with huge code base and higher load times.
        
         | tipiirai wrote:
         | Author here. Not that it matters, but I have certainly used
         | Tailwind. I even reverse engineered the Spotlight code to
         | semantic CSS. Fully aware of the ins and outs of the TW
         | ecosystem.
        
       | ekzy wrote:
       | In my experience, it isn't black or white. I've used tailwind
       | along with components, e.g.
       | 
       | .button-primary { @apply rounded-full focus:ring focus:ring-
       | orange-500 ring-offset-4 outline-none px-6 py-3 etc...
       | 
       | and it gives you the best of both worlds. You refactor common css
       | code into components and still have the amazing flexibility of
       | utility classes.
        
         | tipiirai wrote:
         | Certainly not black and white. The article merely states that
         | you need less HTML/CSS code to do the same thing and the
         | resulting site is leaner and faster.
        
       | d1sxeyes wrote:
       | Tailwind excels when it's used on reusable components. Anyone
       | handcoding Tailwind for a full page will start to hate it
       | quickly.
       | 
       | But you can have the best of both worlds with apply:
       | .card {           @apply p-2 rounded shadow text-gray-700;
       | }
        
         | romanovcode wrote:
         | Exactly. This is a non-issue if you use @apply (as people
         | should).
        
       | cornedor wrote:
       | This is not a good comparison. The Neu implementation lacks a lot
       | of styling and features from the Tailwind CSS implementation.
       | It's not responsive, missing styles for a bunch of components,
       | using much simpler styles for other components.
        
       | izietto wrote:
       | What about a mix of them? Which is actually something Tailwind
       | expects you to do at some point, AFAICT:
       | https://tailwindcss.com/docs/reusing-styles
        
         | tipiirai wrote:
         | Seems legit. I personally use a mix of semantic class names and
         | utility class names. But without Tailwind.
        
       | audessuscest wrote:
       | That example with a million div for the nav with tailwind is so
       | ridiculous.
       | 
       | I agree with the conclusion but that first example is so
       | grotesque that it made me discard the whole article
       | 
       | One other advantage of tailwind is that it makes it easier to
       | work collaboratively with people of different css level and it
       | requires less review, less possible side effect. But it's clear
       | to me that clean semantic well developed css is way better than
       | tailwind.
        
         | tipiirai wrote:
         | > that first example is so grotesque
         | 
         | It's the actual HTML code in the sites that are compared
        
       | jacknews wrote:
       | Is this page ( https://nuejs.org/docs/nuejs/server-
       | components.html and others) broken for anyone else?
       | 
       | I can't scroll horizontally and only half the text is visible.
        
       | andix wrote:
       | Tailwind is not pretty, perfect or the best. It's a pragmatic
       | solution that works well for a lot of people.
        
       | gardenhedge wrote:
       | From the examples the tailwindcss one works on android Firefox
       | whereas the semantic one doesn't..
        
         | tipiirai wrote:
         | Author here: I'm sure there are a lot of corner cases since I
         | did not test with all the browsers. My main focus was on
         | writing, and explaining the differences between the two
         | approaches. When/if Nue provides official templates they will
         | obviously be fully tested. I expect the size of CSS grow by
         | 1-5%. Certainly not 7x.
        
       | vbezhenar wrote:
       | So given the popularity of tailwind I can conclude with
       | confidence, that semantic movement has failed. HTML does not need
       | semantics (because every big site is absolutely filled with divs)
       | and CSS does not need semantics either. Spending time thinking
       | about semantics is wasting time.
        
       | tmikaeld wrote:
       | The article makes a point when editing CSS manually.
       | 
       | I'm still waiting for a visual editor that take all of the
       | "semantic" parts and make it usable while still preserving this
       | cleanliness in the markup.
       | 
       | It's not so easy to "decouple" in this case..
        
       ___________________________________________________________________
       (page generated 2023-10-23 09:00 UTC)