adamwathan
.rounded-full {
border-radius: calc(1px * infinity);
}
...as opposed to what everyone has done historically, which is pick some arbitrary huge value like: .rounded-full {
border-radius: 9999px;
}
No real practical benefit, just satisfyingly more "correct".So things are fine but we do need to reverse the trend which is why we are pretty focused on the commercial side of things right now.
We started a corporate sponsors/partner program recently, and I'm hoping that will earn us enough funding to focus more on the free/open-source stuff, since that's where we create the most value for the world anyways. Fingers crossed!
We have a pretty collaborative/sync culture here. Everyone on the team really enjoys pair programming together or working through designs live in Figma, and wouldn't want to build the team in a way where there are people who can never work together because of timezones.
We’re hiring a Design Engineer and Staff Software Engineer to work on Tailwind CSS, Headless UI, and related projects full-time.
- Design Engineer ($275k/yr): https://tailwindcss.com/careers/design-engineer
- Staff Software Engineer ($275k/yr): https://tailwindcss.com/careers/staff-software-engineer
We're small, independent, and profitable, with a team of just 6 people doing millions in revenue, and growing sustainably every year. You'd work directly with the founders on open-source software used by millions of people.
If you like the idea of working on a small team that cares about craft and isn't trying to achieve VC scale, I think this is a pretty awesome place to do your best work.
Re: separating presentation from page structure, Tailwind is designed around the opinion that that whole idea was mostly wrong, similar to how frameworks like React brought back the `onClick=` attribute when everyone was saying “unobtrusive JavaScript” was the best practice
Wrote about this in depth a few years ago shortly before releasing Tailwind, can read here:
https://adamwathan.me/css-utility-classes-and-separation-of-...
Here's one:
.foo .bar {
.baz & {
color: red;
}
}
In Sass, that would compile to: .baz .foo .bar {
color: red;
}
With native nesting, it effectively compiles to: .baz :is(.foo .bar) {
color: red;
}
The Sass version matches this DOM structure: <div class="baz">
<div class="foo">
<div class="bar">
...
But the native version matches all of these structures: <div class="baz">
<div class="foo">
<div class="bar">
...
<div class="foo">
<div class="baz">
<div class="bar">
...
<div class="foo baz">
<div class="bar">
...
Not a criticism at all (the `:is(...)` behavior is a very useful and welcome enhancement to CSS) but a notable difference worth understanding coming from Sass.https://twitter.com/jarredsumner/status/1542824445810642946
Easy to dismiss this as "another JS build tool thing why do we need more of this eye roll" but I think this is worth a proper look — really interesting to follow how much effort has gone into the performance.
Check out this HDR YouTube video at this timestamp to see how bright white actually is at 1600 nits:
https://youtu.be/NlAsAuBtmps?t=180
Here's a photo of my XDR display with a pure white rectangle in Figma next to white content in an HDR video, with the display set to the 1600 nits mode:
https://www.dropbox.com/s/rmvu6r6vugaxg95/xdr-brightness-com...
We worked with several accessibility experts when building Tailwind UI for example, and I am very confident in the semantics of all of that markup and how it performs in situations where that actually matters like when using assistive technology, because we tested it ourselves.
.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.
.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);
}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.
Agree that if inline styles offered all of the features you get when writing your CSS in a stylesheet that it would be a compelling option because of the simplicity, even though the verbosity would be a big knock against.
Keys in the config file generally correspond with the CSS property they refer to, and we use the singular form to make it match the CSS property.
There are 3 exceptions, which are "colors", "spacing", and "screens", and these are sort of special keys that don't map to anything in CSS. The "colors" and "spacing" keys are more like reusable variables that are consumed by the property-specific keys like "backgroundColor", "fill", and "borderColor" in the case of "colors", and "width", "height", "gap", and others in the case of "spacing".
The "screens" key is a list of breakpoints for your project, which also doesn't map to an underlying CSS property.
Originally we tried to keep things really abstract and group things together under concepts like "spacing", "typography", whatever, but ultimately found it was more flexible and predictable to make it possible to customize every CSS property using the exact property name, while only providing a couple high-level things like "spacing" and "colors" that you can use to update other dependent keys at once.
Getting complex config files right is unfortunately hard and it's not perfect for sure. At this stage in the project it's a delicate balance between improving things and maintaining backwards compatibility. Totally appreciate what you're saying, just wanted to do my best to clarify though as I'm equally picky about this sort of consistency.
We've been doing Shape Up since July 2020 and have yet to fail to ship what we shape for each 6 week cycle, and while there's sometimes a bit of a crunch in the last few days before a release, everyone is generally working at a pretty relaxed pace.
My favorite side-effect of working this way as a leader is that by batching 6 weeks worth of planning effort, the team (and myself) can just be generally left alone to get into it without having to decide on the next priority every single week. Combined with async check-ins (that the team provide themselves every couple of days via Basecamp) instead of daily/weekly stand-ups, everyone generally has an empty calendar at all times.
I’m an outlier for sure but $20k is low. If you do a great job at everything that goes into running a business like this you can definitely do much better than that. Josh Comeau did an incredible job building his audience and reputation before releasing his CSS course a few months ago for example and he has done over $500k if I remember right.
I wrote in detail about the process of writing, marketing, and releasing my first book here:
https://adamwathan.me/the-book-launch-that-let-me-quit-my-jo...
And was interviewed on IndieHackers to talk about the most recent one here:
https://www.indiehackers.com/podcast/098-adam-wathan-of-refa...
If the work is a good match for your skills and personality it’s a really great way to make a fantastic living.
Seeing a bunch of incessant vitriol in the mentions all the time about something I've worked really hard on for many years is very distracting and upsetting to put it mildly, and on days when my emotional reserves are already low from the stresses of figuring out how the hell to make money working on the project or having a young family it's really not a healthy thing to have to deal with.
Criticism being delivered in good faith is welcome and productive, but constant holier-than-thou "wow whoever created this is extremely stupid compared to me and clearly has no idea what they are doing" is not that.
I've only ever blocked two people for this sort of abusive crap since 2017, in case that provides some perspective.
Tailwind CSS is a "company" now in the sense that Steve and I built a commercial product to make the OSS stuff sustainable, and it turned out to be successful enough that we could hire handful of other people to help out, but I certainly don't think of us as some sort of faceless corporate entity. We don't plan to grow the team and I don't plan to become a full-time manager — I just want to keep working on interesting OSS projects and we decided to use the revenue from our commercial stuff to make that possible by hiring people to help with customer support, working full-time on existing OSS things from the ecosystem (we hired the person who built the OSS Tailwind IntelliSense extension for example), and to keep up with the barrage of GitHub issues we see as a popular project.
Tailwind CSS itself is very much a personal project of mine and a labor of love, and for better or for worse it's not as easy to detach yourself from projects you pour that much into as people (who have no perspective on the emotional challenges of being the face of a popular and polarizing project) make it sound.
The JIT engine is our solution to this, and ensures the CSS file is never large so it never causes these issues. We have done a ton of work to iron out bugs in the new engine between 2.1 and 2.2 so I would definitely give it a shot and see how it goes.
Consider even using our new CLI tool to compile your CSS instead of integrating it into your Ember build step — on the biggest project we’ve tried (over 400 template files, some thousands of lines long), the new CLI compiles the CSS in about 400ms, and incremental rebuilds when you save a template file take 3–10ms.
https://github.com/tailwindlabs/tailwindcss/discussions/cate...
Managing OSS stuff really is brutal, and the amount of negative stuff you hear is hugely disproportionate to the amount of positive stuff. Anything to encourage the happy users to speak up once in a while can go a long way toward preventing OSS maintainers from burning out.
Crazy amount of effort went into building all of these interactive examples, so proud of how it turned out.
The trailer in the blog post is absolutely 100% a joke in case it's not obvious. The music was scored for us by a friend, and that's a real life professional opera singer at the end chanting "utility first" in Latin. It's completely absurd and absolutely outrageous, just laugh at it :)