The rise and fall of Bootstrap and how Tailwind became the go-to CSS framework
betterprogramming.pub
betterprogramming.pub
> This is how you write a card component with Bootstrap:
<div class="card"...>
<img src="..." class="card-img-top" alt="...">
<div class="card-body">
<h5 class="card-title">Card title</h5>
<p class="card-text">
...
> This is how you write a card component with Tailwind: <figure class="md:flex bg-slate-100 rounded-xl p-8 md:p-0 dark:bg-slate-800">
<img class="w-24 h-24 md:w-48 md:h-auto md:rounded-none rounded-full mx-auto" src="..." ...>
<div class="pt-6 md:p-8 text-center md:text-left space-y-4">
...
Let's be honest. All other considerations aside this does not make the case for TailwindIt doesn’t feel simple to me… there is just something about all these inline styles (that’s exactly what these utility classes become) that really turns me off.
Hickey’s talk is a very very great talk, but I fail to see its relevance here. All tailwind does is give names to often used css attributes and allows one to apply them very specifically. It has no strange abstractions going on, it is basically “developer WYSIWYG” for CSS styling
All of a sudden tailwind makes more sense.
With Tailwind there’s no consistency across developers. It’s all highly configurable, but no convention.
Components are locally consistent but not globally consistent.
Or, let’s say you want to change all your grey text to #777, then you have to go back through all your individual components and hope you didn’t miss anything.
So are your own custom defined colors like text-armatav-500.
Use the thing before you dismiss it.
You should have a design with a catalogue of components to build off of so you don’t have 30 card components.
It’s a your-team issue, not a Tailwind issue.
If you want an unsemantic one-off, you can do it just like Tailwind by setting a utility class like “p2”.
But the two examples are completely different, and I dont understand why they would do that. Surely the the benefit of an example is to point out how hard it is to do the same thing in the old system compared to the other. not have two wildly different examples and say "look, the other one is shite"
I think the idea here is "how is you accomplish the end goal in each, using their normal way of doing things". For example, if you were going to build a sorter in C vs Smalltalk, you would use procedural code for C and object oriented code for Smalltalk. Both would show how a sorter would be built in the style of the language in question (vs building an object oriented approach in C).
Separate css style sheets make sense for "document" web pages, but for "applications" I have found keeping the style close to, or inline with, the HTML much better.
Personally I prefer the concept of the "single file component" popularised by Vue. Having one file that contain the js, HTML and css in close proximity but not on top of each other works really well.
A common phrase used to describe this is "locality of behaviour".
You could say, perfect is the enemy of good, with almost every document you could easily get 95% there. That's true - but that 5% made the whole idea into a leaky abstraction. The more strict you were about the separation of content and presentation, the harder it got to deal with the 5% that were both - and back then, people were dogmatic about this.
Many of us here probably remember the CSS Zen Garden[0] - the site that demonstrated just how far you can go with CSS if you keep the content and styling separate. I used to be in love with this, but now I think the site did incredible damage to web developers of that era: by getting people excited about flexibility of CSS, it made people forget that any particular site they're building is not going to have 20 alternate stylesheets to choose from - rather, it's going to have one, and the content on that site will be created with a specific presentation form in mind. Devs and designers ended up chasing half-formed visions of what could be, without realizing those visions made no sense in practice.
(This of course doesn't mean that doing HTML and CSS in JS is a better idea. It's also a bad fad, just for different reasons.)
--
Every generation repeats the mistakes of the past, and every time "this time it's different". This time it's different because components.
I'm still well-disposed towards Tailwind and it provides ways to handle this. I was just amused that the example was so bad.
If you add this to the fact that you would actually write a <Component> and only specifically style that “inline” once, then you are actually better off with tailwind.
I mean, it would be a lot more useful if people used the Tailwind classes as primitives to compose site-specific components, which can be further changed locally.
Not classes, but components as primitives. You just go to the component’s definition and can see its style at a single place, right next to its structure without which CSS makes no sense.
Tailwind accepts greatly reduced DRY for straightforwardness. It's kind of like inline styles with training wheels.
I'd much rather do this type of thing in the CSS layer, but doing it inline has advantages. Mainly, I think the reason it's caught on is new junior devs get productive in it very quickly.
They prepackage bundled JS for interactivity, skipping over any build process.
There are also way more websites running bootstrap that need maintenance or enhancements.
These seem like a better fit for junior programmers.
I think tailwind has caught jr programmers because course sellers have had an easier time getting market share because there isn’t remotely as much (free) content, examples and docs about tailwind.
I think the influence of people with a vested interest in selling courses (like the hosts of Syntax web dev podcast) is what gets people to choose newer frameworks, not practicality or employability.
Yes, I agree, and that was more my point than any dig at Tailwind itself. Just because the article argues badly does not mean the argument itself is bad.
What the article (and many that are trying to introduce Tailwind) doesn't make clear is that Tailwind is purposely lower level than something like Bootstrap and it really exists to let developers make their own higher level framework.
In particular, the idea is that you use Tailwind's `@apply` to bundle your own components. So you would do:
.card {
@apply md:flex bg-slate-100 rounded-xl p-8 md:p-0 dark:bg-slate-800;
}
.card-img-top {
@apply w-24 h-24 md:w-48 md:h-auto md:rounded-none rounded-full mx-auto;
}
.card-text {
@apply pt-6 md:p-8 text-center md:text-left space-y-4;
}
Then your markup becomes <figure class="card">
<img class="card-img-top" src="..." ...>
<div class="card-text">
...
You basically can quickly build up your own replacement for Bootstrap out of components that fit well together, handle a lot of the messy implementation/compatibility details for you, and results in a bespoke framework with only exactly what you need and easy to change when you need to.I think most of the articles and documentation that don't make it clear that Tailwind isn't a direct replacement for Bootstrap, but something that you use to build a better Bootstrap do it a real disservice.
Anyway, I think `@apply` should be one of the first things mentioned when introducing Tailwind. That made it click for me.
I wish it didn't require building/compiling with JS, but I guess we lost that battle way back with SASS/LESS.
Seems like tt that point you're basically learning an entirely new syntax just to save time on typing a few characters.
His most valid point is how hard is to customize bootstrap theming options. The rest of his points are just a matter of taste.
Luckily, if you google for "free bootstrap theme builder", there are several free sites that let you point and click your way to whatever fonts, colors, etc. you want in bootstrap then download a bootstrap.css file that is a drop-in replacement for the one that ships out of the box.
I would use something like Symfony's Webpack Encore (but if I had to start over, I might use something lightweight like Parcel.js, I might migrate though), then let a "yarn watch" run in the background and it would re-compile in 2-3 seconds.
While I'm building my product and doing marketing and making sure it is performant and up all the time, I don't have too much time to adjust the details of the menu dropdown in mobile view (or even figure out how to do it).
Bootstrap also has utilities now (e.g. "py-md-3" for a large padding in the y axis - top and bottom - in larger screens) and that's good enough for me as a solo-dev for my own side project. Adjusting the border radius and the shadow in the "btn" class in the Sass already gives it a different feel.
It's even worse when it devolves into "X framework/library sucks" linkbait. Guess what, the only guaranteed worse library is the one you wasted time ripping out perfectly good code to rewrite
The point of bootstrap is to get something that's 90% of what you want FAST. And it can easily be customised to build a design system for yourself. With tailwind you have more foundational design work to do up front.
Personally I like the direction Bootstrap going, introducing utility classes, however there is more to do. My main wish is that they embrace web components for the JS side so that they are js framework agnostic.
As with all these tools you should evaluate what's best for you and your team.
I worked with a front end developer who used and liked tailwind. I always thought that Bootstrap was for people like me, it lets me get set up quickly, then I never think about the CSS on my sites again.
I think due to how prevalent vanilla Bootstrap sites are there is the impression that they all look the same. But it's actually a really good starting point for completely bespoke design systems too.
For what its worth, their communication style is often regarded as pretty great compared to other companies, they don’t fck around with things like “pricing change”, they plain out say they had to increase their pricing.
I'm a hardliner against CSS frameworks. Any time you learn a CSS framework, you're picking up a tool that is going to break or be made obsolete in a couple years. Just learn CSS right the first time and you're good forever.
That's why CSS frameworks are so popular. I can install bootstrap and make something not terrible pretty quickly. As someone new to programming to do the same in raw HTML and CSS is much much harder.
CSS is like global mutable state — it is too flexible to properly work when multiple people work together on it. Sure, I’m never against learning something from fundamentals, but I am on the opinion that it is increasingly the wrong default.
With Tailwind, you're not caught up in understanding the relationship between CSS and HTML which includes challenges like inheritance. Another benefit of Tailwind for new learners is the exhaustive documentation which captures all of the rules and their relationship in one place: it's hard to overstate the value of being able to look at a single page to fully understand how you can pad an element.
Certainly, there's limits to what you can achieve with Tailwind, but given it does expose a learner to the key principles of styling, it can then lead into an expanded learning of CSS if a user is interested in learning more -- you don't have to unlearn anything from Tailwind.
I can absolutely understand why someone would dislike Tailwind, especially those with pre-existing knowledge of CSS for whom this is a totally different way of styling, but to describe it as problematic for newcomers seems ignorant of where the real challenges of learning CSS are.
Can you provide more insight into the specifics of the issue? I am happy to try and diagnose the issue -- even if you've moved on from Tailwind, you might get value out of understanding the issue! A GitHub repository link would be ideal, or some code in a Gist :)
My gut feeling is that the issue you're describing has nothing to do with Tailwind. One of the challenges of learning any library or technology: you can experience an issue outside of the bounds of your understanding and misattribute the issue to the tool in question, even after decade(s) of experience, this'll still happen!
I’m sorry but to really learn CSS, you need to get this. The fact the TW abstracts this away may be easier to learn, but it does the learner a huge disservice if the don’t get what’s going on. Learning from first principles is always the best approach, even if the learning curve is slightly steeper, because it reduces a lot of mystery down the line when something isn’t behaving as expected.
I, personally, started writing HTML and CSS long before any of the tools we are discussing existed, CSS Zen Garden was state of the art back when I was learning… and nowadays I am very thankful that I don’t need to keep all of the esoteric aspects of CSS in my head when styling my HTML.
The most effective method for learning is the method that keeps the learner interested, and for most people, that’s the method that gets them to results the quickest. If you want to start learning how to make webpages by doing a deep dive on the DOM and WebKit, great, but that’s not the path for most people.
I would argue there's something to that.
Maybe hello world level Basic or Pascal or beginner Python first, but then assembly before C or Rust or even JavaScript. Something's been lost for the set of devs who don't know what higher languages are doing for them under the hood.
I'd similarly agree with ricardobeat that CSS frameworks should come after CSS, and JS frameworks after JS. Rapidly ascending abstractions is great, if you take long enough to understand what they're built with, and some things will always be solved more simply by dropping back down a layer or three.
* lvl102's comment was deleted: https://news.ycombinator.com/item?id=34764573
People that never go low level usually don't feel it in their guts how computers work. Which is OK most of the time, but it bites you back often enough that it's annoying having to explain the actual fundamentals when your colleagues haven't had that experience
Though to add a more relevant point, I read a great saying on HN that a good developer knows their stack. A great one knows a layer beneath as well. (I usually butcher up quotes, sorry. It may have been more layers actually)
I chose bootstrap over tailwind for my personal projects purely because tailwind looks terrible to read. For example the card example they chose. Div class"card" vs figure class"puke lots of classes I will easily forget" .
I think these two frameworks are aimed at entirely different types of people with entirely different goals.
I use it because:
1. It looks nice and users are familiar with it / it is a mature / proven system.
2. It’s fast. Drop in the CSS and I’m done fussing with CSS for +90% of situations. On with building the app.
The article ends with this conclusion: "My impression is that Bootstrap is declining." The article is the author's work with both, which is fine, but the title implies an industry trend, which isn't really supported by the article.
The article could have done this by pointing to statistical trends. However, I don't think the conclusion would then be supported. Just looking at NPM, they both are at their high points, suggesting it's not even a matter of competing. (I think Bootstrap has a larger amount of non-npm downloads, so that's not a perfect metric admittedly)
> Most of the time, you can tell easily if a website is running with Bootstrap or not, even if you’re not a seasoned developer. From my perspective, it doesn’t always sound like good news! Because when using it, websites tend to look the same.
Which is often fine for internal or B2B. For B2C, a unique look may be more important. Many apps are LOB, internal dashboards, B2B SaaS. Often customizing the brand colors is enough.
> With Tailwind, however, you can add your custom styles to almost anything. Why is that so important, you ask? First, because it allows you to design the website how you want it, this is great, especially for designers!
I'd say it's mainly great for designers, although there'll be overlap with developers for certain use cases. With the kinds of projects I work on, I don't generally find myself needing that. When I do, editing the CSS is easier than bringing in Tailwind.
> Look at easy it is! I don’t need to write custom CSS or Sass code. I just need to call the right classes to be able to use it. It’s really, really simple and yet powerful!
This is a bit handwavy. It isn't easier to use Tailwind vs. custom CSS per se. Do away with custom CSS and you're now just writing custom Tailwind. That could be good or bad depending on your team and tooling.
At some point there can be so many classnames on different elements that you basically arrive back at the original problem of complex stylesheets where you don't know what is affecting what.
Combine that with the fact that you need to have good knowledge to which CSS styles each classname refers, and I can see a lot of headaches down the line when someone has to fix the styles on a complex component.
Bootstrap and tailwind aren't really trying to do the same thing.
e.g.,...
One client wanted a dashboard for certain data... we chose a bootstrap template they liked and... we were done with many aspects of the visual design. The template looked good, was appropriate for the purpose, the client was happy, and development proceeded to the parts of the site they really needed to control.
Another client wanted a custom design for an outward facing site. Designers and the customer worked together, iterated a bunch, and came up with a design they all loved... I implemented it with tailwind... straightforward for me and the client and designers loved it because it looked just like the design they worked so hard on.
It would have been possible to use tailwind on the first site, but it would have taken longer, for no benefit to the client or project.
It would have been possible to use bootstrap on the second site, but it would have taken longer (to customize) and/or would look more like bootstrap and less like the custom design in places where it just wasn't worth the effort to customize it.
Bootstrap requires learning a new set of class names.
Tailwind is like in-line styles with fewer characters.
With both you can create an exponential number of similar looking, yet unique styles. It makes editing easy, but there’s no consistency constraints.
I think the holy grail will be something that enforces consistency without memorizing a new, unique styling dialect.
https://chrome.google.com/webstore/detail/gimli-tailwind/foj...
Though reading Tailwind's website, people seem to think they're fighting some holy war against Bootstrap.... absolutely bizarre.
And as another commenter pointed out, Tailwind is just as complex or more complex.
Full stack type safety, including styling, is where it’s at IMHO.
Maybe there’s other ways of making CSS typesafe and supporting editor autocomplete, but why bother using CSS if you’re not even really using the cascade or non-trivial selectors?
might as well just use styles directly?
Especially in the modern era, it’s not that hard – what takes time is building a custom design, and that’s a key point he’s missing in this article. If you want to look different than other Bootstrap sites, you can do the same customization work as in his Tailwind example. It’s also likely the case that thinking about how to name things is going to be better than just spraying utility classes long-term since that gets you to think about where things are and are not the same.
I'm not a huge React fan, but I cannot agree with this criticism. Its documentation is thorough and complete. It also introduced the frontend community to the idea of Functional Reactive Programming.