Tailwind CSS v3.0
tailwindcss.com
tailwindcss.com
With the regular way, to style something that's probably not going to appear elsewhere, I'm having to: come up with class names, annotate the HTML with them, repeat some of this annotating in a CSS file, jump back and forth between files to tweak the styles, use the web inspector to figure out which CSS class is overriding another then jump to the right CSS file to fix it etc.
Tailwind classes are also faster to type and flip between when you're experimenting (e.g. editing "mt-5" to "pb-3" vs "margin-top: 4.25em" to "padding-bottom: 2.75em") and you get less distracted because it has sensible defaults and helpful guardrails (you rarely need all the possible attributes and range of parameter values CSS has available).
I also rarely had the super irritating and common CSS scenario where you edit a style and it doesn't change and you have to go investigate to find out why e.g. something is overriding something, your selector is wrong, and even after all that maybe you undo the edit because it doesn't look good. Plus you no longer have the fear that tweaking a shared class to going to break some completely different page.
I feel that beyond some building blocks, trying to create reusable CSS classes with cascading styles has similarities to using excessive abstraction and deep OOP class hierarchies in regular programming languages to avoid a little duplication.
I also don't have a problem with styling stuff appearing in my HTML files either as long as the right HTML tags are used around the data. HTML files are already full of class annotations and divs that are only there for styling yet this doesn't cause a problem to e.g. browsers, screen readers or crawlers.
This experiment has failed though. CSS isn't powerful enough to style HTML however you want without having to add a soup of extra divs and classes that are only there for styling. No large website today works otherwise.
HTML is still semantic when it contains styling markup (in the sense that a computer can read and understand the structured data from it) so I'm unclear what benefit is being missed out on. Whether you call a class "home-cta-subheading" or "text-center" so you can apply some styles doesn't make a difference to screen readers, browsers or search crawlers either.
<figure>
<img src="/sarah-dayan.jpg">
<blockquote>“Tailwind CSS is the only framework that I've seen scale
on large teams. It’s easy to customize, adapts to any design,
and the build size is tiny.”</blockquote>
<figcaption><b>Sarah Dayan</b>Staff Engineer, Algolia</figcaption>
</figure>And if you need to modify the HTML, were the extra tags added 100% only for semantic reasons and not for presentation reasons?
Anyone have good advice on a better way?
> Here is how I approached this challenge
...but you modified the HTML?
The original challenge includes questions that apply only if the resolution involves HTML modifications, which (contrary to the earlier text viewed in isolation) indicates that such modifications are not invalid in response to the challenge.
- There must be a logical reason for wanting to make the word "tiny" use a small font, so that word is missing a tag that represents that prosaic intent. I've used <small>, but depending on how you'd verbalize the word "tiny" (which is what you're representing both with making it use a smaller font and with wrapping it in a semantic tag), you might also wish to use <em> or another tag.
- Similarly, there is missing semantic markup inside the <figcaption> for the person's name, job title and company. Those are semantically separate concepts for each other, but for some reason the example HTML was written without semantically differentiating them. This is much like trying to represent two paragraphs of prose with just a couple newlines, rather than actually wrapping each in a <p> tag. To fix this error, I've added tags as necessary to implement the semantic hCard microformat -- independently of styling.
- I've also added the recommended attributes to the image tag, because it was missing. (And for the sake of the Codepen, I replaced the image's src with a placeholder so as not to hotlink from tailwind's site.)
Given those improvements to the semantic structure of the HTML, here's how you can make the author's name appear on the right, with the quote underneath, with a line break before the company name, and "tiny" in a small font: https://codepen.io/Kerrick/pen/KKXgPYw
> - Similarly, there is missing semantic markup inside the <figcaption> for the person's name, job title and company. Those are semantically separate concepts for each other, but for some reason the example HTML was written without semantically differentiating them.
Presentation/visuals aren't always tied so closely with logic though. "To make it look nice" is a valid reason. As I said, this experiment has failed. All modern website designs use divs + classes everywhere for styling. I agree extra semantic tags would be useful but at some stage you're going to be forcing yourself to come up with semantic reasons to add a tag when there isn't one.
> I've also added the recommended attributes to the image tag, because it was missing.
Related: alt="" is best practice for when an image tag is for presentation purposes only because images don't have to be there for semantic reasons.
https://codepen.io/BlindPenguin/pen/GRMjjvq
I'm off scrubbing my hands with a wire brush and abrasive cleaner.
If you want to make a word tiny, you can use the <small> HTML element.
Here is the CSS for my example
body {
font-family: sans-serif;
background: #e4e5f8
}
figure {
text-align: center;
background: #fff;
border-radius: 1rem;
padding: 1.5rem;
max-width: 40rem;
}
figure img {
border-radius: 50%;
width: 7rem;
height: 7rem;
object-fit: cover;
}
figure blockquote {
font-size: 1.125rem;
margin: 1rem;
}
figure b {
color: #0ea5e9;
display: block;
}
The trick is to keep things simple.
Then when you have mastered the rules, you can break the rules. eg. when you can style semantic HTML however you want without adding div's and CSS classes, that's when you can start adding a little div and class here and there just to keep things even more simple.Simple code is most of the time faster to load, and easier to maintain.
Totally this. We say we've come a long way from using tables for layout, but for example you still can't use Flexbox without at least some non-semantic .stuff-container and .radio-with-label junk. Decoupled HTML and CSS have failed in the real world, outside of pet projects.
Can you provide an example? I've never found this to be the case, particularly with modern CSS. Happy to be wrong though.
style is orthogonal to semantics
You need divs all the time for layout (e.g. to group parents/children in the right way for flexbox), to target content for styling (e.g. putting a div around the name of the author to make it blue when you otherwise wouldn't tag it) and to get around CSS quirks (search for "wrapper div" for examples).
> Can you replace them all with more semantic tags? If not, can you remove them and still style it the same way?
I looked at on the first four examples, but my responses are yes and yes.
Take the figure example. The first div, which groups blockquote and figcaption, is extraneous and unnecessary for the end styling result. The second div is not extraneous because it exists for a purpose. The purpose of the second div is to place emphasis on the name or make it stand out. Thus, it should be changed to em. The third div is extraneous. With the HTML in place, grid it up.
You have the container (figure) with two columns and two rows. The image sits in the first column spanning both rows. The blockquote sits in the second column on the first row. The figcaption sits in the bottom right-hand corner. Then tweak to get your img and other parts as desired (e.g., width, spacing, font-size, etc.).
> You need divs all the time for layout (e.g. to group parents/children in the right way for flexbox) ... to get around CSS quirks (search for "wrapper div" for examples).
Sometimes flexbox is the wrong tool. Sometimes floats are better. Sometimes grid is better. If you find yourself reaching for extra HTML elements first, you should stop and re-evaluate whether your approach to achieving that layout is appropriate.
On quirks, my experience is that "quirks" are rarely actual quirks. They are usually a limited understanding of HTML and CSS.
That's a loaded question. CSS frameworks (or tables, or div based designs) are also used because they save time when iterating, not because of a lack of expertise.
And it's hard to take Facebook serious as an example. They're known to engage in HTML obfuscation on purpose.
https://dev.to/ganderzz/how-facebook-avoids-ad-blockers-4mdc
There's a reason why inline styles and important! were to be avoided
separate files != separate concerns
This is untrue by any measure.
This might have been true in the days before flex or grid, but with those additions, there is no need for extraneous styling divs.
> "...and classes that are only there for styling."
That part is confusing. Classes? As in CSS classes? CSS has no other purpose than styling.
I'm really glad I just powered through that point and let myself feel dumb.
Also does this comment even has a point? Like if we do what you suggest then no need of tailwind?
Yeah, that's kinda the poster child use case for Tailwind and similar frameworks. Landing pages are all about being jazzy and unique and eye catching, and not so much about code reusability/composability.
Where it gets less fun is when you want widget consistency across multiple areas of a site and across design tweaks over time, since now you have to deal with several `class="..."` strings across multiple files, possibly with class names in arbitrary order, possibly mixed with logic from other templating languages (be it from Django or JSX or whatever). So you can't just grep to achieve the objective of changing styles in one place to affect all instances of some semantic group.
Personally I think comparing Tailwind directly against traditional CSS as a whole is painting in too broad strokes. There's a lot of CSS methodologies and also a lot of bad practices (e.g. using SASS indentation as namespacing mechanism and then running into the old problem of specificity), and comparatively, there's a lot more than Tailwind in the atomic CSS space, and more broadly, in the compiled CSS space.
Utilities like Bootstrap (e.g. `class="btn btn-primary"`) for example share many benefits of both atomic CSS and "good" subsets of traditional CSS practices (namely, you get memorable short class names, which are also organizable along semantic lines). So there's definitely more shades of gray than just "atomic-css-is-the-best-thing-since-sliced-bread" vs "looks-like-lazy-style-attributes-lol".
I am going to give it a try. The argument against using it is that it defeats the purpose of Tailwind, but I think its useful to start by spraying classes until things work and then moving those classes into e.g. btn-primary once the styles become stable and need universality.
> 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
Approaching it with moderation is probably worth trying though
The intended method of not repeating yourself in Tailwind is using a framework, and writing the styles in the template of the component.
With this workflow:
* There are no global styles that can have an unknown or unexpected impact on the application when modified.
* The component's style is completely encapsulated. It can be placed anywhere in the application without worrying about inherited styles causing problems.
edit: formatting
Another variation I've seen is a combination of atomic CSS and Mithril.js' hyperscript selector syntax, which lets you do stuff like this:
const Button = 'button.bg-gray-900.px-6.text-white';
// JSX
return <Button>Click me</Button>
There definitely are interesting ways of applying atomic CSS beyond basic Tailwind usage.Occasionally, I'll use @apply directives to DRY up something that isn't easy to encapsulate at the component level, but 95% of the time, I can easily get by with utility classes.
I try to avoid using hyperbolic-sounding language like 'revolutionized,' but Tailwind + ViewComponent has basically revolutionized the way I build user interfaces in Rails.
Although, I'm still a bit nervous spitting utility classes all around. That sounds almost like inline CSS and almost unmaintainable.
I realized that all of my semantic CSS classes might as well have been inline CSS for all the good they were doing me on reusability. Utility classes are faster to work with, and, as long as you’re componentizing everything, still going to give you consistent styles across your product.
IMO one of the interesting parts of functional CSS is that we can apply the same tactics we use for organising code to organising the styling.
Also, with separated CSS, and especially with semantic CSS, there is often a fair amount of duplication that happens in the CSS code itself, which we programmers tend to be very forgiving of. Giving Tailwind more scrutiny than we do for our CSS ends up making our code more consistent, less duplicated and better in general.
It means that we can have our own custom "button button--sm" classes - a single place to change general styling - and on top of that get all flexibility of the tailwind utils for edge cases.
I don't think it's perfect, but it's so far much more flexible than bootstrap, and we don't need to duplicate loads of classes for each similar component.
It doesn't matter, you can have an entire newspaper and perfectly done in functional css with incredible results without having to mastermind any architecture.
Tailwind aggressively speeds up development time of components by allowing me to stay in the same cobtext when styling things. The brevity of class names also dramatically shortens the time spent writing styles. While working on the projects I'd setup with Tailwind, I felt far more productive.
However, those were new projects. After completing them and needing to go back and modify or maintain them, the experience has been horrible. The resulting style declarations (as class names) are completely unreadable and unmaintainable. I've tried organizing them and splitting class names onto multiple lines, but it has only cluttered things.
In my experience, Tailwind (and similar projects) produce styles that are effectively read only. They are superb when writing a new component and styling things from scratch, but maintenance is nonexistent.
Because of this, I've now switched to using a CSS-in-JS solution to gain the benefits of in-context styling and still have the ability to write CSS declarations in a structured and maintainable way.
I have created React components with TW, where the components are complex and large.
However, breaking them down into tiny functional blocks, maintenance is easier.
It's been an absolute dream in a decent-sized project so far, and even with some refactors.
Regardless, it's not everyone's cup of tea, but depending on the UI framework of choice and the flavor of CSS you use, YMMV when it comes to dev experience.
In Vue or Svelte, I wouldn't even use a CSS-in-JS solution because vanilla Tailwind to compose utilities into localized classes is a straightforward approach.
Svelte's styling is already pretty atomic as it is.
With Svelte, I use a small global reset, and a global file containing native CSS variables (which I reuse across multiple projects).
Most of my Svelte CSS is component specific (and in most cases, no classes are even necessary) and they can be themed by simply referring to the CSS variables in my global variable file.
I've stuck with styled-components for now, though I confess that I've started to wonder if the the verbosity of creating a (styled) component for everything, passing props, etc. is a bit excessive since trying Tailwind.
With Tailwind, I see a <div>, and I see all the styles on it, right within the template. I don't need to follow class names, or cross-reference between files, it's just there, where I'm already looking.
I wrote HTML in a time when you used inline HTML attributes for styling. Changing one bit of the style meant visiting every single page to update everything (then making sure to test because you definitely forgot at least one place).
CSS was an amazing idea for making just one place to put all your styling. You could now change one style and everything else would automatically update.
Tailwinds feels like it's just a trip right back to the old inline styling right down to searching bunches of pages if you're making a styling update.
CSS modules let you use the full power and control of vanilla CSS, without having to worry about styles bleeding across components. Sprinkle in your global utility classes for your design system and you're good to go. Or sometimes even better, abstract design into components like `<grid>` `<column>` etc and not even worry about the classname implementation.
I know I'm missing part of the picture, because of the hype and joy that people report from Tailwind. What part(s) am I missing that move folks from the power, beauty, and simplicity of CSS modules, to all-utility-classes-all-the-time Tailwind?
Tailwind is a f*king godsend XD
I have not personally found the need to use Tailwind because of that.
I agree with most of what you're writing, but in arguing this out with people who seem to be enthusiasts, what I think I've discovered is that while there are existing (hell, longstanding) unbundled technical solutions fully capable of solving the problems Tailwind does... they don't solve the practical problems of channeling a group into a good-enough design system, and in fact many people who've been doing CSS have never actually really used a design system (especially if their experience is solely recent, and definitely if their experience is only incidental in the sense that they're application devs first). And many organizations don't have roles where someone can focus on solving this problem.
Just-add-Tailwind may hit an interesting pit-of-success spot for a lot of people in this position, where TW provides the atoms of the design system to scatter in a just-in-time manner. Sure, not elegantly, but practically.
Personally, I'd prefer to work with people/orgs that don't see this is an optimum, but I might accept it as a situational local optimum.
Let's be honest, there isn't much elegance to the non-Tailwind solutions either. At the end of the day it's text input used by a rendering engine to style layout, it and your customers don't care how it got there.
Tailwind is great if you're a startup, or someone who is a webdev and also has to be the designer. But in a large organization, with a company-wide style book, and a design department, it's not a good fit.
Tailwind works for "I see this control in my head, and I'm going to code like this to make it happen." It's not really a good match for "I see this control from the design department, and I'm going to make it fit into the rest of the site codebase like this."
But I still prefer naming things to the class soup and the excessive repetition.
ITCSS (Inverted triangle CSS) works with the cascade and results in clean, minimalistic CSS files.
I do not build SPAs though and do get that quick styling works really well for that scenario.
I do import Tailwind colors, spacing and sizes in SCSS maps for easy access and do like the standardized approach.
The real Tailwind lightbulb for me was understanding that the cascade and actual CSS files don't matter anymore - you don't need them. No more inheritance, no more naming, no context switching.
I'm a big fan of ITCSS and was using Harry's methods before he coined the name but we don't need to fight the cascade any longer.
> I do not build SPAs though and do get that quick styling works really well for that scenario.
Admittedly, if you're not breaking down your UI into small components then Tailwind will get real messy, real fast.
"CSS modules still seem to solve every problem Tailwind solves, and better."
- Not necessarily true. Unlike css modules, tailwind removes the whole "think about a name for your class" mindset, reducing friction from the development process. It also unifies some base level design decisions like spacing and colors, which developers would have to rely on "best practices" otherwise, which don't necessarily get strictly enforced.
"I'm not sure how Tailwind works, but any CSS that's built at runtime and JS and inserted into the DOM dynamically should be avoided, and is an example of favoring developer experience over end user experience."
- You are right, looks like you are not sure how Tailwind works. Tailwind does not build anything at runtime, it all happens at build time. Tailwind will compile only the things you need (using the new JIT mode) into a css stylesheet which is sent to the frontend. Not much different from how sass or scss works.
"CSS modules let you use the full power and control of vanilla CSS, without having to worry about styles bleeding across components."
- Tailwind does not stop you from using vanilla css, but in most cases you do not need to. As per their website, you can think of it as an API to use parts of CSS, instead of CSS replacement. I think you are confusing Tailwind as a replacement for something like CSS Modules, but those two are completely unrelated. You can still use CSS Modules while using Tailwind. Think of it as an api to your design sytem just like you could think of an ORM as an API to your database.
Before they didn't have all colors enabled by default, because generating classes like `bg-blue-500`, `text-blue-500`, `border-blue-500`, etc. for all colors would increase the resulting CSS way too much. They did the same thing with variants.
With the JIT none of that is necessary anymore. Plus you can use arbitrary values because it's being compiled now.
/[^<>"'`\s]*[^<>"'`\s:]/gI just can’t go back without tailwind.
It sits on top of Styled Components or Emotion (your choice), and uses your project's Tailwind config faithfully, minus a few of the plugin features.
It eliminates the need for JIT or PurgeCSS because it compiles Tailwind's utils with a drop-in Babel macro, eliminating the need for PostCSS.
As a lover of vanilla Tailwind in Vue and Svelte projects, Twin Macro has made using it in React 10x better and I haven't looked back! :)
<Button
h5
w6
bgBlue500
textWhite
hidden={props.hide}
/>Twin Macro has a few snippets of type definitions you can add to your project based on whether you're using Styled Components or Emotion, specifically to support these two props (tw and css).
They link to their Examples repo from the official readme with several projects using many different combos, with a handful of TypeScript ones.
Recommended even. I use Tailwind with CSS Modules as a fallback when there's simply no way to achieve the result using Tailwind (rare) or it's prohibitively complicated/messy.
Also for CSS hacks if you need to support an older browser.
Another thing that Tailwind is is an opinionated delivery mechanism for your styles, in this case, as utility classes that can go straight into your HTML. This is probably a big cause of Tailwind’s popularity, not because any one person necessarily loves using classes, but because it makes it extremely easy for everyone to start using Tailwind in nearly any imaginable web project starting at plain static HTML files and going up from there. This aspect of Tailwind is something I’m not a huge fan of. To me it feels like a step back from a lot of higher-level CSS tools (like many CSS-in-JS libraries) to just go back to concatenating magic string literals into my UI code. All the official Tailwind tooling (AFAIK) either just watches your codebase looking for these magic string and generating the appropriate raw CSS, or doing it in real-time with their new JIT compiler (which I admittedly haven’t investigated yet).
Personally I feel like a better approach is taking that same philosophy of design system primitives and executing it via something like SASS mixins, paired with single-file components à la Vue or Svelte. Then you can use better names (no need for brevity now), keep the styling separate from the markup (but still paired with it), and have a better experience debugging in the browser.
CSS-in-JS libraries are not magic that summons CSS out of thin air. They basically do the same thing Tailwind does: they watch your code for changes, they re-build/re-create raw CSS by, yes, often using string concatenation etc.
I don't understand what you mean by this. Literally decades ago would take us back to at least 2001. OOCSS, BEM, etc. were all created after that year. Wouldn't it be correct to say "Doing everything with utility classes and OOCSS / BEM are things we hadn't even started doing literally decades ago."?
1. It removes a layer of abstraction that's redundant if you use a component-based UI framework.
2. It provides constraints that act as guardrails against introducing inconsistencies into a design.
3. Its tooling is not magic and does not have runtime impact.
More detail at https://vincenttunru.com/why-tailwind/
I don't understand Tailwind either; but I find myself struggling with CSS modules when I need to override a CSS rule of a child from a parent. Like, say, my button should always be green, except in this context I want it to be purple, its font-size larger and its padding a bit different. With CSS modules, the parent component is unaware of the class name of the child component; so it cannot target that. Perhaps this should all be done with CSS variables; but then hell, how many CSS variables should my components expose? and besides, I am not even sure even they will completely solve this.
className={isContext ? ".button--context" : ".button"}
----
alternatively if you want many unrelated base rules that aren't color/padding as a baseline:
.button contains base rules .button--default default color/padding .button--context contextful color/padding
className={`.button ${isContext ? ".button--context" : ".button--default"}`}
import classNames from 'classnames';
...
className = classNames(styles.buttton, props.className);
But this leaves me at the mercy of the order in which webpack builds stylesheets (sometimes props.className will be defined after styles.button and my plan would work; other times it will get defined before styles.button, and styles.button will override the CSS rules of props.className).Really wanted the extension of the base rules to work out; but I guess you are right: the className from the props should override entirely one of the classNames of the component.
There's a fundamental argument that inheritance is a mirage and things in large projects become much simpler with composition-based approaches. You don't really need to grok the inheritance chain with Tailwind in the same way you do typical CSS.
For my personal projects I'd continue writing my own CSS... but for teams, I'd go to Tailwind without a second thought.
the major stumbling block has been how tailwind is mostly just css translated into its own hard-to-memorize lingo.
For example, say I want to do something basic like "display:flex; justify-content: start".
In tailwind you would type "flex justify-start" instead.
Which doesn't really follow any rules as far as how to get from A to B, so it's just a matter of having to look the magic word up in their docs each time until you memorize. And there are a lot of keywords (many modifiable according to n-dimensional properties) to memorize.
I know there are handy slugs like "w-1/3" that encapsulate a best practice - but I'm a person who'd rather master the underlying mechanics of that best practice and be able to deploy, tweak and debug it myself.
Honestly, I agree with you on the good variable names, but in average team setting I prefer no names than bad ones.
the semantics of most html elements is useless to know for more devs (and classes don't help users)
in fact a class like .red conveys more useful information to a developer than .standout-link because when we go to change the colour of the button it's the colour we care about, not the "purpose" of the button
<el style="display:flex;justify-content: start;">...
?* media queries
* @apply
* low specificity (tailwind doesn't do !important)
EDIT: It "does" important, but only when instructed so, in 1.x it was a global switch, apparently since 2.x its available as a per-class modifier. Thanks dcre
* the theming abstraction
* brevity
https://tailwindcss.com/docs/just-in-time-mode#built-in-impo...
https://github.com/tailwindlabs/tailwindcss/releases/tag/v2....
Media queries are a good call out, they're definitely a benefit tailwind's approach has to the built-in browser support for inline styles. Another benefit is hover and focus states, which are very difficult to apply with inline styles.
With tailwind you can do “block md:flex hover:font-bold” and you’ve covered pseudo class cases and media queries very succinctly.
<el class="[display: flex] [justify-content: start]">...
I wish I were being hyperbolic, but alas, no: https://tailwindcss.com/blog/tailwindcss-v3#arbitrary-proper...FWIW, I also hated using header files in C++ and also wrote a Ruby library for inlining all my tests immediately following the functions they test. I like having more context when looking at code without having to flip around from file to file to piece a bigger picture together.
If you haven't tried Vue yet, I strongly recommend it based on what you said.
It seems the biggest advantage most people find in tailwind is working around a react limitation.
Not much different than injecting an object in a `style` attribute in practice, but there's a lot of creative firepower in the arbitrary styles API.
I'm often in a cycle where I am tweaking a complex class with 10-20 properties including flex, transforms, animations, etc. - and having them each be on their own line (and the class being in a separate file along with its parents, siblings and children, frankly) is key for readability to me.
I guess in the end I have come to have enormous respect for CSS as a powerful, mature language and I'm not looking to be buffered from it.
It can get long. I certainly have parts of my app where I break out into plain CSS because it's easier to understand.
Keeps everything clean and readable!
And the keywords all seem to make sense to me? It's "n-dimensional properties" but the dimensions are pretty consistent...
Autocompletion in your IDE makes this easy (the class names are similar to the CSS attributes, even in your examples, so you can usually guess them) and you use the same classes over and over again so you learn them quick. I barely spent 10 minutes in the Tailwind documentation the first few days because of the VSCode extension.
I wish framework devs would just hyphenate (or even colon-ize) the CSS property names fully like "display-flex justify-content-start". I think Bootstrap does their own pattern like "d-flex", but all that does is require one to visit the docs to view some less common properties. Autocompletion pretty much makes typing these a breeze, and having less opinionated patterns for property names will make it less painful transitioning between frameworks.
One thing to consider is that being a bit more terse in tailwind is good because you effectively end up with media queries, dark mode, hover states etc all placed together.
I have it open in a browser tab almost constantly.
Twin Macro is a great wrapper library for Tailwind-in-JS with strong IDE support and it autocompletes all my utilities. I barely have to type anything to style everything in my project.
I can even hover over utilities to peek at its raw CSS.
https://marketplace.visualstudio.com/items?itemName=lightyen...
Another way of saying this, is that Tailwind adds cognitive overhead.
This is the only problem of tailwind, it relies on its own lingo, as all the OOCSS/BEM projects. When you involve semantics, you will always bring these kind of problems.
I covered this problem and I solved it with this approach http://minid.net/2019/04/07/the-css-utilitarian-methodology/
1. It's a step function over CSS units. This is the biggest strength, just standardizing that your design uses padding of 2, 4, 8px, but not 1px, 3px, or 1.23123em :). It provides more steps than you need, but still it's good that the core of Tailwind is a design system with defined unit and color variables.
2. Some of the utility classes are very helpful. Even as someone who likes writing CSS, it's nice to not need to give something a custom classname just because I want to put margin-top on it. class="mt-4", done.
I think the problem is Tailwind goes too far and tries to replace EVERYTHING with a stack of utility classes.
This works okay in extremely componentized web apps. It's a nightmare if your UI isn't highly componentized. I've seen projects where you make a button by copy pasting this ~80 character string of tailwind classes all over the place, and then changing the color names if you need to. Good luck fixing that when the designer decides that we don't want any buttons to have rounded corners anymore.
Personally I think the best parts of Tailwind are captured in Pollen[1], but I do wish it came with a subset of utility classes for colors, font sizes, margin, padding, and text alignment. I think the hard part is defining which subset is the right subset... I doubt you could find strong agreement from a large majority of developers on that.
That app is done wrong. If you are using the same styles to represent a button you should use postcss and do
.myButtonClass { @extend: (80 tailwind classes here) }
function Button = ({ children }) => <button className={80 tailwind classes here}>{children}</button>
<Button>Create</Button>
<Button>Edit</Button> // Same style
<Button>Delete</Button> // Same styleSome are big and some are small; some are bold and primary and some are muted and secondary; some have icons; some have shadows; some are disabled, etc, etc.
It's easy to make them identical. The challenge is to be as flexible as necessary in a mature application, while minimizing verbosity and complexity.
In my experience Tailwind hurts more than it helps here. It forces you to use your component system to abstract things which otherwise wouldn't warrant the extra level of indirection.
<button class="btn large shadow">Edit</button>
.btn {
...default button styles
}
.btn.large {
font-size: larger;
}
.btn.shadow {
box-shadow: 0 0 8px #0004;
}.btn.large {} .field.large {} .fieldgroup.large {} .title.large {} .link.large {} .large {}
to find all the elements that the .field.large declaration impacts we need to enumerate all the elements that have both .field and .large in any order.
we've coupled out html and css files
<Button variation="primary" size="large">Primary Button</Button>
<Button variation="secondary" size="medium">Medium</Button>
<Button variation="tertiary" size="small">Small</Button>For example when using React you can create 5 button components first and the refactor your code to make the 5 buttons use/call a generic button. Or have 2 generic buttons if the combinations are hard to handle. The thing with atomic CSS like Tailwind is that it very easy to quickly create a few different buttons.
https://tailwindcss.com/docs/reusing-styles
Although I realize in looking this up in the documentation to show you, it's actually @apply and not @extend you are supposed to use.
For anyone interested, you can find it at: https://brixi.dev/
* No more worrying about naming class selectors. This frees up so much cognitive space. The less you have to worry about naming the better. I used the SUIT CSS naming convention before, which allows a mix, and that just creates friction. You need the same level of abstraction all the way through.
* No more flipping between files. You edit your styles directly in the HTML. You will need to consult the TW docs, of course, but they're easy to navigate.
* Tailwind is more than just inline styles. It provides a nice syntax for targeting breakpoints and little utilities for conveying more abstract styles/stacking rules.
* TailwindUI is a great way to jumpstart a project and looks way better (IMO) than Bootstrap's components.
* JIT is awesome
I'd be remiss if I didn't mention some cons:
* Looking at a bunch of class names in your HTML is at overwhelming at first. It's hard to delineate the structure. Using proper HTML elements, roles, etc. helps.
* You will need to DRY up your repetitive styles by moving things to templates/components. So you still have to name things, but just keep it generic (alert, dropdown, badge, etc)
* Sometimes you'll have to create class selectors when working with web frameworks and JS libs that require a single class selector option.
We'll see if UnoCss takes over.
The one thing I don't like is that the culture around Tailwind seems a lot more proprietary, like you're getting three quarters of a product that you need to buy the rest of, whereas Bootstrap felt like you got everything you could ever need for free.
I'm not sure what you mean by proprietary culture! Based on the fact that I've pretty much never seen anyone talk about it, I would guess (total guess, no real knowledge) that no more than 1% of Tailwind users have paid for Tailwind UI.
https://tailwindcss.com/docs/divide-width#add-borders-betwee...
Spending $250 in order to get a well implemented and well designed HTML and CSS framework for your app sounds like money well spent to me, depending on the circumstance.
If you're an expert or pro at CSS, then yes, that's expensive. But if you have a little budget and need to make some quick progress on a new site, it's a great deal. Hiring someone who can recreate these designs and give you exactly what you want is probably going to cost more than $250.
* https://blocks.wickedtemplates.com
* https://tailwindcomponents.com/
* https://www.tailwind-kit.com/
* https://www.tailwindtoolbox.com/
Most of the sites I put together this year used an amalgamation of components from those sites for basic structure, and then just get customized to the brand and site function. I hate writing raw CSS and I would also hate writing raw Tailwind.
Tailwind is just a different way of writing CSS styles. Not a bunch of premade UI templates.
It's fine that they want to make money but it's very confusing for a new user. Ultimately, they might make more money by dropping the shady links if it's turning away enough new users.
s/Components/Tailwind UI/g
across their site would be a big improvement.Try daisyui as a tailwinds plugin. It comes with the missing components. It also allows you to replace your 80 character style for buttons with btn btn-primary.
As a frontend developer I don’t like Tailwind for several reasons, it brings the styling into the structure. As a frontend developer Tailwind is at a forefront of what I would consider bad practice and encourages a code style which would be a nightmare for me to maintain.
That said. Tailwind seems to be loved be people who are not professional frontend developers. It seems to be just the right tool for people who are not necessarily proficient in CSS. And perhaps people like me (and the dead sibling) need to learn to let go and allow other people to have the tools which makes it easier for them to do the job which they are not experts at. For that reason I understand Tailwind, even though I don’t agree with it.
Show me a site that has CSS Zen garden style replaceable stylesheets that totally overhaul the nature of the site. It's incredibly rare and almost always not worth the effort. What business says "I want to overhaul the styles of my application but change no structure at all. I'd posit it's near 0.
Even if that's your goal, and I'd argue that it shouldn't be, you can still do that with TWCSS and the @apply keyword. You can write your generalized names then apply whatever twcss keywords you want to them separate from your document's structure.
If your overhaul amounts to changing a "theme" you can easily do that with twcss. In fact, that's basically the point.
I am a professional frontend developer and I love it.
I mean header files are OK, and professional C developers probably love them, but not having header files is kind of great too :)
I have a similar comment elsewhere in the thread but it applies here too, I think: the main drawback of Tailwind is that it's extremely general. I'd imagine a well abstracted, focused, domain-specific set of CSS created by experienced frontend developers will be much better within that domain.
Pair your tailwind with styled components and you can finally reach the dream of semantic HTML.
i prefer the later. with styling in structure if i make a change in one place, it effects the one thing i intended it to
with structure in styling, if i change one thing, it may impact many other things, some of which i might not intend to and are sometimes unknowable at the time of the change
If I change the structure I usually have to change the style anyway. And with component scoped styles, I know exactly where I need to do that (usually in the same file, or in a file referenced by the component).
As for shared styles I use the cascade which can penetrate the component boundaries, e.g. font-size, color, but usually --css-custom-properties.
Looking at the new features, I wondered why they went with a major version bump, but seems like it's because the Just-in-Time engine released in Mars as a feature flag is now the default engine, which is a pretty big change by itself.
Has anyone used both seriously who can compare?
[0]: https://tachyons.io/
Tailwind is better in every way, and JIT is a killer feature.
I dunno, the smaller dev build from JIT is great, but it breaks my in-browser design workflow. Only the CSS styles needed are generated, so I can't make in-browser tweaks to see what a different padding/margin/other-property looks like.
It's a pretty small and readable codebase, so while there's a downside that you can't upgrade it by incrementing a version, the upside is that you don't have an opaque upstream dependency and you can cut any fluff you don't need (though there isn't much).
Also, the naming of classes in Tailwind feels much more natural — the tachyons naming is condensed to the point of being abstruse.
CSS frameworks don't ... need? to be state-of-the-art/updated all of the time (I get that), but at the same time, like anything else, once a component/css/etc. library falls behind, it (can) become harder to make it work with other tools.
i.e. it's hard to abandon the bandwagon of constant new releases, as the second that you do, "stuff" sometimes starts breaking. This is of course a very general observation that doesn't apply to everything.
[0] https://tachyons.io/components/collections/albums/index.html
https://adamwathan.me/css-utility-classes-and-separation-of-...
I fucking LOVE CSS and Tailwind is an insult to the craft.
Those who love Tailwind tend to not understand CSS beyond the basics, is what I've learned. Those who hate Tailwind know CSS inside and out.
To each their own, but this example from their own homepage makes me want to vomit:
<button class="flex-none flex items-center justify-center w-9 h-9 rounded-md text-gray-300 border border-gray-200" type="button" aria-label="Like">
Like what the actual flying fuck. This is inline CSS, period. And that's wrong, always. Tailwind makes me mad and angry because I love front-end development, I love CSS, and everything about this feels like a mentally challenged person spitting me in my face. Nothing I can do about it, they are challenged after all, but damnit it's annoying.You know what's going on if you're in a component called user-profile.component.html
How often are you writing something like a user profile component in the context of something much larger? Also, what styles would the class "user_profile" even have? You say the second one "tells you nothing about what's going on," but I'd say it's the opposite. If you actually put real tailwind classes in the second one, I'd know exactly how that div is styled whereas the first one requires cross-referencing another file.
"user_profile" probably has CSS implementation that have almost nothing to do with a user profile. It's probably a container that has maybe a margin, a max-width? The important styling details all come from the inner HTML and stylings on those things. So your "user_profile" class is mostly just another generic wrapper that you had to come up with a name for.
<div>heading</div><div>bob is a person</div>
This is better: <h1>heading</h1><p>bob is a person</div>
This is less clean but has the same level of semantic detail in the HTML: <div class="container"><h1 class="home-heading text-center">heading</h1><div class="m-10"><p class="home-body color-blue"><div class="first-name">bob</div> is a person</div></div>
Am I missing something?I think people conflate semantic class names (read by programmers and maybe ad-hoc web scrapers) with semantic HTML (read by screen readers, SEO bots). Semantic HTML is HTML that uses the appropriate semantic HTML tags, but including wrapper divs and CSS class names on top of this doesn't make it less semantic to a machine.
For styling, when a utility class is all you need to style a particular tag and it's obvious from context what that tag is being used for, I don't see to reason to spend time trying to come up with a semantic name e.g. `home-hero-wrapper-inner`.
To me, this is people dogmatically sticking to a "best practice" without thinking about the pros/cons and reason behind it. This is also related to the pipedream that HTML is for data only with nothing about presentation and CSS should be able to style the HTML without you editing the HTML.
Which I also think is weird, because the hierarchy of HTML is inherently styling/presentation. If HTML was truly decoupled from styling, you'd just throw all the tags that you want into an HTML file and then arrange them around with CSS.
That's why when you're using child selectors in CSS (or the nesting in SCSS that's transpiled to child selectors), you're forced to keep two hierarchies in sync, which makes it a huge PITA to refactor.
Yep, trying to keep data and presentation separated like this comes with a lot of pain. Why bother? I don't see the practical benefits in real-life projects as long as you're still using semantic HTML tags.
There's this other pipedream that the HTML is generated/written by people that aren't concerned with the presentation and then the CSS can be swapped in to style it however you want. You can and should do this in a sense that you keep your data/articles/posts in Markdown, SQL databases, behind APIs etc. - I think trying to split this further at the HTML/CSS level isn't gaining anything.
<div class="w-16 h-16 px-2 py-1 m-1 text-sm text-white bg-black rounded md:w-32 md:h-32 md:rounded-md md:text-base lg:w-48 lg:h-48 lg:rounded-lg lg:text-lg focus:bg-red-400 focus:rounded-md hover:bg-yellow-200 hover:rounded-t-md md:focus:rounded-xl md:focus:text-lg lg:focus:rounded-xl lg:focus:text-xl md:hover:rounded-xl lg:hover:rounded-xl">Yikes!</div>
I would love to have a transpiler that produces the line above from a code like this: <div
class="w-16 h-16 px-2 py-1 m-1 text-sm text-white bg-black rounded"
md="w-32 h-32 rounded-md text-base hover:rounded-xl"
md-focus="rounded-xl text-lg"
lg="w-48 h-48 rounded-lg text-lg hover:rounded-xl"
lg-focus="rounded-xl text-xl"
focus="bg-red-400 rounded-md"
hover="bg-yellow-200 rounded-t-md">Yeah!</div>It also seems that the major speed improvement in Tailwind is inspired by windi
It's exactly what I was looking for, Thanks!
const md = styles => styles.split(' ').map(style => 'md:' + style).join(' ')
Then const styles = [
'w-16 h-16 px-2 py-1 m-1 text-sm text-white bg-black rounded',
md('w-32 h-32 rounded-md text-base hover:rounded-xl')
].join(' ');
Then <div className={styles}>Hello</div>
I haven't actually tried this approach but it might clean some things up.It’s predictable, there are a billion ways to accomplish things, and it’s super easy to namespace yourself to safety.
SASS I understand. It makes writing CSS faster.
Tailwind feels like you have to learn CSS, but you’ll never have to actually write CSS.
Reminds me of CoffeeScript in that way. You always had to understand both It and JavaScript.
1. Naming things “semantically” is a giant pain. Sure “user-card” is easy enough, but when you have to start giving names to all the little bits of the user card it quickly becomes absurd. Yeah you can use child selectors and stuff to ease that a little but then you’re basically re-writing your HTML in CSS. Tailwind’s approach is to say “have a UserCard.{html,vue,js} component and move on”.
2. Most codebases have multiple people working on them, and those people are often not CSS experts. It is very common to end up with giant stylesheets that only grow with time, because people are too scared to ever remove or change things in case it breaks something seemingly unrelated. Utility frameworks (and other modern approaches like styled components) keep the styles directly attached to the HTML being styled. You can make any change you like, safe in the knowledge that you are only affecting the thing in front of you.
3. It pushes you into a design system. Sure this is achievable through Sass/CSS variables, but for Tailwind it’s right there with a sensible default out of the box, and easily configured if you need something different.
I think the important thing is, Tailwind doesn’t enable you to do anything you can’t do by writing well structured CSS, because ultimately it is just CSS. However, people aren’t perfect, and I believe that Tailwind does a genuinely good job of helping people avoid common footguns.
If your team is largely composed of CSS wizards who are fine to carry on as normal, that’s great, you probably won’t get much out of Tailwind. But for a lot of us, the price of remembering some (very consistent, to be fair) shorthand class names is well worth not wasting hours battling the cascade and suchlike.
2. There are ways to structure your CSS so that's a mitigated issue.
3. It's not really a design system. It's a theme.
But is it true that every developer I hire has to understand CSS. But mostly because I think it's an insanely simple thing to learn.
Props to the team though - I feel like this is something I'll try out for a marketing site.
Another less popular one that I have had my eye on for some time is Mantine. It seems very polished and composable.
[1] https://chakra-ui.com/docs/comparison#the-runtime-trade-off-...
Thanks for helping me think through it further!
But a swell of less opinionated offerings [2] [3] [4] (more and more the popular anyways) work well with Tailwind. In fact, when writing your own libs, exposing a className prop makes them painlessly customisable.
0 - https://mui.com
2 - https://www.radix-ui.com/docs/primitives/overview/styling
The way HTML forms (in particular, but also things like tables) are stuck in a not even good for the time '90s level of functionality is an under-appreciated drag on all web development, IMO. So very much wasted effort, wheel-reinvention, brokenness (a11y, especially) et c. for shit that should have been built-in years ago.
It absolutely is, but things are changing! Come help us get better form widgets built into browsers at at https://open-ui.org/.
The website's a bit behind, the Discord and GitHub issues are where most discussion happens. We need people who know hte pain points to help us.
The use case demonstrated was suppose you have a twitter button on your site, and it has to have a background color of #1da1f2 because that is Twitter's brand color. Instead of writing style="background-color: #1da1f2" like a normal person they have a class name called bg-[#1da1f2], and their "JIT compiler" generates a named class with that property.
In another part of the video, they use className="font-bold" instead of style="font-weight: bold". Apparently the advancement in this version is that instead of having all of those pre-defined classes they only generate the ones you actually use. The feature list for 3.0 includes the ability to use any color you want, and even arbitrary CSS properties that the framework doesn't explicitly know about.
Is this progress? I could use the style attribute in 1999.
This is a way of paying only for what you actually use.
I'm not a tailwind user but I think the following:
``` <div class="flex">Foo</div> <div class="flex">Bar</div> <div class="flex">Baz</div> ```
gets generated to:
```html <div class="flex">Foo</div> <div class="flex">Bar</div> <div class="flex">Baz</div> ```
```css .flex { display: flex; } ```
If we replaced this with `style` attribute usage, you'd get:
``` <div style="display: flex">Foo</div> <div style="display: flex">Bar</div> <div style="display: flex">Baz</div> ```
Assuming the content is gzipped when transferred (a good assumption), the non-Tailwind version's payload is smaller because there are no separate CSS definitions.
Your statement is true in the general sense (a page can easily load unused CSS with other CSS/styling approaches) but I don't think it's correct to say that using Tailwind results in smaller payloads vs. using style attributes.
For example it can convert `<div style="background-color: white">` to `<div class="bg-white">`. Perfect! (Yes, "bg-white" is the Tailwind way to make the background color white.)
Tailwind definitely solves a problem for me. I don’t like writing CSS, and Tailwind serves a (very) thin abstraction layer. I don’t have to worry about reusing CSS, figuring out how to name my classes, or what CSS selector I need.
I guess these features are helpful, but they’re hilarious to read. “Arbitrary color support” is a release note you’d see in the 90’s
I was in the Tailwind is dumb camp also until I tried it. Then I realized I can ship my own prototypes faster because I wont waste time fine-tuning margins or picking colors. It isn't perfect of course but nice when speed is your top-priority.
I am a developer nerd and have a good taste for design. However, during actual development, I do not have the ability to visualize what I want in the first attempt.
So, I have to tweak the look and bring out the beauty I want through a 1000 cuts. TW makes that process extremely easy. Like, mindbogglingly easy.
However, I have learnt to be careful with my code, and I often limit the styles by splitting them off into sub-components.
https://getbootstrap.com/docs/5.1/examples/
Is there anything similar for Tailwind CSS?
Rest cost $
2. https://shuffle.dev/components/tailwind
The tool is paid, but we have many free components/layouts more than Bootstrap docs.
And let me repeat what every Tailwind fanboy (like me) states every time this project is on HN: don't knock it till you've tried it. Look at the animated example in the front page. You'll never be able to iterate that quickly with CSS.
Design in the browser with browser technology, it’s just boxes, gradients and shadows for industrial level web design at the moment. You really shouldn’t even be designing in a tool like Photoshop or Figma given the current design paradigms.
You will not iterate faster than what I am suggesting.
Edit:
The reason why we are here, why something like Tailwind and MUI exist, is mostly because we need an abstraction layer to do what a designer does on a whim. You can flick a shadow on and off on a Photoshop layer and mess with the subtlety of a drop shadow with a slider. If a designer makes a fickle change, the developer needs this abstraction to make the fickle change as fickle as the thought that made it. That’s why you have all these quick utility methods. The designer is one layer (no pun intended) removed.
In 2021 (2022 really), it’s shocking the amount of latitude we give designers to still not be able to do CSS. A half competent designer could have a modest style sheet that mostly captures their design instincts, yet here we are, unable to capture their whims and must now have an albatross utility library to have manual laborers capture the translation - all because … they still won’t learn basic shit.
And for what ultimately? These aren’t baroque art pieces, it is ultimately boxes with an aesthetic applied, all very describable with semantic HTML and CSS. But alas, our brilliant artists can’t be bothered. Here, send me your masterpiece so I can transform it for you.
Take the bootcamp on web dev. You are literally the people I want going there. Not the Classics major that needs money because they picked a stupid major. It’s you guys that need it, and deserve it.
This is why all but the very best flat designs (which does not always correlate positively with the size or reputation of the firm turning them out—looking at you, Google) look to me like something I'd have turned out for a quick feature demo circa '05, with everyone at the table agreeing that, however nice the feature, a designer definitely needed to take a pass at it before it was released.
Let designers focus on designing, developers on developing.
The words of an open mind.
Each of those adjectives are very open to disagreement.
Does nobody remember themeing forums software like vbulletin? Designers weren't allowed to touch the markup in the slightest and yet so many amazing themes were made. Why? Styling wasn't hard-coded in the markup. Hell, remember the insanely customized old.reddit subreddits?
FYI I'm a recent Tailwind convert so I agree that Tailwind is good, but your comment is like saying Tesla cars are great because they aren't horses.
I won't argue if one is better than the other.
So far with this plugin/extension design i've not found a way to use Tailwind and also retain nicely sized CSS.
This 3.0 release has its biggest feature be JIT. If you read the linked blog post, CSS is no longer purged but generated dynamically by reading your source files and generating the TW classes you use. It's not tree shooken anymore
Whether or not you're using Javascript doesn't matter (I guess unless you use the new CDN script which I haven't tried), but it does need to be run in a build system.
Will be interesting!
The creator of Tailwind posted a comment in this thread that the Tailwind website itself, which uses way more Tailwind classes than a normal size would use (for demoing everything), only spits out 36.9kB of CSS.
- One point where atomic CSS frameworks are supposed to shine over conventional CSS is bundle size, since they (at least the good ones) compile to only a single rule for any used value, rather than potentially repeating rules for semantically different classes.
- Another point where atomic CSS frameworks shine is just sheer volume of banging code out. When the bulk of your output is visual, mastering tools based on shorthands like tailwind, emmet, etc can feel very productive.
- Purely atomic CSS frameworks can make some workflows more difficult, e.g. by having too granular call sites and not allowing "let's see what happens to the overall theme if I do this design change" iterative style of work, or because workflows that edit CSS on the fly via browser devtools can no longer be used to limit impact within semantic lines (e.g. "I want to change padding only on buttons, without breaking everything else that happens to depend on the same padding value"). There are both design-oriented and debugging-oriented workflows that are affected in similar ways.
- You generally don't get visual regressions at a distance w/ atomic CSS. This matters at organizations where desire for pixel precision and simultaneously fickle design teams are the norm. But conversely, "can we just change the font size to be a bit bigger across the site" can often run into issues of missed spots. On a similar note, designs may become inconsistent across a site over time due to the hyper local nature of atomic CSS oriented development.
- Custom rules may as well be written in APL[0]; they usually aren't documented and it takes a "you-gotta-know-them-to-know-them" sort of familiarity to be able to work with them (or get back to them after a while).
- There are some tools that mix and match atomic CSS with other paradigms. For example, styletron[1] can output atomic CSS for the bundling benefits, but looks like React styled components from a devexp perspective, and has rendering modes that output traditional-looking debug classes for chrome devtool oriented workflows.
The main theme to be aware of: proponents of atomic CSS rarely talk of maintenance, so beware of honeymoon effect. Detractors often omit that traditional CSS (especially at scale) also requires a lot of diligence to maintain. So think about maintenance and how AOP[2] vs hyperlocal development workflows interact with your organization's design culture.
[0] https://en.wikipedia.org/wiki/APL_(programming_language)
[1] https://www.styletron.org/
[2] https://en.wikipedia.org/wiki/Aspect-oriented_programming
It's true that I haven't tried it. And I probably wouldn't, at least until someone can formulate at least a hypothetical advantage.
Not the blog post, the main landing page, ie https://tailwindcss.com/
However, there's definitely a very prominent youtube video on the linked page. https://tailwindcss.com/blog/tailwindcss-v3 That's the one I was talking about.
Maybe this shows my age, but it kinda looks like an extension of <b></b> <i></i> - you know, that stuff that we moved away from a long time ago...
Isn't this losing the point of CSS - that our "content is separate from its styling"?
I know I know, we often have to adapt our HTML to allow the styling to work properly, but this is only really true for layouts, not for colors / padding / margin / fonts etc.
I understand that we now have people writing React apps and componentising everything, but if you litter your code with styles such as "font-semibold" and "font-sans", isn't that just going to mean you have a million places to change next time a designer decides to give your webapp a makeover?
If, instead, you litter your code with my-brilliant-semantic-class you create a different kind of problem. Requirements change and my-brilliant-semantic-class won't be sufficient. Now the choice is; alter my-brilliant-semantic-class and suffer all of the unintended side effects or abandon reuse and make another-brilliant-semantic-class.
The likely choice is the latter and so applications become masses of ad-hoc, partially finished, inherently flawed styling abstractions scattered hither and yon among directories full of redundant styling artifacts, half of it long dead. How is that a benefit to some future re-designer?
> next time a designer decides to give your webapp a makeover?
I figure the odds of one approach vs the other being the greatest benefit to some future re-designer are about even, and my guess is as good as yours.
You don't refer to bananas as "the curved sweet yellow food that grows on trees", you simply refer to a banana as a banana.
Sure, for one off items it might not make sense to name it but when you create design patterns then it's incredibly useful to be able to name things.
Yes it may be hard and require you to think, but just because that is so does not make it bad necessarily.
You have (some variety of) cavendish bananas in mind. There are red, pink and blue bananas. They're not all sweet. The plants they grow in are not always "trees" but rather large fern like plants.
And then that day arrives when you are required to style some variant of 'banana' you are forced to decide: do I break the world by messing with banana or do I make new-banana?
In CSS land however you wouldn't break the world for a different banana, you'd simply add another class for the variant and style appropriately.
.banana { // generic banana styles }
.banana.musa-velutina { color: pink; }
Of course not all decisions are going to be as straightforward, but I do think that there's a lot of value in keeping a website's items consistent.
The work upfront to name things and build out concepts will pay its dividends as you extend a site or build out new ones.
Of course, there’s no right or wrong answer here, and I suspect it very much depends on what type of web systems you are building. I feel the entire debate is basically a special case of the question “do you make websites or web apps”.
If you plan on using bananas multiple times throughout your app, aren't you going to be pulling that out into a component anyway? So define that it's curved and sweet and yellow in that one place, and then insert an instance of it wherever necessary.
Sure, a Galaxy Fold is a pretty niche user device, but its genuinely the worst first impression of a mobile website I've ever seen, with everything weirdly scaled to sit in a narrow portion of my screen (other dimensions linked to px values on the video embeds maybe?). Had to load the link a few times to confirm I hadn't just accidentally zoomed out, since if I do zoom in it looks like a normal mobile stylesheet https://pasteboard.co/V0Cy3etIngpY.jpg
I struggled with css for many years but Tailwind has actually helped me improve my css - when I'm forced to write plain old css, my mental model of how everything works is much better. The fact that Tailwind has become so popular is a smell that css is slightly too low-level for most developers.
What is it about CSS that gets people so offended and opinionated? If it were a new JS framework, few people would be saying “I just don’t get XYZ. Use React”. Is it because Tailwind is so drastically different and breaks people’s core ideas about separation of concerns? Maybe it’s because we all learned CSS very early and were told to do it XYZ and now challenging that is painful.
If you honestly want to “get” Tailwind, go use it in a project. If you don’t like it, don’t use it. Nobody is going to change your mind in a comment and you’ll never convince anyone to stop using it.
Idk. CSS is what I least care about. It’s a thing. I use it to do a thing. And I move on. I used SASS. Now I don’t.
And just for the record I like Tailwind :)
I can't help but feel that Tailwind detractors have never actually tried Tailwind or are too square to give it a chance.
but your concerns arent really separate if, while in their separate files, they are concerned about the same things
and, so long as you want relative styling, they always will be. you can either (1) attach properties to your tree or (2) flatten your tree into a list of paths and attach properties to nodes that match the paths
in (1), changing the structure can only impact an individual node or it's children, only by the properties attached to the node and it's parents; changing the style can also only impact an individual node or its children
in (2), changing structure can impact the individual node, it's children, siblings or parents by any rules that now match any of the mentioned nodes; changing style will impact all matching nodes (not all of whom can be identified statically) and their children and may interact with other rules which apply properties to matching nodes.
either way, you cant escape the structure of the tree and one strategy lets you scope your changes easily, the other does not.
And yet, a lot of people swear by it and think its great. This really confuses me, and I'd kind of like to understand: how can other people like this thing that I think is terrible?
Cause it works for them? You cannot be the arbiter of what other people like or don't
I hate CSS and I find the TW classes being right there with the HTML more helpful than class-hunting through a bunch of CSS files. React solves that somewhat with styled components now. I like having design guidelines set loosely about things rather than writing reams of CSS myself. I like having media queries defined right there in the HTML. I LOVE the flexibility it offers me and how quickly I can iterate through concepts and styles
That's not necessarily what the GP said. The charitable reading is that they're genuinely, open-mindedly, asking what they're missing that's so great about it, so they too might get to love it.
Hey, maybe your explanation above does the trick.
I'll agree with having the styling information with the HTML. But there are lots of ways of doing that such as svelte-style components, CSS-in-JS, or inline css. Tailwind really didn't seem to have useful design guidelines to me. Since the classes seem to mostly correspond 1:1 with css properties, I didn't seem to be saving writing styling information. The media queries are something you can't do in inline css, but you can do it with css-in-js or svelte components.
https://news.ycombinator.com/item?id=22422873
https://news.ycombinator.com/item?id=28004515
https://news.ycombinator.com/item?id=18084013
https://news.ycombinator.com/item?id=26422286
https://news.ycombinator.com/item?id=25332101
From reading the previous threads, large projects are where it (apparently) really shines. Personally I didn't find it useful at all, but obviously YMMV.
Now I'm back working on a project with a team that is staunchly against TW and I'm having a hell of time getting back into the rhythm of naming things. Everything just kinda looks like a box so I'm having to go back to the the designer or team to pull out names for things.
Definitely looking forward to when I can go back to using Tailwind at work and on personal stuff. The cognitive overhead is real.
Also, you can prototype your stuff and then use the "extract" functionality to create components with nice shiny class names.
Components are a better way to segment semantic pieces of layout. Styling is lower level and having to name each atom of it is an enormous PITA.
For example, several of the next.js examples[1] use tailwind without explicitly stating so, because I guess it's just become a ubiquitous as css stylesheets or modules for some people. The problem I find is that it adds opinion and mental overhead for people learning related technologies or trying to get a head start without an opinionated styling solution. In order to use something like the blog-starter example for next.js I have to go and learn tailwind and then come back before I can use their blog starter, where as CSS is universal. CSS works with every project, without depending on Tailwind.
Anyway, looking forward to seeing newer improvements to Tailwind, but I hope that people will consider it an alternative to something like Bootstrap instead of an alternative to CSS.
[1] https://github.com/vercel/next.js/tree/canary/examples/blog-...
I used Bootstrap for years and give MDO major props. I learned Tailwindcss actually because it was starting to show up everywhere and many of the Next.js examples were using it. Now that I have used it I would say it changes how you think about css and styling - it gives you more power and more guardrails and it also then ships a smaller css load to the client. It was always a struggle to carve away the parts of Bootstrap you weren't using.
Is TailwindUI an alternate to Bulma ?
Kind-of. People usually pick one or the other, but they're not alternatives in the same sense as Bulma vs. Bootstrap vs. Zurb Foundation.
Bulma has opinions about structure and style, and its value proposition is providing out-of-the-box components so you can skip spending brain cycles on that design work. At a high level, Bulma believes projects reuse a lot of design patterns, and those shouldn't have to be rethought each time you need them.
Tailwind doesn't care what you want your project to look like, or how it's structured. Tailwind's value proposition is streamlining you choosing your own design, and removing footguns from that process. At a high level, Tailwind believes cookie-cutter styles are typically less reusable than you hope, that you should instead optimize for tailoring design patterns to each place they're used, and that style reuse is better implemented by e.g., React components than a CSS framework.
0: https://tailwindcss.com/docs/upgrade-guide
1: https://github.com/tailwindlabs/tailwindcss/blob/master/CHAN...
There is a point where there are so many utilities; it's just not reasonable to ask me to remember them... and at that point where I can't keep them in my mind, then the "framework" loses some of its appeal and benefits.
Of course I suppose it's up to the user to decide what they want to remember, and it is the nature of the framework to become exhaustive.
I don't really have an answer to this. Only that it further reinforces how TW is a tool, among others, and as it becomes more and more complex it can no longer become a "holy grail" sort of approach precisely because you lose the benefits of having "rails".
Cmd+K to search (it's also a pretty damn good, exhaustive search too)
This makes it difficult to have open source Tailwind components that can be imported and themed differently for your apps. Even after buying Tailwind UI, they are basically just code samples that we'd have to copy into our own libraries and maintain.
Again it's a really cool library, but feel the approach is probably better for smaller apps and teams.
Daisy UI might help with this, but seems pretty small at the moment. https://daisyui.com/
https://tailwindcss.com/docs/utility-first#why-not-just-use-...
https://tailwindcss.com/docs/adding-custom-styles#arbitrary-...
Here's a link to the repos: https://github.com/nickjj?tab=repositories&q=docker-*-exampl...
It took longer to rebuild the Docker images than making the v2 to v3 Tailwind specific changes. In my case it came down to deleting and renaming a single property in my Tailwind config file.
This comes at particularly nice timing with Rails 7 releasing at the end of the month. I can't wait to pair the two and see how well the new features of each work together.
So much of enterprise IT is little more than glorified form fill-in, and yet so few CSS/JS libraries solidly cover these use cases.
Thank you to the team and I look forward to using it more in the future.
I'm happy they have also expounded upon some of the more common FAQs on the homepage, including the extraction to components.
How can I learn tailwind enough to become proficient? Most of the documentation I looked at seemed to lack any tutorial on how to locate the correct classes I need, or any other sharp edges that might exist,
https://www.youtube.com/playlist?list=PL5f_mz_zU5eXWYDXHUDOL...
It helped me a lot!
The tailwind.config.js is missing.
I can’t even begin to describe all of the reverse engineering I’ve tried to regenerate the config file with no luck and we’re royally screwed.
Make sure you don’t lose that file!
IMO Tailwind is awesome (and cant wait to try out v3). It took me a second to warm up to it but now it makes so much sense.
You deal with a lot of minutia writing your own classes and since css is designed to be put in classes, it looks ugly when you add it to elements.
Minifying the styles into structured classes makes life so much easier. Once you map out like 5% of the lingo, you can instantly play with it like lego blocks.
I literally get the same feeling I had when I was first messing around with frontend. That feeling of power/possibilities/excitement when you can tweak a few words and shit changes on the screen.
The worst thing is it ONLY happens on the production build.
I like Tailwind CSS and I really hope they make it stable.
maybe i'm reading into it too much, but i don't think they think print readers are inferior.
The invaluable utility of which ultimately convinced us to implement real-time search into our docs as well.
The Tailwind website is only 36.9kB of CSS and it likely includes more classes than any other Tailwind site on the internet by virtue of the fact that it has to provide visual demos for so many of the classes. I don't think 36.9kB is massive personally, it's much smaller than the CSS of almost every website I've checked.
What's new in Tailwind CSS v3.0?
This is what makes me cry at night.
And/or this: https://youtu.be/cZc4Jn5nK3k
Tailwind is fine, but how they pulled off making tons of people pay for a css framework just blows my mind.
I remember reading the “UI for developers” articles, and saw how they built up the hype. This was so well done…
If you're thinking of TailwindUI, that's a separate product that's just a bunch of premade components built with Tailwind. You don't have to pay anything if you're just using Tailwind to write CSS, which is all I want it for.
Are you going to update all your HTML in a year when a fresh new hip library lands on your HN homepage?
<button type="submit" class="inline-flex justify-center py-2 px-4 border border-transparent shadow-sm text-sm font-medium rounded-md text-white bg-indigo-600 hover:bg-indigo-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-indigo-500">
Sign in
</button>
A real joy compared to writing CSS, lemme tell ya. .btn {
display: inline-flex;
justify-content: center;
padding: 8px 16px;
border: 1px solid transparent;
box-shadow: 0 1px 2px 0 rgb(0 0 0 / 0.05);
font-size: 14px;
border-radius: 6px;
color: #fff;
background-color: rgb(79 70 229);
}
.btn:hover {
background-color: rgb(67 56 202);
outline: 2px dotted transparent;
outline-offset: 2px;
box-shadow: 0 0 0 2px #fff, 0 0 0 4px rgb(99 102 241), 0 1px 2px 0 rgb(0 0 0 / 0.05);
} .btn { display: inline-flex; justify-content: center; padding: 8px 16px; border: 1px solid transparent; box-shadow: 0 1px 2px 0 rgb(0 0 0 / 0.05); font-size: 14px; border-radius: 6px; color: #fff; background-color: rgb(79 70 229) } .btn:hover { background-color: rgb(67 56 202); outline: 2px dotted transparent; outline-offset: 2px; box-shadow: 0 0 0 2px #fff, 0 0 0 4px rgb(99 102 241), 0 1px 2px 0 rgb(0 0 0 / 0.05) }
<button class="
inline-flex justify-center
py-2 px-4
border border-transparent rounded-md
shadow-sm
text-white text-sm font-medium
bg-indigo-600 hover:bg-indigo-700
focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-indigo-500
">
Submit
</button>
My experience (and the experience of thousands of others) is that in practice, an approach like Tailwind is much more maintainable, even if it's superficially ugly.At the end of the day it's a lot easier to understand what's happening in a template where you can see all of the styles directly attached to each node instead of having to map things together in your head across multiple files.
For example, for me at least I can't believe how much more difficult it is to look at your average CodePen demo and understand what is doing what at a glance vs. looking at a Tailwind template. With traditional CSS there is just _so_ much indirection in comparison.
<button class="px-3 py-2 bg-green-300 text-green-900">hello, brainzap</button>My impression is that most of the negative comments are coming from people that don't code for Web often (I could be wrong). To those folks: I'm not saying you don't know your stuff or that you argue badly - since I was on that side myself a few months back.
What I am saying is that the elegance and pragmatism of Tailwind might not be easy to intuit just by reading about it. Try to implement a simple landing page using Tailwind+TailwindUI and see if any lightbulbs gets lit.
When you write anything substantial you end up with class name soup. The answer to this is to use `@apply` which is literally just a normal CSS class with extra steps.
The new vernacular just means that users have to learn Tailwind language rather than proper CSS.
CSS modules solve the main problems that Tailwind attempts to solve. The other things are solved with use of CSS variables.
The only thing that I find useful in Tailwind is the responsive design classes. Being able to do `md:<some other style here>` is pretty cool.
To me, Tailwind seems valuable to newer engineers because they feel like they don't have to learn CSS. They learn "Tailwind." It's like all those people who would say "I don't know JavaScript, I know jQuery." Like jQuery, there are benefits in having a unified language especially when you're newer. I believe that a better solution to styling is inevitable (my latest favorite heavily uses CSS variables). I do not believe Tailwind is the best way forward.
Other times, I would write web components with lit. With shadow dom, web components would have their own little bits of CSS, which provides sufficient amount of encapsulation that neither CSS modules nor SCSS are really necessary.
I don't have any problems with importing CSS from (S)CSS files or writing it inside of a LitElement-based web component. I don't have any problem with writing CSS by hand either. I find it strange that people would want to learn another domain-specific language for CSS, in addition to the CSS itself and DOM's camel-cased style dialect.