Styling Best Practices I Use With Tailwindcss
Tags: tailwindcss
Published: 2021-05-16 09:47:21


This blog is not about learning Tailwindcss from the ground up. Tailwind Labs has a complete [playlist in their youtube channel](https://www.youtube.com/watch?v=elgqxmdVms8&list=PL5f_mz_zU5eXWYDXHUDOLBE0scnuJofO0&ab_channel=TailwindLabs). I recommend checking that out, I learned a lot from it.

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

## Why Tailwindcss?

Tailwindcss 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](https://theodorusclarence.com/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.

Tailwindcss 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 Tailwindcss 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 Tailwindcss before you understand css.

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

Well, enough talking, let's get to the best practices I use in writing CSS and Tailwindcss. Both applies because like I said, Tailwindcss 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 Tailwindcss](https://tailwindcss.com/docs/container), but I prefer my own.

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

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:

```html
<!-- 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>
```

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](https://codepen.io/theodorus/pen/JjWKobM)

![Layout Demonstration](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/uon1rx6om34qdujgmm5d.gif)

## 2. Add base style

Tailwindcss has a feature called [Preflight](https://tailwindcss.com/docs/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](https://tailwindcss.com/docs/preflight).

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](https://clarence.link/starters) which I use in every project.

```css
@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
```

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 Tailwindcss has a built-in CSS pattern which is [Lobotomized Owl](https://alistapart.com/article/axiomatic-css-and-lobotomized-owls/) by Heydon Pickering. This usually helps a lot even in Vanilla CSS. In Tailwindcss it is called [Space Between](https://tailwindcss.com/docs/space). It works by adding margin-top to all of the child elements except the first one.

Here is the original one by Heydon:

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

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](https://theodorusclarence.com/blog/btb-rem-em)

Tailwindcss 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:

```html
<!-- 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>
```

## 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

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

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.

```jsx
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>
  );
}
```

Notice the use of space between to reduce class too. The code example is taken from this website and [available on github](https://github.com/theodorusclarence/theodorusclarence.com). Kindly star it if it helps!

## Install Tailwindcss 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 Tailwindcss Injector](https://clarence.link/tw-inject)

> Originally posted on [my personal site](https://theodorusclarence.com), find more [blog posts](https://theodorusclarence.com/blog) and [code snippets library](https://theodorusclarence.com/library) I put up for easy access on my site 🚀