I had two major complaints and this update fixes both. The first is the enormous size of the css file locally, which caused the browser to become considerably slower and made the developer tools really slow to load when selecting elements. The second was the lack of the !important selector.
This is a solid update. Kudos to the team.
I also love Tailwind, glad to know it's about to get better.
Note: I’ve written a lot of CSS and generally prefer rolling my own components to using a library... perhaps I’m not the target audience. Perhaps this is a cherry flavor to make the “designing your own UI” medicine go down more easily. Perhaps I’m mistaken and not being charitable enough, too.
This approach allows tailwind to be terser than raw inline styles, while giving you the ability to write a lot of your styling inside the markup, which prevents context-switching. It's a nice balance between many of the approaches that have come before it.
If you're using styled components and you want a small margin you have to do something along the lines of.
const ThingWithMargin = div.styled`
margin: ${margins[1]}
`;
Presuming you've set up a file full of font sizes, margins, paddings.In TailwindCC you get a bunch of very sane, well picked defaults chosen for you for free, by default. You write in a simple DSL and don't have to worry. You can update the defaults as you see fit, too.
<div className="m-1" />
This has autocomplete, etc etc.IF you don't want the clutter of all these utilities, you can abstract them away into smaller components as you already should be doing. You build your component library with speed and can focus on the actually interesting parts of your system as opposed to wasting time naming stuff or pissing about with CSS.
And of course, if your div is reused a lot, you naturally abstract it into a component at a time that suits you!
I'd say try just using for a project or two and you suddently realise you were wasting a whole lot of time and effort before.
Anything truly dynamic calculated can go also into a style= prop. They work great together!
E.g. here's a progress bar I made for a thing:
<div
ref={ref}
className="w-full relative cursor-pointer -mt-1 -mb-1.5 h-3.5"
onMouseDown={onMouseDown}>
<div className="absolute h-1 top-1 bg-gray-600 bottom-0 left-0 right-0" />
<div
className="absolute h-1 top-1 bottom-0 left-0 bg-gray-200"
style={{
width: `${(currentTime / duration) * 100}%`,
}}></div>
</div>
I was so sick of working web because it felt like working in CSS was a total footgun unless you spend a lot of time making a solution that does things right. Now I find working on web projects a joy again. my-component {
margin-inline: var(--margin-thin);
}
If I want this dense notation I can name the custom property `--m-1`. In most IDEs (or language servers) I’ve tried custom properties also have autocomplete.That is I use CSS custom properties inside component scoped styles. (Component scoped styles is what I call the general idea that React’s styled components are implementing, but Vue’s SFC and the shadow DOM scope the styles to the component at hand equally well).
I’m not saying “Don’t use Tailwind; use custom properties instead”. But for those of us that don’t like the idea that Tailwind brings, there are options, and we are perfectly happy with what we got.
If you give the combination of Tailwind + Alpine.js + your favorite server-side templating engine a try, it may just click. At least for me, that was the key.
My assessment is based on the fact that when you design something, you generally have to be able to explain its value, with little exception.
As someone who’s used this approach in production for years I can vouch for it. It greatly reduces complexity and is easier to maintain. Day to day no one is writing any css at all, nor are they bogged down with naming conventions, etc. You just “snap” together your utility classes ad-hoc as needed.
Responsive breakpoints are also much easier to work with because they’re just “built in” as modifiers on all the base utility classes.
So, when you use JIT you no longer get all tailwind classes in chrome dev tools only the ones you applied to components. I know it's by design to keep css lightweight. But that also means I can no longer design UI using Chrome dev tools. Only when I apply tw classes directly to component in editor like vscode it reflects the change in browser. this back and forth cycle between editor and chrome took the fun away from me :(
When I'm building, I'm typically using a toolkit like vuetify or bootstrapvue. These are dozens of components - tested, documented, expanded on, and styled (using bootstrap or material design or... whatever).
The 'just to go tailwind!' I keep seeing seems to assume I want to rebuild components (and then test them) which already exist, and are designed to work together. The common refrain is "but all those sites look the same!" but... I can change colors, sizes, and... when needed, a bit more, by going in to the scss (or similar) and recompiling.
I understand the 'purge' stuff in tailwind is nice and useful (tested it firsthand) but the time/effort of rebuilding large sets of components (which are, often, by and large commodity things) is so far a hard sell for me. I was on a team last year that was in their second round of developing their own in-house UI toolkit - basically recreating most of bootstrap-react, but poorly, and with no testing or accessibility, because "bootstrap is bad". They were so far behind they thought they were ahead...
I'm just not grokking all the tailwind love. I've played with it, and yes... I guess anything that you learn and spend time with will, overtime, become 'natural' and save you time.
It's impressive tech, for sure - not trying to downplay it.
But for the kinds of applications I build there simply does not exist a “UI toolkit” that could save me any amount of time worth the hassle of ingesting another library and finagling it to my needs for what? Maybe 15% of my UI? The value in the tools that I build is partly in the UI I make to interact with them.
There is nothing more frustrating than the 5th or 6th time you just need the padding to be a little different to make your component pop, and you have to slog through the docs/source figure out how to adjust 2px...
You're right though that a lot of people who jump straight to tailwind probably don't realize that its low level might be too low for their needs. A higher level component library like bootstrap, tailwind ui, chakra, etc. is a better start in many cases.
There is also a “free” site, which offers lovely designs: https://tailblocks.cc/
Every team eventually tries this and fails to some degree, incurring costs along the way.
Also it's a lot like Akin's 39th law of spacecraft design:
https://spacecraft.ssl.umd.edu/akins_laws.html
But replace "launch vehicle" with "in-house UI toolkit".
It baffles me that people time and time again make the judgement that their several months of work are somehow more worth(in terms of effect) than literal man-years put into a decent UI library.
I'm looking into their react-aria and react-stately libraries which appear to just give you the hooks that power the UI components and then you can supply your own markup.
Tailwind has headless-ui coming out soon which appears to be very similar to the aforementioned two libraries so that may fill the void but it'd be nice to have a something now. At the moment I'm using Tailwind for mainly static informational sites rather than interactive UIs until I get around to making an internal library of components that I can style with tailwind css. At the end of the day it's basically just CSS anyway.
Before Tailwind with PostCSS, I'd probably hand roll some Sass-powered UI, or find a template to base it off of.
You'll probably always want AOT for the "critical css" in the first load, but afterward, JIT might be reasonable.
At a minimum, it should be feasible. You can override Prototype's appendChild, replaceChild, and insertBefore to grab classnames and generate CSS before the DOM is updated. Everyone will tell you this is insane, but it seems to work.
But it's unclear if this leads to something "better" than the AOT solution. It feels like code golf: will the transpiler have less bytes than the CSS generated by a pure AOT solution? The tailwind folks have come up with a really dense way of expressing verbose CSS, so I think it's possible!
No affiliation to Tailwind. Just playing on weekends.
Large companies have too much baggage - fear of breaking compatibility, and don't develop new enough things.
There is a certain size where changes are exciting, or certain company cultures that encourage new stuff. Tailwind is there, and it is always fun to get their update emails.
I'll echo other folks who have said that using Tailwind has significantly increased how quickly I can put together frontend stuff -- it's close to a 5x speedup for me workflow wise.
This is really not that different from the frontend world where you've got a markup language to define semantics of the view, a logic layer in JS to pull in data with web requests to populate the view, and CSS as a style layer to make the view look good.
Welcome to what us React folk have been saying since at least 2016. Splitting your code by language is bad. Vertical slices for the win.
- A fellow React folk.
Sorry to go on a tangent here with a commentary unrelated to the discussion at hand (which is indeed an interesting one), but can we please stop with the rape jokes. They are not funny, and may be triggering to a large portion of your readers.
I think a lot of the love for tailwind are people finally getting the mental OK to remove the strict isolation of style and template/code which has been dogma for 20+ years. If you're using something like vue, svelte, or a good web components library you can just define components with all their markup and style in one place, all using bog standard CSS. It's fine.
That said, self-promotion disclaimer but if you like inline/utility CSS, and also like TypeScript/React/Emotion, we've got a "Tailwinds-ish" CSS-in-JS library that we've enjoyed so far:
https://github.com/homebound-team/truss
Would love to have people try it out.
Can't wait to upgrade Tailwind on my project and try this out :)
I feel tailwind is somewhat going down that path, but I wonder if this is a problem that a bundler can solve.
I use tailwind with tsx react components and it seems the tailwind just-in-time mode won't work with that.
When Laravel refreshed its documentation design, I wrote a stylesheet to revert it almost entirely to the old design. I could do it because restyling something like `.sidebar` is super simple. The new class list is
fixed top-0 bottom-0 left-0 z-20 h-full w-16 flex flex-col bg-gradient-to-b from-gray-100 to-white transition-all duration-300 overflow-hidden lg:sticky lg:w-80 lg:flex-shrink-0 lg:flex lg:justify-end lg:items-end 2xl:max-w-lg 2xl:w-full
And that is much harder to maintain in a user style.One area I'd love to see Tailwind tackle is better targeting for child elements. I understand the library is functional and the classes are atomic, but I think being able to chain and target arbitrary children elements would be quite powerful.
<div class="md:top-[-113px]">
Instead of this: <div class="md" style="top: -113px">
Why would you want to inline your overrides directly in the class names instead of just using style?Inline styles apply all of the time. With a class, you have access to media queries and thus some basic form of logic.
The “md:” prefix is used exactly for this. It applies any following class at a medium media query breakpoint. Same thing with focus or hover styles, also impossible with an inline style attribute.
The custom overrides are obviously more one off and less reusable, so the difference between those and a style attribute are less obvious at first glance. With classes though, you are bound to the class names in your stylesheet and thus some form of sanitization/linting. Inline styles won’t stop you from breaking your design system.
Is there a vscode extension that possibly aligns classes in new lines? Alphabetical sorting could be nice as well.
Is this on the horizon for the Tailwind team? The intellisense extension is quite good so it’s possible this is a problem they are working on as well.
I don't know honestly, I just wish there was a convention.
The problem is more, that to my knowledge, none of them got wide adaption. You could at adapt them on at least a company/team wide level, but don’t know what tooling there is to make it easily configurable.
Otherwise, I usually try to separate out states when using @apply.
` .example { @apply bg-blue-100; @apply hover:bg-blue-200; @apply focus:bg-blue-200; `
But now with JIT you could simplify if you wanted to:
`.example { @apply bg-blue-100; @apply hover:focus:bg-blue-200;`
something like <div data-css-size='large flex-box display-flex' data-css-color="red" data-css-font="gotham serif"></div>
then something like [data-css-color*="red"] {color:red;}
I haven't tested this just thinking off the top what might work
- https://github.com/nickjj/docker-flask-example
Unfortunately, the podcast hasn't been kept up in the past few months. I assume TailWind is taking all of Adam's time now?