Styling Best Practices I Use With Tailwind CSS

Written on May 15, 2021 by

photo of me

Theodorus Clarence.

––– views • 7 min read

Read in Bahasa Indonesia

Introduction

This blog is not about learning Tailwind CSS from the ground up. Tailwind Labs has a complete playlist in their youtube channel. I recommend checking that out, I learned a lot from it.

For me, Tailwind CSS is like another form of writing CSS, and will not replace the knowledge about basic CSS and responsive design.

Why Tailwind CSS?

Tailwind CSS is a utility-first framework that is currently my go-to framework for styling on my website. It provides reusable styling and components that I can even use between multiple websites. Checkout my library, I have some of my components put there so I can easily find them when I need them on another website I'm building.

Tailwind CSS is provided with a lot of CSS best practices that I also follow when writing Vanilla CSS or SCSS. It mostly suppresses all of the quirky things that most developers found in writing Vanilla CSS like box-sizing, annoying button defaults, collapsing margins, etc. Which makes many developers think that Tailwind CSS is a way to avoid writing CSS and understanding all of the quirky things in a CSS.

But I love writing CSS. I'm quite comfortable in writing CSS and understand how it works. For me, learning Vanilla CSS is really crucial and you should not replace CSS with Tailwind CSS before you understand css.

Don't get too comfortable with frameworks that you can't make a website without Tailwind CSS or other frameworks like Bootstrap.

Well, enough talking, let's get to the best practices I use in writing CSS and Tailwind CSS. Both applies because like I said, Tailwind CSS is just another form of writing CSS.

1. Using Layout Class (or container)

You probably won't notice sites without constraining width if you are not using a big monitor. Sometimes people forget to add this constraint when developing and causing styling issues for someone that have a larger viewport

You can use container class from Tailwind CSS, but I prefer my own.

.layout {
max-width: 68.75rem; // 1100px
width: 90%;
margin-left: auto;
margin-right: auto;
}
css

The 90% width will provide a great amount of padding for mobile view and will get constrained at 1100px when we get to a bigger viewport. You can use any value for the max-width, but I found 1100px suits a lot of cases.

To use this class, I usually combine it with section tag like this:

<!-- Put all of background colors in the section tag -->
<section>
<!-- This `div.layout` is for all of your layout usage, put flex, text-colors, min-height, container's font-size here. -->
<div class="layout">
<h1>Content</h1>
</div>
</section>
html

We can put all of the background colors or background image on the section tag, to avoid it getting cut off by the constraint.

Here is a demo of the layout class, you can also check the codepen

Layout Class

2. Add base style

Tailwind CSS has a feature called Preflight, which is a set of base styles for Tailwind projects that are designed to smooth over cross-browser inconsistencies and make it easier for you to work within the constraints of your design system.

Basically, it does something to the default stylesheet agent like removing margin, padding, even font size. Also adding some base style to buttons, links, list, etc. Find more at the Preflight Docs.

It is a good thing because we didn't need to do all of the chore like removing blue color and underline from links, resetting font-family, background, border out of buttons, and many more. But, we miss a lot of things like font-size and font-weight for each heading.

I have a preconfigured base style that I usually add in my projects, it is already added to my starter which I use in every project.

@layer base {
h1 {
@apply text-3xl font-bold md:text-5xl font-primary;
}
h2 {
@apply text-2xl font-bold md:text-4xl font-primary;
}
h3 {
@apply text-xl font-bold md:text-3xl font-primary;
}
h4 {
@apply text-lg font-bold font-primary;
}
body {
@apply text-sm font-primary md:text-base;
}
}
// Whoops, I think the syntax highlight broke because it didn't recognize @layer and @apply
css

This will add responsive font-size, and apply the font you are using. Don't forget to configure the font-primary in tailwind config, or just use font-sans.

3. Whitespace

Still, because of preflight, default margins are removed from the base style. So we need to add the margin ourselves. I usually found mb-2 and mb-4 really great when adding some whitespace.

Also, don't forget that Tailwind CSS has a built-in CSS pattern which is Lobotomized Owl by Heydon Pickering. This usually helps a lot even in Vanilla CSS. In Tailwind CSS it is called Space Between. It works by adding margin-top to all of the child elements except the first one.

Here is the original one by Heydon:

.flow-content > * + * {
margin-top: 1.5em;
}
css

It uses relative units so it will be relative to the element's font size. Learn more about this in my blog about rem, em, and px units

Tailwind CSS Space Between basically does the same, but with rem. So we can only use it if we are sure that the elements inside all have the same spacing. For example:

<!-- Using normal margin class -->
<div>
<p class="mb-2">Paragraph</p>
<p class="mb-2">Paragraph</p>
<p class="mb-2">Paragraph</p>
<p class="mb-2">Paragraph</p>
</div>
<!-- Using Space Between -->
<div class="space-y-2">
<p>Paragraph</p>
<p>Paragraph</p>
<p>Paragraph</p>
<p>Paragraph</p>
</div>
html

4. Use component and map function

I'm using React, so I can easily achieve a DRY code by mapping the value and using components to reuse. A common example is a Button component

export default function CustomLink(props) {
return (
<UnstyledLink
{...props}
className={`${props.className} inline-flex items-center font-bold hover:text-primary-400`}
>
{props.children}
</UnstyledLink>
);
}
jsx

By using component, we won't repeat the same class over and over again

For the mapping, I usually put my data in a JS file or declare an array, then map it out.

const links = [
{ href: '/', label: 'Home' },
{ href: '/projects', label: 'Projects' },
{ href: '/blog', label: 'Blog' },
{ href: '/library', label: 'Library' },
{ href: '/about', label: 'About' },
];
export default function Nav() {
return (
<nav className='bg-gray-700'>
<ul className='flex items-center justify-between px-8 py-4'>
<li>
<Link href='/'>
<a className='font-bold text-green-400'>Home</a>
</Link>
</li>
<ul className='flex items-center justify-between space-x-4'>
{links.map(({ href, label }) => (
<li key={`${href}${label}`}>
<Link href={href}>
<a className='text-white hover:text-green-400'>{label}</a>
</Link>
</li>
))}
</ul>
</ul>
</nav>
);
}
jsx

Notice the use of space between to reduce class too. The code example is taken from this website and available on github. Kindly star it if it helps!

Install Tailwind CSS Injector Addons

When tailwindcss is shipped to production, the classes that is shipped is only the class that we use in the site (tree shaken). Sometimes it is needed to add some class for debugging issues, or if we just want to play around with website that don't use tailwindcss.

So, I created an addons that will inject the tailwindcss CDN on the website.

Install Tailwind CSS Injector

Enjoying my post? Kindly subscribe to my newsletter if you want an update everytime I post.