ramoska blog logo showing grasshoper

ramoska

Playing with Tailwind CSS

Posted on December 2023 in Web development

The days of yore

Before I resurrected my blog, I was using a theme I made myself. It was clean, minimalistic, light theme with a cute custom logo drawn by my sister in law. I really want to have that same feel back, but theming engine in Pelican has a bit different layout, different data passed to templates and old theme used bootstrap. I really don't want to invest my time in working with it, and also as a side effect include a lot of unused CSS and JavaScript on every page load. And I heard of frontend people in my previous workplaces (plural) talking about Tailwind CSS, and how they like it. Looking into it, it seems like a bit of a framework for CSS, with its own config, build process and everything. But it results in single CSS file I could include in my theme and be done with it. So let's give it a go.

Preparations

So first thing to do is install tailwindcss npm package. Quick search on tools similar to pipx for npm and I found only npx. But that's not what I want. I want to install npm package globally, but in such a way that it sits in its own virtual environment with binaries available in my $PATH. Since I didn't find anything of sorts and didn't want to invest my time in it, I just created new nom package in my blog themes directory and installed tailwindcss as a dev dependency (with adding themes/blog.ramoska.eu/node_modules to my .gitignore). And let's create Tailwind config file with npx tailwindcss init and add templates directory for tailwindcss to look for used CSS classes. Also I need to add actual templates and static directories for Pelican theme to work. Also I need to create actual templates according to Pelican theming docs:

├── static
│   ├── css
│   └── images
└── templates
    ├── archives.html         // to display archives
    ├── article.html          // processed for each article
    ├── author.html           // processed for each author
    ├── authors.html          // must list all the authors
    ├── categories.html       // must list all the categories
    ├── category.html         // processed for each category
    ├── index.html            // the index (list all the articles)
    ├── page.html             // processed for each page
    ├── period_archives.html  // to display time-period archives
    ├── tag.html              // processed for each tag
    └── tags.html             // must list all the tags. Can be a tag cloud.

After creating all templates with dummy content, creating style/main.css and testing it with npx tailwindcss -i style/main.css -o static/style.css seems to be working fine. With preparations complete I can move to shaping template base and can't really wait for it since it was a very long time since I last had to create HTML and CSS from scratch (if using Tailwind can be called that).

Writing base template

Looking for inspiration

Getting down to business. I want to have responsive layout with sidebar, header and main content area. I imagine sidebar containing links to about, archive, other pages to make content easy to navigate. Aldo it could contain icons with links to social media and GitHub profile. Nice to have things could be tag cloud, table of contents for articles. And while researching I found nice plugin called series, which allows to link articles together to form a series. And I instantly noticed that I am thinking about this theme as a desktop theme. Main problem with that approach is that it's easy to add things, and it's way harder to subtract them (removing elements from layout). Let's change that.

Imagining how I open my blog on my phone, I want to see header with links to social media, GitHub profile page. I'll need to think how to expose links to other pages (about, or archive). I think they're necessary to make blog accessible. When screen gets bigger, I imagine header becoming sidebar on the left and having extra sections there. And when screen gets even bigger, I could add table of contents for articles. Inspiration for this I'm taking from Transmit theme from Tailwind CSS showcase: I really like how header in that theme becomes left sidebar and that just clicks with me.

Transmit theme preview

Making layout for mobile

With that in mind let's start with the base template. I'm opening Firefox and switching to dev tools in responsive mode. Going with most primitive template containing basically only header and main content area. Adding logo and links to social media and GitHub profile, using font awesome icons. After having that I start to sprinkle Tailwind classes here and there to make it look decent to my untrained back-ender eye. Result doesn't look too shabby. Next break point in Tailwind is md (medium) at 768px and it doesn't look I need to change anything. Moving on onto lg at 1024px and that's where I need to make changes. And then changing "devices" and viewing theme in different resolutions I noticed something funky and styles under md selector affecting styles on smaller screens. And it so happens that I forgot to add:

Noob mistake as I imagine when trying to work with responsive designs. Now I have to look over my sprinkled styles again, because I viewed my theme in wrong resolutions. Going over sm screen again. Also need to look into all that rem, wv, hv and all other magic units - back when I did little of frontend all I've dealt with was pixels and percents (yeah, yeah, I know - dinosaur). After playing around a bit with sm and md screens I have more or less what I want from layout. Still strange to use classes like good old inline style - writing w-1/2 or md:max-w-3xl instead of <a style="width: 50%" href="#">link</a>, but I feel like I'll get used to it quickly.

Moving on to desktop

