Get Even More Visitors To Your Blog, Upgrade To A Business Listing >>

5 best practices for preventing chaos in Tailwind CSS

Nina TorgunakovaFrontend EngineerTravis TurnerTech EditorWorking with Tailwind CSS is pretty fast and easy (that’s why it’s received such wide recognition). You just paste a list of different classes in your HTML—and your interface immediately becomes attractive! But, as the application grows, the lists of classes grow. Then, one day you realize you can’t understand your code, you’re confused with the structure of the application and magic variables, and work becomes a struggle. This article is all about avoiding this scenario, sharing some best practices to ensure you stay aloft when using Tailwind CSS.We can prevent any headaches and resolve any problems (for the most part) by using Tailwind accurately and wisely. But, there are two requirements your project must met, and if it does not, Tailwind can make your job very difficult instead.First, you should have a design system in your project. Tailwind’s philosophy goes alongside the design system where designers and developers use consistent design tokens. Design tokens are atomic values (like colors, spacing, or typography scales) that define a design’s properties and that are reused throughout the project.Let’s imagine that we have a standard button and some tabs that need to be the same color as that button:If we decide to change the color scheme of the project a little, we’ll need to find every instance of this color (which looks like a magic variable) and update them everywhere. This can be inconsistent and harder to maintain.Design tokens help prevent these problems and ensure uniformity across UI elements.Luckily, to implement design tokens, we only need to to define the tokens in tailwind.config.js:After adding a new color with the name primary, we can use bg-primary for our background color or text-primary for the text color throughout the application:This way, when you want to change the color scheme in the project, you only need to replace the color in one place: tailwind.config.js.It’s better to avoid using Tailwind if you haven’t considered a design system because you’ll have to write magic values in the class lists (like 'p-[123px] mb-[11px] gap-[3px]') or add a lot of new tokens (15px, 16px, 17pxthe in spacing config), and this will eventually bring a lot of mess to your code.Having a consistent design system is good because it can help the development and design teams understand each other better.For instance, within Figma, you can have a single shared source of truth for any values in your design system. But to make this system truly maintainable, you’ll need to introduce some conventions regarding token grouping and naming—which we’ll get into later in this article.This is the second requirement your project needs to meet: you should already be using a component-based approach. The utility-first approach can lead to quite cluttered and verbose HTML structures since Tailwind classes apply directly to elements. This can mean the markup is harder to read and maintain, especially noticeable as your project grows.The solution: actively using a component-based approach that encapsulates frequently used patterns (in our case, HTML elements appearing more than once) as separate components.With this approach, we can keep things DRY). Moreover, we’ll still have a single source of truth for our Tailwind styles, and we can easily update it together in one place:If your development tool doesn’t allow you to split your code into components, it’s likely that the utility-first approach of Tailwind will only make development harder, and you should probably look to other CSS frameworks-for example, CSS Modules.And one last thing regarding a component-based approach: avoid using the @apply directive:Yes, using this directive, your code may look cleaner, but it throws away the key advantages of Tailwind: less mental overload when coming up with names for CSS classes, and the absence of regressions when changing styles (since with @apply they won’t be isolated within the component). Further, using it increases CSS bundle size.The creators of Tailwind have also highlighted the importance of using the @apply directive with caution in the documentation.If you met both requirements, Tailwind CSS is likely a good framework option for you! Here are the most helpful practices for improving your long-term experience with it.When you build a list of utility classes for an HTML element, each new class adds additional complexity for the developers, and they’ll have to analyze and work with the code later (and this includes you, too). Of course, these lists are an essential and inherent feature of Tailwind, but nevertheless, it’s better to write as little utility classes as possible.Here are a few ways you can decrease the number of classes and get exactly the same results:With a shorter list of classes, the next time you inspect the structure of your application, it’ll be much easier to analyze what’s going on.When working on a team, you probably agree that some clean coding practices (like the clear naming of variables) are really important for long-term development. That said, even if you’re working alone, it also can be worth setting some rules for code clarity, otherwise, you could get confused about your own project (for example, when returning after a break).This approach is especially important while working with Tailwind because reckless usage of such a large number of classes and design tokens can really bring confusion into your code.As discussed above, using design tokens is a great practice, but just pasting them haphazardly can lead to chaos in your tailwind.config.js file.To remedy this, group related tokens together in tailwind.config.js. This means that design tokens for breakpoints, colors, and so on, will be in specific areas and won’t mess with each other:Here’s another important thing: keeping a single semantic naming convention for your tokens will make it easier to find the necessary tokens and expand the system as the application grows.For example, to add a color for your error state, don’t just copy and paste the bright-red token from your Figma file into your Tailwind configuration: put it into the colors section and give a more concise name like error. This will make the system much more consistent.Here’s another clean coding convention: using a consistent order makes classes easier to read and understand. To illustrate, let’s take a look at some HTML elements with unsorted classes:In the blocks above, there are classes for different categories: dealing with the box model, display, typography, and so on—but they don’t have any sort of presentational order. We can apply a unified order to sort classes by categories:Since maintaining class ordering manually requires a lot of time and attention, it’s much better to automate this work using the official Prettier plugin for Tailwind CSS. To learn more about how to get started with it and the methodology of how the classes are sorted, we recommend reading this article.It’s important to keep bundle size as small as possible—heavy builds mean slow-loading pages, bad performance, and frustrated users.Tailwind provides us with thousands of utility classes, and it’s unlikely we’ll use all of them within a single project. So, how can we make sure that any unused styles won’t end up in our production build?If you use Tailwind version 3.0 or above, the Just-in-Time (JIT) engine is enabled in your project by default—it ensures that CSS styles are generated as they are needed, and we won’t need to purge unused styles for production builds.But if you’re using an older version of Tailwind, you need to perform additional optimizations for your build—this can be done using PurgeCSS, a tool for removing unused CSS. This article explains how to do this in version 2.1 and older. You can also enable the JIT mode manually in your tailwind.config.js file, like so:This will make sure that we’re only including the necessary styles in our bundle.There is another important thing to consider: always minify the final CSS for the production build. Minification removes all unnecessary characters (like whitespace, comments, and so on) and this will noticeably reduce file size.Using the Tailwind CLI, this can be done by setting --minify flag:npx tailwindcss -o build.css --minifyOr, if you’ve installed Tailwind as a PostCSS plugin, you can use the cssnano tool for minification by adding it to your plugin list.If we don’t consider optimization, the size of our CSS can end up really big (more than several tens of kilobytes). Even in a small project with a few components with styles, there can be a 30%+ size difference after minifying CSS and enabling JIT mode. To achieve this, you just need to input the two new lines described above.If we don’t consider optimization, the size of our CSS can end up really big (more than several tens of kilobytes). Even in a small project with a few components with styles, there is a 30%+ size difference after minifying CSS and enabling JIT mode. To achieve this, you just need to add the minify flag and enable jit mode, as described above.If you want to learn more information about minification and compression for Tailwind, check this section of documentation.Tip: If you have design tokens in your project, make sure that they’re all actually being used. Unused design tokens confuse developers, make the configuration more complicated, and introduce unneeded messiness into your design system.Imagine that we use a component with a custom button on our page:And we have a Button component that has some default style:In this case, the button will remain white–Tailwind doesn’t automatically override style and apply the black color, so we need to specify it in the Button component:There’s nothing inherently wrong about this aspect of Tailwind, but if we want to customize some appearance by overriding or extending a lot of styles, it can be cumbersome to pass classes via props each time.Moreover, there is one more drawback to this approach: accepting utilities via props can make it harder to ensure a consistent component view. This approach encourages using any utility combination for the same component across the app which can lead to a lack of visual consistency.So, what can we do with it?Instead of allowing any arbitrary utility classes to be passed via props, define a set of predefined variants:Then, change the Button component so it can accept a variant prop. To make constructing className more convenient, you can use clsx:Tip: using clsx would be also especially handy if you need to construct classes conditionally.After constructing className for the component, just use it, passing the desired variant:Now, consistency is ensured, and despite the fact that we added a restriction on full customization, flexibility remains; we can add any new variant for the component or edit an existing one.And the other benefit of this approach is that it allows for simpler maintenance: changes to utility classes can be made in one place, and then propagated to every component of that variant in the app.If for some reason you don’t want to use the sets of predefined variants, you can try the package tailwind-merge, which provides utility function twMerge to merge Tailwind classes in JS without style conflicts–but it should be used carefully and only when necessary, since it is not the most lightweight and increases bundle size.Tailwind is a powerful tool, but it’s important to use it while following some rules to prevent chaos from erupting in your project. Let’s sum up the principles that we listed above.First of all, to get the most out of these practice, you should use Tailwind when you already have a design system and consistent design tokens and have opted for a component-based approach. Without breaking reusable elements into components, using Tailwind will become painful sooner or later, leading to repetitive or verbose HTML structures.By following these rules, you’ll be able to use Tailwind for the long haul–with pleasure and without problems–giving your team the chance to revel in all the benefits it provides.At Evil Martians, we transform growth-stage startups into unicorns, build developer tools, and create open source products. If you’re ready to engage warp drive, give us a shout!Get all the new posts delivered directly to your inbox. Unsubscribe anytime.We’d love to hear from you! We’re not really all that evil, and we love discussing potential projects, intriguing ideas, and new opportunities. Complete the form below or drop us a line at [email protected]. Alternatively, schedule a Calendly appointment with us right now!We transform growth-stage startups into unicorns, build developer tools, and create open source products.United States+1 888 400 548577 Sands St.Brooklyn, New York11201Portugal+351 308 808 570Rua Alexandre Oneill, 38,Porto4400-008Japan+81 6 6225 12429F Edobori Center Building, 2-1-1 Edobori, Nishi‑ku,Osaka550-0002Get all the new posts delivered directly to your inbox. Unsubscribe anytime.Designed and developed by Evil Martians



This post first appeared on VedVyas Articles, please read the originial post: here

Share the post

5 best practices for preventing chaos in Tailwind CSS

×

Subscribe to Vedvyas Articles

Get updates delivered right to your inbox!

Thank you for your subscription

×