DEV Community

Cover image for Styling Best Practices I Use With Tailwindcss
Theodorus Clarence
Theodorus Clarence

Posted on • Edited on • Originally published at theodorusclarence.com

Styling Best Practices I Use With Tailwindcss

This blog is not about learning Tailwindcss 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, 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, 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, but I prefer my own.

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

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>
Enter fullscreen mode Exit fullscreen mode

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 Demonstration

2. Add base style

Tailwindcss 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
Enter fullscreen mode Exit fullscreen mode

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 by Heydon Pickering. This usually helps a lot even in Vanilla CSS. In Tailwindcss 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;
}
Enter fullscreen mode Exit fullscreen mode

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

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:

<!-- 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>
Enter fullscreen mode Exit fullscreen mode

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>
  );
}
Enter fullscreen mode Exit fullscreen mode

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>
  );
}
Enter fullscreen mode Exit fullscreen mode

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

Originally posted on my personal site, find more blog posts and code snippets library I put up for easy access on my site 🚀

Top comments (0)