Now it comes to tricky part for me - going with flexbox to move header to sidebar and making it all limited in width. I'll be using this layout technique for the first time, so some learning will be involved (and most likely some mistakes). It looks like I just need to add flex class to body tag and everything drops into its place. Playing a bit with max width and text sizes and it looks like I have what I want. Now all the small things to finish - displaying additional fields, adjusting padding and margins, etc. And implementing the rest of the templates.

Extending with meta tags

After layout is working pretty much how I want it, I need to finish templates and update base one with additional blocks, that actual pages could extend and add missing attributes, like keywords, description, etc. Also seems like index pages for tags, categories, and some other could reuse index.html template.

Theming

Start with spacing

Now that I have layout and templates finished (for now at least, since I don't know what I'm missing or have too much of), I can start with formatting content. Tailwind by default has all styles sort of disabled (or reset if you prefer). I guess it makes sense not to leak any styles into your theme. So after getting done with spacing and text sizes, it's time to move to colors. And this is most likely where I'll have the hardest time since I'm no designer nor I'm good with colors.

Colors

I remember there used to be online tools for colour-challenged people like me to help with choosing colors. Sadly I can't remember any of them, so quick search showed quite a bunch of them. After trying a few I going with the one called palletmaker - it has preview of how website/app could look with generated colour palett, and quick easy to use UI. I'm filtering by colour green and pallet being basically different shades of green. Let's put these colours to Tailwing config and see how to use these colours in styles. I'm putting colours into theme.colors.light since I plan to have dar theme also. But most likely not today taking into account how long it takes for me to select few colours for th light theme already. And it takes a lot for me. And I'm still not happy with colours and find myself changing them over and over again. Using colour in CSS classes is pretty straightforward - just use path to color as a name in CSS class. For isntance to set bg colour to one defined in theme.extend.colors.light.background I just need to use bg-light-background class. And it works. After setting one for header I once gain adjust colour code for that colour. I'm not a designer... What is left is to set colours for links, tweak styling of code blocks and deploy all these changes. And all that experimenting with colours took me a lot of time and it is all wasted because I still don't like how it looks and I'm just going with plain white background and dark text with some green accents. I have new found respect for designers.

Impressions on Tailwind

Classes, classes everywhere

After playing with Tailwind for a few days I can say that I might be liking it. A bit. Or maybe not. I'm not sure. I mm not a huge fan of having too many classes in class attribute. At least it's my understanding of how it is supposed to be according to authors of Tailwind. On the other hand it is possible to have custom classes and @apply any Tailwind classes to them. I guess my biggest bone to pick with Tailwind is that I need to learn all these classes and how to use them when I already (almost) know CSS. But IDE support helps a lot with that. Also most of the time I am dealing with padding and margins, so not much to learn I guess. Only what units mean what and what numbers mean which unit. To me it feels like doing Django - you kinda work with Python, but you need to learn Django's way of doing things and read their docs, not Python's.

Config

I didn't think that I'll be writing about Tailwind config, but here I am. First of all why it had to be so easy to fuck up? I want to introduce some colours for my theme. I look into docs and I see that I should put them into config under theme.colors key. That's all good and working for now, but suddenly I find myself not able to use text-red-700 class to set text to red. And I'm starting to think that I can have either my set colours or the ones predefined by Tailwind. But after looking for something completely unrelated I find that there's config key theme.extends. And after moving my config from theme.colors to theme.extends.colors I can start using both default colours and mine in class names. After looking into colours docs I see now that it explains how I can have both, but I would expect default behaviour to be extend, not override.

And that also brings me to my next annoyance with Tailwind and its config. I have to set my theme colours in config, not in main.css file. Tailwind is still preprocessing whole main.css to spit out (minimised) resulting css. So why can't I have my colours in same file close to other defaults for my theme like having spacing and text sizes defined? It still is a preprocessor, a bit more sophisticated than SASS or LESS, but still a preprocessor so I see no reason to theme colours to sit in config file. I know there are variables that could be leveraged to have colours in main.css, but then classes in html would look almost unreadable.

Overall

I think I'll be sticking to Tailwind for now, since it still feels like it's easier to work with than vanilla CSS. And definitely easier/better than Bootstrap, which comes with JavaScript. At least it did when I was using it. And for static blog site I don't need any JavaScript. I think Tailwind is in the middle between LESS/SASS and Bootstrap - it is exhaustive and has pretty good documentation, and also it produces pure CSS. I guess my disdain for JavaScript is showing here (but only because of what it has become).

When working with Tailwind if feels more like a library, not a framework. But if I were to include it's command line tooling I could see it being more of a framework, because it is not just simple collection of specific classes, but also minimiser, optimiser and other things that builds minimal CSS to use in production. And I guess that's what makes it a framework. And the one I see myself using in the future.

Tags: Pelican, Pelican themes, Tailwind CSS, Web Development