Tailwind CSS Tips Every Developer Should Know

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


Over the past two years, I've used Tailwind CSS in almost 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 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. This is especially common for 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.
export default {
theme: {
container: {
center: true,
padding: {
DEFAULT: "1rem",
sm: "2rem",
lg: "4rem",
},
},
},
} satisfies Config;
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 mx-auto px-4 sm:px-8 lg:px-16">
<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.
<div class="bg-red-500 sm:bg-green-500 md:bg-red-500">
<!-- ... -->
</div>
However with the release of Tailwind CSS v3.2 and the implementation of dynamic breakpoints it is much easier to target a single breakpoint now.
You can stack responsive modifiers and achieve the same result with only one class selector.
<div class="bg-red-500 sm:bg-green-500 md:bg-red-500">
<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.
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. 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.
.shiki {
pre {
@apply scrollbar-thin overflow-x-auto bg-neutral-900;
code {
@apply block w-fit min-w-full;
}
}
}
#Use arbitrary variants
With the implementation of arbitrary variants in Tailwind CSS v3.1 it is possible to create custom variants directly in your HTML.
<div class="... [&>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">
<!-- Auto generated code -->
<!-- <pre>
<code>
...
</code>
</pre> -->
</div>
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 CSS, 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.
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.
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 CSS.
With the introduction of the size-*
utilities in Tailwind CSS 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 CSS easier.
#Automatic wrapping of long class names
In Tailwind CSS 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.
The problem is so significant that it is rated as the top idea for Tailwind CSS on GitHub.
But now there is a solution.
User Hyeonjong 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.
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
.
/** @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.
{
"tailwindCSS.rootFontSize": 17
}
You should now see the correct pixel values when you hover over the classes after changing the setting.
#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 CSS, is automatic class sorting.
#Integration with Prettier
The prettier-plugin-tailwindcss automatically organises Tailwind CSS 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.
I can't recommend using it as it's no longer maintained and there seem to be some issues that won't get fixed. However 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 CSS'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 typography 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 md:-mx-16 lg:-mx-32 2xl:-mx-48">
<!-- ... -->
</div>
</div>
The result is a section that extends beyond the plugin’s defined max-width
.
This is a breakout section
On screens wider than 768px, this section appears broader than the other content. Use it to draw attention to key information or introduce a visual break in your layout.
#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 how you can implement that in one line with Tailwind CSS.
<h1 class="inline-block bg-gradient-to-b from-neutral-500 to-neutral-300 bg-clip-text text-3xl 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!