Tailwind and the death of web craftsmanship
pdx.su
pdx.su
If most people have exposure/understanding to the Boostrap way of doing things, or the Rails way of doing things, then we as a system/company/team/organization benefit when new people join the team. There's already a well established way of getting stuff done.
If we forgo the use of a system, we will end up building one anyways. But this time, it will be known ONLY to your existing team members. It could/will buck convention and established best practices, it will grow to develop the bloat and technical debt for which the existing systems were rejected.
Software engineering is about trade-offs. This is just another trade-off.
Ultimately, I don't begrudge people for using whatever tool they find best. But I try to avoid Tailwind when given the choice.
Can you share some of those? I don't do much raw CSS so have no idea where it has gaps.
Another is attribute selector support. They have many common ones, but to do anything more complex you need to add support to your configuration. https://tailwindcss.com/docs/hover-focus-and-other-states#at...
I don't want to oversell this; I think Tailwind does a pretty good job covering the "happy path", and if you haven't run into any gaps I wouldn't worry about it too much. But you'll encounter its limits well before you encounter the limits of CSS.
It's an abstraction, but a poor one. It's too low-level to be truly useful, and it's also confusing as some properties doesn't mean the same as in CSS.
You end up with huge unreadable blobs, reminding me of the "write-only" label that Perl once used to have.
And the answer to avoid that unreadable blob is to include CSS, defeating the point.
I prefer CSS/SASS with variables for customization (so you don't have to repeat the blobs) and well-chosen class names (so you can actually read and modify existing code).
I miss some of the already established components from Bootstrap, but whatever. Bootstrap is always kind of a pain in the butt to integrate into a project.
With a really good design team, this isn't a problem, as the numbers are just pointing to something in a design document, but I've yet to see something that well done in the wild. And its not really that hard to make such a design system using css or preprocessor variables
Even if I don’t know what specific values m-2 may hold for a given project, I certainly know a lot more about it right off the bat than whatever .class-name you may have come up with from scratch, and can reference the config to know the rest.
Does it matter? Putting aside that anecdotally it seems very rare to override the default values for spacing anyway, m-2 is twice as much as m-1, which is whatever the baseline spacing for your project is.
Sure it can vary from project to project (though again, it doesn't seem awfully common for folks to do), but the config file is in your source control so m-2 is always consistent for the project you're working on.
Of course there is a big group of devs who use tailwind for easy copy paste templates that never change the config. But those who use as system use config a lot.
So anyone using Tailwind already has the setup to add tailwind.config.js into their project. They make it as easy as it can possibly be.
The reason why people don't change the config is that you need the default tailwind config for all the copy-paste-able snippets to work. People buy something like TailwindUI and copy what they find around. Including things like colors (which i find super stupid that the TailwindUI team didn't you know... use their own config OR css variables to be able to change brand colors).
And that kind of usage of Tailwind is lazy and you won't learn anything. But that's up to people. It doesn't mean Tailwind is bad abstraction or not possible to use for efficient design systems.
It's like being free from 1000's of levels of mundane resistance. It feels like going from writing assembly to some higher level language.
CSS finally GETS THE FUCK OUT OF THE WAY and lets me design as fast as I can think.
No project I have ever built, even the most "designey" have come even 10% as bloated as that input example he gave, so I have no idea what that is.
Nearly everything in this article I couldn't disagree more with. Maintaining tailwind (note GIVEN that you are using a SPA/JS framework, thats key) is one of the easiest things in the world.
I have complex layered apps with all sorts of directional changes, feature additions/removals, and its just as easy to modify this CSS without a hair tangle like traditional CSS or even CSS modules (albeit CSS modules are quite nice)
In cases where theres repetition within a single component, I will combine CSS modules + tailwind using @apply.
> There's been a rapid deterioration in pride-of-craftsmanship in development. It's naive to believe that "back in the old day" everyone wrote everything with a perfect eye towards beautiful craftsmanship, and now we just push code out as fast as we can. I remember having to use ugly CSS hacks to get IE to render things properly, or float clears to get containers not to shrink under an inline image. But there was definitely more interest in "doing it right" rather than dismissing it as a problem that wasn't worth solving.
Speak for yourself man - these are all unsubstantiated claims. I see absolutely nothing of the sort with my peers. For me personally, I care MORE about craftmanship than I ever have when I have brilliant tools that allow my input->output energy efficiency to reach nearly what feels like 100%. With Neovim + Vue/react + Tailwind + Room-temp superconductors I can design the most complex brilliant designs and systems, where I will launch entire features as a single developer, caring about every miniscule pixel perfect detail, all the backend coding, all the wiring together, the i18n, the 1px layout shift of a dropdown on android, the translations, EVERYTHING, and you will still be writing CSS and whining about "craftsmanship" having imaginary conversations in your own mind that doesnt in any way reflect reality
in other words, gatekeeping.
There's still value to being able to write at lower levels of language. Always has been, always will be. But having the higher-level languages lets you move a lot more rapidly, so long as the abstractions it makes for speed align with your goals.
For a lot of people, Tailwind's abstractions very much align.
I don't think it's inferior or superior, just a better approach for certain people.
Personally I've found Bulma to work well in conjunction with Django.
EVERY property must be explicitly specified. There is no "cascading" (inheritance). At first glance, this might seem like a horrible idea, but it has a TREMENDOUS upside in that everything is explicitly defined in the clearest possible way. (the style is directly ON that exact element. if you have a div inside another div, that inner div will not inherit font, colors, etc. You must define it all again).
The benefit of this is that everything can be "componentized" or split apart, and reordered, and moved around, and nothing will "break" stylistically. Your styles literally are perfectly attached to the structure. This is because EVERY single element is decoupled from EVERY other element, stylistically. This is truly the 100% stark opposite of traditional CSS.
A good example of this... is the very first time I googled a tailwind component, for some dropdown or something, I pasted the HTML + CSS classes directly into my project in some arbitrary spot, refreshed, and it looked PERFECT. I was literally floored and stunned! If you have programmed wordpress or other sites back in the day, and you know the true nightmare of trying to put some arbitrary bit of css or some script into your own projects and the styles are all conflicting, thats what I'm talking about. You know that pain. Even my BEST projects back in the day where I SWEAR to myself "im going to make THIS project the perfect CSS structure", ... after about a month i would be once again caught in these complex awful webs of conflicting and overwriting classes, despite my very best efforts.
Now there are downsides to this as well, but they're mitigated by using a component framework:
First, Because everything must be explicitly defined in EVERY place, this obviously creates a lot of duplication. After all, this is the entire point of CSS classes. Lets say you have a shopping cart item in one area of the app, the main listing, and then you want to show it again in your shopping cart. Youd have to define those style classes twice using tailwind if youre using a standard app which has "layout files" and "views". Now a component based framework though means you can make a component called <ProductItem /> and define the classes ONCE in that component. In this sense, a component almost becomes a much more advanced replacement for a CSS class (in a sort of weird and twisted way).
Lets take it further, and say WITHIN the product item is some text that looks like this: "Reviews (5) [NEW]!" And its styled a certain way. Now lets say that same style text appears below a different type of "review" and not a product item. In this sense, you can't use <ProductItem />, but you could make a new component called <ItemMetaInfo /> and then write your class in there (once), and extract that out to a component. There is a sweet spot to extracting out components vs a slight amount of duplication (say...5%). This also aligns VERY nicely with the entire purpose of component based frameworks is that the complex logic lives within the component... so lets say your <ItemMetaInfo /> grows in complexity over time, maybe it shows literal star SVGs, or supports multiple A | B | C sections based on an input parameter. That complexity can live in that new component along with the tailwind classes, defined once.
The second downside is its a LOT of typing, and this is where tailwind really excels to me. The properties you type are a god send, and SO much faster, easier to remember, and everything. This is coming from a vim freak who has memorized and written thousands of hotkeys and macros over nearly 15 years for CSS, and 100's of projects over the years. With tailwind, you do NOT need editor completion or anything like that. Its SO fast that it feels "effortless" in terms of the "ugh" resistance from writing CSS.
The best example of tailwind is right on their homepage: https://tailwindcss.com/
Scroll down about 100px and watch the realtime demo of them adding css classes and watch the design change on the left. It really IS THAT FAST to write tailwind classes and design THAT quickly, including responsiveness, and everything. This is 1000% not the same as css even with the very best macro/autocomplete setup.
Except this isn't the case if you ever touch any of the spacing[0] parts of tailwind. Then you'll suddenly have your elements growing margins out of nowhere, seemingly, and you once again have to look at the ancestry of an element to figure out why its being laid out the way it is.
Those seem to ignore the spirit of what I'm saying though, as firstly, no one says you have to use them if you truly want 100% decoupling. They're just convenience functions.
If you want to control margins based on component indexes and only use margin, then great.
Secondly, they're quite simple to understand.
They're also not out of nowhere, they're out of what you explicitly define as say, space-x-4. Having this be on the parent just makes great intuitive sense, that it wouldn't be defined on the individual items. If I see items evenly spaced I don't even have to think about it that it's obviously on the parent. The mental overhead of this is truly negligible.
I would argue that "spacing growing out of nowhere" is an order of magnitude more painful when using traditional CSS that has grown beyond the "perfect" starter phase of every complex app that uses normal CSS. And I've even tried using all the different CSS frameworks from back in the day where you write classes in certain ways with prefixes, etc etc. It is inevitable that eventually you get so much tangled and dead code, the mental overhead of that is now something orders of magnitude more.
While we are talking about that, you mentioned it being bloated. Your argument is that it takes "CPU" cycles... I forget the exact article (and exact details, paraphrasing), maybe it was github. Classes outperform inherited CSS tremendously, and I think it was github that tried to design their site using 10's of thousands of 1-level-deep classes instead of nested. This is just nitpicking, however. With tree shaking, I have an entire app that sees millions of visitors per month get a 3kb css file when gzipped. The bulk of the js (compiled html) takes up < 100kb for the entire app. I don't think even the most "lightweight" wordpress theme or what have you comes close to that. I just googled "most lightweight high performing wordpress themes" and some blog spam has most of them weighing in at 900kb-1mb (!!!).
What got me to convert to using Tailwind on projects (after a lot of reluctance) was styling variants. How to handle edge cases in your CSS empire.
For modern CSS practices, he gives a good example in the article of creating a button component with scoped styles. At first, that seems to work really well. But now use that button in unique and unforeseen location where it really needs left margin. There are SO MANY little scenarios like that which will creep up in actual usage.
You could target the button via id or perhaps a class on the parent, but making adjustments that way is not really fun, maintainable, or repeatable.
So then the next step is creating a few utility classes so you can easily apply a bit of margin, padding, etc. But now you have to decide what stays in the .button class and what properties to make flexible via added utilities. Pounding your head on the table brings you to the same conclusion Adam (the Tailwind creator) reached: it sounds crazy, but may I could only use utility classes...
Tailwind is certainly verbose. But it's very readable, explicit, and easy to debug. Wait... why is this button blue? Ah, I see right here in context... because it has bg-blue-600 applied.
The cascade is powerful but also tricky... it can be hard to determine where and when across global and local style that a piece of html picked up a certain color, size, or property.
I'd say this: Do what works for you and your team in the moment.
In 2023, I am a super hard-core vanilla-only web developer. My websites typically work without javascript and are completely rendered before they leave the server. I parade around HN advertising MDN as the Bible. Google is evil and Firefox is our savior. This stuff feels like religion to me.
Back in 2010 when I was responsible for the first website I was ever being paid real money to work on, I reached for Angular 1 and then happily upgraded to Angular 2 when it was time. Used bootstrap CSS for everything (aka the original back in 2011). I didn't stop using bootstrap CSS until ~2020. That was the last 3rd party item I dropped from my tool belt. RiotJS was the last JS framework I ever used and it got kicked to the curb some time around when Blazor was released.
10+ years is about how long it took me to completely lose my webdev training wheels. I think in many contexts (i.e. working with juniors and large teams), you are still going to want some sort of structure even if you personally don't need it. In our shop, I decided to establish and maintain that structure in-house. Our team is small and willing enough. In a larger shop, you will likely fail at DIY frameworks but I'd be the last one to say you shouldn't try. If you do succeed, nothing can compare.
To not leave this comment with simply a hand-waving disregard of this post, let me say this: Nobody who knows what they are doing writes Tailwind styles as long as the ones presented in this post, nobody uses arbitrary styles or custom styles as many times as is presented in this post, and yes (in a shock to nobody)- it is quicker to write "m-2" than write ".[my unique, non conflicting class name (usually incredibly arbitrary to avoid conflicts)]{ margin: 10px };" and then implement that in code. Usually, when you try to write pure CSS efficiently, you just end up basically duplicating Tailwind by creating utility classes anyways, except minus all of the actual perks of JIT.
At this point in time, if you say that you see no benefit in using Tailwind, you are being obtuse.
That sounds a lot like no-true-scotsman.
The big image of the overstyled checkbox is from Netlify's admin dashboard.
You literally defended CSS in a similar way in your post "The cascade, selector chaining (see above), and specificity are all very powerful tools. If you misunderstand them, yeah you can cut yourself. Just like if you don't use a saw properly you can cut yourself.". In the same sense, just because some people write super long Tailwind classes doesn't mean that you can extrapolate that to all Tailwind classes.
Maintaining and debugging code (yes even styling) takes much more time than writing it in the first place. Which is why readability is so important, and why Tailwind's approach of big unreadable blobs is so jarring (it doesn't just make the styling hard to read, it also makes the surrounding markup hard to read).
> Whenever I see someone make such a statement, I can tell it's more of a propaganda piece than a piece meant to spawn logical thought.
come across as pretty absurd. on whose behalf is the author supposedly writing said propaganda for? Big CSS? the guerilla antitailwindist movement?
the irony is you accuse the author of being emotionally biased, yet claim objectivity yourself, while defending said supposed objectivity with language that is far from dispassionate. this may resonate with other tailwind enthusiasts like yourself, but to the outside observer who has no investment (emotional or otherwise) in being either for or against tailwind, it comes across as far more overemotional (to the point of mild absurdity) than the author did in TFA.
this ends up having the opposite of what I must presume to be your intended outcome: it leads to the outside observer, reading these comments with mild interest to determine whether or not tailwind is perhaps worth another look since they checked it out last time, to be dissuaded from investigating this tool you like to use any further.
I truly mean no disrespect by this, but have you considered that other people might be better than you at writing CSS? Because what you are describing is absolutely not a universal experience.
Anyway, here's one common scenario for me: I need the same set of styles on multiple elements. With Tailwind, it goes one of a few ways:
- I duplicate the styles on all of the elements
- I abstract the data into some sort of loop and add the styles to the single element in the loop body
- I create a component, add the styles to that component and use that in place of each element
All of the above gets harder if there are existing elements that share some of the same styles, because I now need to identify the subset of styles that must be extracted. It's even worse if it happens across different tag names, because I then need to introduce branching into my abstraction.
Meanwhile, with CSS, I just give each element the same class name and add those styles to that class name.
I think this is what the author is getting at by saying Tailwind is far to the "write-only" side of the spectrum. There's no argument from me that just writing `m-2` is faster than adding a class name to the element, going to my CSS file and writing `.classname { margin: 0.5rem; }`. But that's only the first part of the process.
I’ve enjoyed using Vanilla Extract https://vanilla-extract.style/. It’s like css-in-js with none of the downsides as everything gets compiled to css.
I like tailwind so I prefer the class short-hands and composability.
Once I hit several styles on an element or obvious component styling (a la "primary-button") I just make a class with @apply.
Not knowing what m-3 is is the whole point. You use it across the website to have some consistency in your spacing, and not just slap around another 8px.
Yes, you can also do that with CSS variables, and Imho at times I do think that bootstrap for all it's faults is a better base design system, especially for internal admin interfaces.
If I'm given a design that specifies a margin of a different size than those we have defined in our style guide, I bounce it back for revision. If it all conforms to the style guide, it's easier to write, it's easier to maintain, and it just looks nicer.
Things like Tailwind (and formerly Bootstrap) are popular because they are easy to use. It's straightforward, brings results quickly, you don't need much of an artistic eye nor do you need to learn advanced CSS.
The author sounds like a CSS master/guru. The problem is that the typical web developer sucks at CSS. They know like 10% of it and much of that limited knowledge is outdated. Very few of them are going to level up anytime soon, hence your working situation is that you have multiple "amateurs" that barely have any clue what they're doing fighting the cascade. That's how you get disastrous unmaintainable CSS.
Tailwind is McDonalds.
...
> One of the bits of advice Tailwind gives is to use @apply and extract common blobs of CSS into common classes2. > Why bother to even use @apply? Just write the damn CSS
If you take a look at the official Tailwind docs (https://tailwindcss.com/docs/reusing-styles#extracting-compo...) they say:
"If you need to reuse some styles across multiple files, the best strategy is to create a component if you’re using a front-end framework like React, Svelte, or Vue, or a template partial if you’re using a templating language like Blade, ERB, Twig, or Nunjucks. ... While it’s highly recommended that you create proper template partials for more complex components, you can use Tailwind’s @apply directive to extract repeated utility patterns to custom CSS classes when a template partial feels heavy-handed."
So Tailwind recommends the use of components/template-partials as the way to reuse styles (e.g. your styled button HTML with classes goes in `button.html` and you reuse that for each button) because they think reusing styles in the traditional CSS way via classes doesn't scale (https://tailwindcss.com/docs/utility-first).
I know it's trendy to bash modern webdev here but people criticising Tailwind should at least try and understand the Tailwind approach first. Same with comments like "it's just inline styles" - they cover common knee-jerk reactions like this in the docs (https://tailwindcss.com/docs/utility-first#why-not-just-use-...).
You know how it's popular now to prefer composition over inheritance in OOP languages because it scales better? Tailwind is more like that, whereas CSS is more about preferring inheritance via cascading rules. Tailwind advocates their approach scales better to complex custom web designs. If you're just styling basic documents, you're not going to see much benefit.
With traditional CSS, you would assign a class to each UI component and then write custom CSS for each one. Usually people try to share CSS between classes but then you have to be really careful you don't break unrelated components as you make changes later.
Read the Tailwind links above to understand more about the pros/cons of each approach.
I actively go against their "just create a component" strategy and I find it overcomes all the Tailwind limitations.
Could you explain the problem more? There's lots of Tailwind based component systems that have reusable button and card components you could look at for ideas how to structure this.
In comparison, reusing traditional CSS is usually a nightmare because the CSS for a single component is usually spread across multiple files and difficult to disentangle. That's part of the problem Tailwind tries to solve.
The tone of the article rubbed me the wrong way as well. Pointing to a couple of examples of bad Tailwind usage and then making the sweeping generalization that using Tailwind is equivalent to "the death of web craftsmanship" is completely over the top.
Sure, using Tailwind means that you won't have lots of one-off "craftsmanship" in writing CSS. But that doesn't mean there's no craftsmanship. It just means that the focus of the craftsmanship moves from writing nice CSS to designing nice boundaries between your HTML components.
But what do I know? I've only been writing semantic HTML and CSS professionally for 18 years.
I am not sure what is the solution to the time problem. I foresee it will only get worse now that there is also AI in the mix.
1) Adding it to an existing codebase with lots of global scope. The techniques espoused in the documentation simply don't work well with existing leaky CSS with varying levels of specificity. Adding important to all TW classes and name-spacing all of them invites new problems.
2) Making your own components with lots of variants: the syntax required feels like you're doing contortions to make it work nicely. There's probably some special techniques but it's a lot easier to take advantage of the cascade in my experience.
3) Dev tooling: the OP I think is dead-on in the criticism that you break a lot of browser tooling when using Tailwind. The right hand side of the Elements tab is a complete disaster. The JIT that Tailwind provides to only include styles you need also makes things annoying: If I want to add some classes on the fly in the Elements tab (which is annoying anyway by having to edit HTML), it won't work if you need any classes not currently not used in the built code. You can mitigate this with modifying your JIT setting for dev to include a ton of classes but it just doesn't flow. The TW documentation is very cagey about how dev flows should work and for good reason.
I actually like utility classes as a concept and if I were starting greenfield projects I might consider Tailwind with an existing component library despite the dev tooling issues. I just think it doesn't layer onto existing codebases well.
2) They have a couple of pseudo-selectors but just largely don't use them if we need the cascade. We just write vanilla instead, but it's funny how often that isn't required. When things need to be dynamic we'll often use the classnames library.
3) This is really interesting because we haven't really experienced this. I wonder if it's framework or ecosystem specific. I often find opinions vary broadly across these lines because of what you noted about the variance in dev flow.
Hold on... this is an incomplete thought. What did they say to do instead?
I'm serious. Did they built a pretty good system with Ruby on Rails, Java, or Laravel instead? Did they just use stock JavaScript without a framework? There are perfectly legitimate reasons why a developer might say that, for a certain organization, React is completely unnecessary and a symptom of overengineering. Also, for the few people writing new web apps in 2023 that don't require JavaScript, good for them.
Uh.. I don't think this author knows what BEM is
Honestly, a lot of the negative sentiment comes from how the tailwind 'community' acts and positions themselves.
The tailwind home page feels tamer now than before, but the tone is still there.
Adam’s replies on twitter have always been a problem. I’m not going to go searching old tweet replies, so you can think I’m talking out of my ass if you want. But the guy is an ass. A lot of the responses to even neutral articles were whining manbabyish stuff (yes that’s subjective opinion). I haven’t seen it lately, so I’m hoping someone had a talk with him.
RE "you can't chain selectors": you can stack modifiers like `dark:hover`. The example of having the same styles for hover, active, and focus actually seems Not Great as those are different states that you 99% of the time want to look visually different (Tailwind examples include things like hover:bg-blue-600 active:bg-blue-700 which just seems like a better guardrail)
RE: RE: You can't chain selectors. Its still a valid issue, a lot of styles you would want to apply text decoration to hover/focus/focus-visible, but not the visited, active, or plain state. You still have to write `hover:underline focus:underline focus-visible:underline`.
What I mean is something like this:
.Card {
@apply p-2 bg-gray-100;
&.--red {
@apply bg-red-200;
}
}
Now, the docs (and the founder) are vehemently against implementing Tailwindcss like this, but it makes the code really readable and reusable. Adding "@apply ___" in my SCSS is much more compact than writing out full CSS, and I think much more readable. Plus, I get to apply whatever CSS that are out of scope of Tailwind. Win win.Basically its tailwind without all the classes, and without apply, in pure CSS variables
The problem I'm solving for is NOT having to find/replace every tailwind-spam across several projects/components/frameworks if I want to add a new "color" property to a .Card, or change the padding, or whatever. I just change the source utility, then link to the file (with Git / package.json linking), so the one change can be applied across projects.
If I followed what the founder and docs said, I'd have to spend every waking hour find/replacing text across all my projects.
If you're just going to stick the tail wind classes in a class like this, why bother? just use css vars.
I've been using Tailwind in combination with "normal" CSS where it's warranted and there are plenty of sites out there practicing the same thing. Atomic utility classes just make sense for some things. It's a tool that you can use correctly or incorrectly.
Yes, a developer will read 100 lines of code for every line they write, so the DX is important. But the number of times you read the code pales in comparison to the number of times the page gets loaded by a user. Being able to build that quickly and move on is so much more important that having a lot of classes on your p tags.
In all honestly, I just couldn't care less about "web craftsmanship", I have bigger problems to focus on than today's incredibly messy DOM. Bootstrap allows me to quickly represents my designer's design system through an set of hammers (classes) that allow me to quickly convert work, plus with modern flex styling I really don't run into complex DOM rendering issues anymore that would require me to really dive into the styling and debug.
https://www.themoviedb.org/movie/13020-enron-the-smartest-gu...
However, Tailwind is definitely not the solution, as it is the same as adding a style attribute to each html tag and writing the style in the html. What is valuable about Tailwind imho is the concept of utility classes, which can be accomplished with vanilla css variables.
Now I use tailwind and I've learned their wonderful little syntax for mr-x or py and it does feel a little like inline style days. But I do make this file https://github.com/andrewarrow/settle-down/blob/main/assets/... with some stuff so I can say like "btn-main" over and over.
I would recommend you to try Open Props [0], which you can use with Tailwind CSS, and see how what we all really crave is a good utility class system.
I didn't say Tailwind isn't an abstraction. It absolutely is, but it's a minimal one that is transparent. Every class does exactly what it says, nothing more, nothing less.
Tailwind has tons of good escape hatches, and many of these arguments about terrible maintenance are just rubbish. I use the developer tools with Tailwind all the time when debugging. I just pick a test case, write an inline style to demo an override, then go back and update my styles. I still write a lot of custom CSS when it's called for, modern features, included with Tailwind. Now it's easier to spot those more complex features in a much shorter stylesheet.
I've explained carefully to my junior developers that Tailwind is a tool to make it easier to generate and manage a standardized, reusable design language in CSS that is expressed through JavaScript without inflicting a performance penalty on the end-user. It's not a panacea. As much as it has grown and prospered, we still look at it as an extension of PostCSS, not a replacement for CSS. I stress to my team that learning and writing real CSS is still necessary, and that our goal should always be to look out for ways to not use Tailwind or to eliminate it when it makes sense to do so.
I'd love to hear more about scoped styles, especially why they were deprecated by browser vendors. I'd be interested in seeing some data about performance penalties from HTML parsing too. I personally haven't noticed anything that could make a difference no matter how "ugly" it is. I guess I just want to stress my/our open-mindedness. I don't understand why Tailwind has become such a religious topic of discussion for CSS. I remember when writing CSS was a lot harder before Tailwind and lots of other really nice CSS features were around. I feel like we've come a long way.
A craftsman should know about all the available tools, about their trade-offs and when to apply them. Completely dismissing a concept and offering a "magic bullet" is the opposite of web craftsmanship.
The reality for better or worse is it's good enough for most companies and engineers.
I like working with CSS and have been using it since it came out in the late 90s. Utility classes are by a large margin the best experience I've working with CSS, and Tailwind does it really well.
Also, people really have to stop with the: "But that's not what the original designers of CSS intended!" as if language designers have never made a mistake or a bad decision before.
That way if you dislike tailwind, just run some script and voila, you have your .css file you can edit separately, like a good old days
Scoped CSS doesn't seem to be a feature of CSS. The "scoped" attribute shown in his example apparently existed in some browsers a decade ago and has since been removed.
I guess maybe it's a Vue template feature that happens to reuse the same syntax?
I'd expect most component frameworks to have some equivalent version of this. In svelte, it's the default; all style tags written inside a component are scoped to said component.
You can largely achieve scoping manually if you have to, via nesting, which recently landed in CSS.