# Tailwind CSS# Tips & Tricks

Tailwind CSS Tips Every Developer Should Know

, 7m read

Looking for ways to improve your development with Tailwind CSS? Explore tips and tricks from workflow optimizations to common design patterns.

GitHub profile image of Nikolai Lehbrink

By Nikolai Lehbrink

Web enthusiast, specialising in the React ecosystem.

Post image for Tailwind CSS tips
Last updated on .

Over the past two years, I've used Tailwind CSS in every web project I've undertaken. Along the way, I've picked up a few handy tips and tricks that I'd like to share.

My intention in writing this article

My goal is to offer a cheat sheet that addresses the challenges I face and to continually update this article whenever I find something new.

Please do not hesitate to get in touch with me if you have a tip that you think I should include.

Common Practices

Some scenarios that many people have probably encountered.

Customise containers with standard padding and autocentering

Often times in web design, we do not wan't to scale or fit content to the outermost width of the viewport but rather have content inside a container which helps usability and helps the user to focus on the important part of the site. The container class in Tailwind CSS can be used to achieve just that, applying a max-width to the specific element.

A common case is that the container needs to be centred in the middle of the page and has a padding on the sides so that the content within the container is not at the very outer edge of the viewport.

Info

This is particularly common on mobile devices.

<div class="container mx-auto px-4 sm:px-8 lg:px-16">
  <!--  -->
</div>

The code above achieves that functionality, but always having to centre the container yourself with the mx-auto class and specify your own padding can lead to inconsistencies and is a rather tedious task. That's why there is the possibility to adjust the container class in the config.

tailwind.config.ts
/** @type {import('tailwindcss').Config} */
export default {
  theme: {
    container: {
      center: true,
      padding: {
        DEFAULT: '1rem',
        sm: '2rem',
        lg: '4rem',
      },
    },
  },
}

You can enable automatic centring of the container, as well as a default padding value and breakpoint-specific padding values that can be adjusted as required.

Now, simply use the container class and have the same result, without any further code.

<div class="container">
  <!--  -->
</div>

Targeting a single breakpoint

Sometimes you wan't to style an element only for a specific breakpoint. I ended up writing classes, that targeted multiple breakpoints, only to style one in particular. However with the release of Tailwind v.3.2 and the implementation of dynamic breakpoints it is much easier to target a single breakpoint now.

<div class="bg-red-500 sm:bg-green-500 md:bg-red-500">
<div class="bg-red-500 sm:max-md:bg-green-500">
    <!--  -->
</div>

You can stack responsive modifiers and achieve the same result with only one class selector.

Tip

The same logic applies to breakpoint ranges.

<div class="bg-red-500 sm:max-xl:bg-green-500">
    <!--  -->
</div>

Targeting Elements Not Included in Your Initial Markup

Almost inevitable, you will encounter scenarios where some elements are not directly accessible in your static HTML markup because they are added during the build process or dynamically through JavaScript.

Info

This often occurs with content generated by third-party tools or libraries, which can make applying consistent styling a challenge.

For example, I use a syntax highlighter called Shiki, which generates the blocks of code you see on this page on the server. They are wrapped in <pre> and <code> tags and these elements still require styling to ensure they align with the overall design of the site.

Here are two possible ways of dealing with this situation.

Use the @apply directive

You can use @apply to inline any existing utility classes into your own custom CSS.

style.css
.shiki {
  pre {
    @apply scrollbar-thin overflow-x-auto bg-neutral-900 py-3 pl-4 pr-5 leading-snug;
    code {
      @apply block w-fit min-w-full;
    }
  }
}

Use arbitrary variants

With the implementation of arbitrary variants in Tailwind CSS v.3.1 it is possible to create custom variants directly in your HTML.

<div class="border-t-2 border-border text-sm [&>pre]:overflow-x-auto [&>pre]:!bg-neutral-900 [&>pre]:py-3 [&>pre]:pl-4 [&>pre]:pr-5 [&>pre]:leading-snug [&>pre]:scrollbar-thin [&_code]:block [&_code]:w-fit [&_code]:min-w-full">
  <code>
    <pre></pre>
  </code>
</div>
Which selectors do the classes address?

In this example, the selector [&_code] targets all <code> child elements and [&>pre] specifically targets <pre> elements that are direct children of the surrounding <div>.

Referencing theme values in JavaScript

In scenarios where you're using a design system or a predefined set of styles, like those provided by Tailwind, you might find yourself needing to access these theme values directly in your JavaScript code. You can do that by referencing the resolved config in your code.

tailwind.config.ts
import type { Config } from "tailwindcss";
import resolveConfig from "tailwindcss/resolveConfig";

const config = {
    // ...
} satisfies Config;

export default config;

export const tailwindConfig = resolveConfig(config);

In this example I am using the resolved config for generating the color for the viewport object in Next.js.

app/layout.tsx
import { tailwindConfig } from "@/tailwind.config";
import type { Viewport } from "next";

// Next.js specific viewport object
export const viewport: Viewport = {
  themeColor: tailwindConfig.theme.colors.sky["500"],
};

