SW engineering, engineering management and the business of software

subscribe for more
stuff like this:

A Brief History Of and Advanced Tricks With Tailwind CSS

TOC

I don’t spend a lot of time blogging or thinking about CSS much. For many years, there wasn’t that much interesting happening in the CSS world to me personally as a developer. The spec advanced, but it was just a layer of paint I splashed on at some point in the development cycle.

Tailwind

Something changed however, when I discovered Tailwind CSS. Tailwind launched it’s first alpha back in November 2017. The official v1.0 was released May 13, 2019. It came a cross my radar sometime in late 2019 as my network started chatting about it. Tailwind UI1 was a paid product that launched to tremendous success in early 2020. This success allowed the core developers to build a business and hire a small team around the parent company Tailwind Labs.

I started learning and using Tailwind shortly after Tailwind UI was released in 2020. Tailwind CSS v2.0 arrived in November 2020. The project momentum is strong, and as far as I can tell, still growing.

It should be obvious by now that I believe Tailwind CSS to be an amazing project and I think it can be one of those development points of leverage. That is to say, investing in Tailwind CSS has a transformative ROI. Not many technologies can make that claim.

What makes it amazing

The biggest issue with CSS is that it’s hard to compartmentalize. It’s designed for side effects2 and that makes it so most usage of CSS is quite fragile.

Tailwind kind of rejects half of traditional CSS. The tagline is “Utility-First” which kind of means: never style with ids, only style with classes. In addition, Tailwind also rewrites a good chuck of the classic css syntax into more usable, composable chunks for the modern web.

Thus:

  1. There’s a learning curve
  2. Your CSS is deeply embedded into your HTML

All I can say is don’t worry about it, because they essentially took a fragile yet essential piece of web tech and somehow massaged it into something beautiful. And as an Engineer, I don’t mean beautiful aesthetically, but beautiful in that you can build great looking web components that don’t break other parts of the page as you layer them in.

In other words, properly using Tailwind CSS results in high product velocity. And as Engineering Manager and Entrepreneur, that’s really the best thing I can get out of my tech stack.

To be clear I don’t mean just shipping features fast. Embedded in the notion of high product velocity is that you not only launch quickly, but also that you have low defect rates, tech debt accumulation and mental trauma over the lifetime of the code you write. Unlike any other CSS framework, library or ecosystem I’ve come across, Tailwind achieves this.

Some Advanced Tricks

I’ve been doing a lot of Tailwind recently. I’ve launched two web apps using it and very recently redid the CSS on this very site. The original CSS was probably from back in 2011 or so. You can see what it used to look like here.

I’m going to go over some of the more creative chunks of design I was able to pull off with Tailwind.

This site is statically generated from markdown, so the first thing was to set up a build process to pull all that html into the tailwind app so that purgeCSS can do it’s thing. You can read about how to do plain old HTML and tailwind here.

Trick #1: Fancy blockquotes

I don’t know why, but I’m particuarly keen on how blockquotes look here. The original design idea wan’t mine, but I remember seeing something like it a decade ago and coming up with my own spin on it:

Immature poets imitate; mature poets steal; bad poets deface what they take, and good poets make it into something better, or at least something different. ― T.S. Eliot, The Sacred Wood

We make heavy use of the prose class from @tailwindcss/typography.

The trick to this one is to extend the typography classes in tailwind.config.js like so:

Again, since we make heavy use of prose and its responsive size variantes, we can’t do this one in style.css.

We have to extend the default theme via the config file. the big double quote from the blockquote:before declaration. We choose a nice serif font, escape the double-quote character ("\\201C") make it big and massage the margins to give a bit of offset and even break the frame a little.

We have to make sure the sizes and margin adjustments look reasonable at all the size classes we use.

I did a lot of hand tuning on this one and liberally borrowing from the default styles helped quite a bit.

Trick #2: Styling the scrollbar on Code Fences

A code fence from markdown looks like this:

"scripts": {
    "debug": "postcss site/static/css/input.css --verbose --config debug --output site/static/css/style.css",
    "build": "postcss site/static/css/input.css --verbose --config build --output site/static/css/style.css"
},

In the initial transition to Tailwind CSS, the scroll bar on the fence was white and the gray was the system gray.