Setting width and height in one go

Often, when browsing through tutorials on YouTube or other websites, you'll notice that many developers apply width and height classes separately to achieve square dimensions for elements like icons or avatars. That is because previously, this was the standard approach in Tailwind.

With the introduction of the size utility in Tailwind v3.4, setting both dimensions simultaneously has become much more straightforward.

<div class="h-12 w-12 bg-red-500">
<div class="size-12 bg-red-500">
  <!-- ... -->
</div>

Optimize Development

Tips that should make your development with Tailwind easier.

Automatic wrapping of long class names

In Tailwind it is almost impossible to avoid writing long class names for certain elements. This should not be a problem, but the class names remain on one line and are not, for example, formatted and limited in length by Prettier and split over several lines. This means that developers often have to scroll horizontally for some time to find the right class.

Info

The problem is so significant that it is rated as the top idea for Tailwind CSS on GitHub.

But now there is a solution.

Automatic wrapping of verbose class names with Prettier

ony3000 has created prettier-plugin-classnames, which wraps long class names based on Prettier's printWidth option. With a slightly extended configuration, it can be used in conjunction with prettier-plugin-tailwindcss to also automatically sort the classes.

Tip

For more information on how to get the plugin up and running, I suggest you read the installation instructions. Basically it's just a matter of installing the plugin, adding it to your prettier.config.js and restarting your code editor.

I am using the plugin on this site with the following prettier.config.js.

prettier.config.js
/** @type {import("prettier").Config} */
const functions = ["cn", "clsx", "cva"];
module.exports = {
  // Used to sort classes in strings provided to function calls (clsx, twMerge or cva)
  tailwindFunctions: functions,
  // Used to wrap classes in strings provided to function calls (clsx, twMerge or cva)
  customFunctions: functions,
  // https://github.com/ony3000/prettier-plugin-classnames?tab=readme-ov-file#ending-position
  endingPosition: "absolute-with-indent",
  plugins: [
    "prettier-plugin-classnames",
    "prettier-plugin-tailwindcss",
    // Needed to make both plugins work together
    "prettier-plugin-merge",
  ],
};

Adjusting Font Size in VS Code Intellisense Extension

One of the reasons Tailwind CSS has become such a time-saving tool for me is undoubtedly the great Intellisense extension for VS Code. It gives you autosuggestions for classes, but also pixel values according to your root font size, which can be very helpful.

A common problem I ran into was that if I deviated from the default font size of 16px in my project, the pixel values displayed by the extension would not update accordingly and would always stick to the default font size of 16px.

However, after a bit of research, I found that there is an option to change the font size used by the extension to your liking using the rootFontSize setting.

.vscode/settings.json
{
  "tailwindCSS.rootFontSize": 17
}

You should now see the correct pixel values when you hover over the classes after changing the setting.

Tailwind CSS Intellisense extension for VS Code

Automatic class sorting

Maintaining a clean and organised codebase is essential for any development project. One useful feature that improves code clarity, especially when working with Tailwind, is automatic class sorting.

Integration with Prettier

The Prettier plugin for Tailwind automatically organises Tailwind classes in your files according to a predefined order, which not only improves readability, but also helps to maintain a consistent style across your project. To learn more about how the classes are ordered and how to install the plugin, I suggest you read the corresponding blog post.

VS Code Extension Headwind

There is also a VS Code extension called Headwind which does basically the same thing but has a different ordering system. I used it for a while before I found out about the Prettier plugin.

Warning

I can't recommend using it as it's no longer maintained and there seem to be some issues that won't get fixed.

Tip

There is a more actively maintained fork of Headwind called „Tailwind Raw Reorder“, which is also available on the Visual Studio Marketplace.

Design patterns

Because I find myself implementing the same design patterns in many of my projects, here are some of them.

Break elements out of typography plugin

To ensure high quality typography standards for a project, I often rely on Tailwind's typography plugin, which provides some useful classes to get you up and running in no time.

Recently I was creating a website for a job application and to make things a bit more interesting I wanted to break out some of the elements out of the typography container. At first I thought this could be achieved by using the not-prose class as mentioned in the plugins README for undoing styles. However, this does not work for breaking elements out of the prose container that sets a max-width, which makes sense.

A workaround for this is to set a negative margin on the horizontal axis and break out elements that way.

<div class="prose">
  <!-- ... -->
  <div class="... not-prose lg:-mx-32 2xl:-mx-80">
    <!-- ... -->
  </div>
</div>

The result is a section that is outside the max-width defined by the plugin.

Post image

Create gradient headings

Many professional websites today use gradient headlines to grab the attention of visitors and give their pages a dynamic, modern look.

Here is an example from the Supabase website.

Homepage of Supabase, where a gradient heading is used

Here is how you can implement that in one line with Tailwind.

<h1 class="inline-block bg-gradient-to-br from-neutral-500 to-neutral-100 bg-clip-text text-5xl text-transparent">
  This is a demo text
</h1>

That's all for now! Thanks for reading and I would really appreciate your feedback or hear about tips that you find worth sharing!