I wanted the background of the scroll bar to look like the rest of the code fence and the scroll bar thumb to match the Tailwind CSS color palette.

This one just took a bit of Googling. In your input.css or style.css file add the following lines:

This is a great example of customizing the source input.css file rather than tailwind.config.js.

It’s just CSS. You can put anything you need in there.

Trick #3: Superscript, Subscript

I’m not sure why this isn’t baked into either TailwindCSS or @tailwind/typography, but there is no support for superscript <sup> or subscript <sub> as of 2.0 that I can find. I typically use this for math stuff like my explanation of the 1% phenomenon: 1.01365 is about 37.7 vs 0.99365 is 0.0188.

This one is easy. we just add support for <sup> and <sub>in input.css or style.css, whichever is your base css file.

Trick #4: Quiet Links

Sometimes I want my links to pop out and grab the user’s attention.

Sometimes I want a quiet list of resources. you can still hover overthem, but the lack of color and underline indicates they aren’t the real focus of the content. I also use this trick for footnotes and the TOC at the top of this page as well. It’s still fairly discoverable with a mouse pointer due to the hover state. It’s not very mobile friendly, so I do use this sparingly, especially within the main content.

We have to rely on the dreaded !importanttag for this one. If any CSS or Tailwind experts can let me know why .prose a seems to have priority over the inner class quiet-tag I’d love to hear why.

.quiet-link {
  @apply text-gray-200 hover:bg-gray-400 hover:text-black !important;
  @apply no-underline !important;
}

Also, you can’t use markdown links. You have to manually (gasp!) craft the anchor tag so you can put the quiet-link class in there.

Trick #5: Footnotes

Footnotes are a goofy beast in plain markdown. While some markdown variants have support for them, I’ve decided to do them manually.

This is an example of mixing two Tailwind customization techniques together. This particular implementation is basically squishing tricks 3 and 4 into a couple of helper classes.

We will extend utilities with a new class, fgoto. This allows us to put some plain old CSS into the class. Additionally, we use the @apply to add in some tailwind keywords into the class.

Note the use of the !important decorator. I couldn’t get it to work because .prose a kept overriding the fgoto and freturn styling. I couldn’t figure out how to do it without it. IF you can shed light on that, please let me know on twitter.

Using footnotes looks like this:

<a name="b3158542291"></a>
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nunc 
maximus nunc velit, sit amet scelerisque lectus consequat ut. Ut 
fringilla orci nec ultrices luctus. Phasellus justo nibh, 
porttitor sed varius at, posuere a arcu. Nam porta metus at elit 
molestie commodo.<a href="#3158542291" class="fgoto">1</a>

Praesent aliquet mattis tempor. Curabitur leo ante, varius eget 
lectus non, convallis consectetur ligula. 

---

Footnotes:

<a name="3158542291"></a>
1. FOOTNOTE_CONTENTS.<a href="#b3158542291" class="freturn">↩</a>

I just use random numbers as the anchor tags but feel free to use whatever.3

You may recognize some of the css in this one. It’s basically lifted from the superscript section. I didn’t want to rely on both sup and the fgoto and freturn so a bit of duplication. If this offends your sensibilities (and it reasonably might), feel free to remove the utility extension and wrap your fgoto anchor tag with the <sup> tag.


  1. I’m a paying user of Tailwind UI and I’m a huge fan. Tailwind Labs continues to add more and more components and example designs. It allows me to punch waaaaay above my weight level as a non-designer. You still need to know CSS, but the component are very well designed. The implications for me personally is that it allows me to save time and money by not having to hunt for new templates every time I work on a new project and in somecases, bypass the need to hire a designer for things like an MVP or early launch.
  2. Don’t get me started on the !important nonsense.
  3. What I really do is use a Keyboard Maestro shortcut to generate a random number and all four tags at once. Easy Peasy.


in lieu of comments, you should follow me on bluesky at @amattn.com and on twitch.tv at twitch.tv/amattn. I'm happy to chat about content here anytime.


the fine print:
aboutarchivemastodonblueskytwitchconsulting or speaking inquiries
© matt nunogawa 2010 - 2023 / all rights reserved