DEV Community

Cover image for Are you still using the ternary operator to dynamically apply Tailwind styles?
Yeom suyun
Yeom suyun

Posted on • Edited on

Are you still using the ternary operator to dynamically apply Tailwind styles?

Tailwind CSS is a CSS framework that has gained incredible popularity, with usage skyrocketing 40% in three years, according to the State of CSS 2022.
It offers benefits such as development speed, maintainability, and gzip optimization. As a result, it is expected to exceed 50% in the 2023 survey.
However, the readability of Tailwind CSS decreases sharply as the style becomes more complex, which is a typical disadvantage of the utility-first approach.
Personally, I recommend my library, CSS Lube, but in this article, I would like to introduce some simple tips that can improve the developer experience when using the Atomic CSS approach.

1. Actively use line breaks

Human eyes can simultaneously recognize multiple lines of text.
Appropriate line breaks are a good way to improve the readability of code by allowing us to take advantage of peripheral vision.
There is a saying that bite off more than one can chew, but personally, I think it is better to have more than not enough line breaks in code.
Additionally, using an extra tab when breaking lines of tag properties improves the readability of tags that have become bloated due to the utility-first approach.

// jsx
<button onClick={handle_click}
    class={`flex column ai=center
    :hover/bold
    :hover/c=--gray-10 @dark@:hover/c=--gray-80`}>
  Click me!
</button>

// svelte
<button on:click={handle_click}
    class="flex column ai=center
    :hover/bold
    :hover/c=--gray-10 @dark@:hover/c=--gray-80">
  Click me!
</button>
Enter fullscreen mode Exit fullscreen mode

2. Use && or || instead of the ternary operator

If you want on/off style instead of a choice based on the state value, it is recommended to use && or || instead of the ternary operator.
clsx library can exclude invalid values from the classList, but if you allow invalid values true and false in classList, you can write the style more conveniently without any other tools.

// jsx + clsx
<button onClick={handle_click}
    class={clsx("flex column ai=center",
    is_active && "tf=scale(1.2)",
    is_disable || "c=--primary")}>
  Click me!
</button>

// svelte
<button on:click={handle_click}
    class="flex column ai=center
    {is_active && "tf=scale(1.2)"}
    {is_disable || "c=--primary"}">
  Click me!
</button>

// result
<button on:click={handle_click}
    class="flex column ai=center false true">
  Click me!
</button>
Enter fullscreen mode Exit fullscreen mode

3. Applying semantic styles using a separate JS file

When writing utility-first, it is recommended to declare complex styling in a separate JavaScript file.
This method allows you to work quickly and easily in the utility-first style, and to take advantage of the semantic style when the overall effect of the styles is more important than the individual styles.
Using JavaScript also has the advantage of receiving powerful IDE support, unlike CSS.

// style.js
export default {
  main: {
    scrollbar: {
      primary: `::-webkit-scrollbar/w=.5
      ::-webkit-scrollbar-track/bg=--primary-70
      ::-webkit-scrollbar-thumb/bg=--primary-50;br=.25`
    },
  }
}
Enter fullscreen mode Exit fullscreen mode

Image description

Conclusion

Most front-end developers will agree that inline styles are convenient.
However, I sometimes experience an uncomfortable reverse sensation when writing inline styles, compared to using utility-first (specifically CSS Lube).
Utility-first makes our fingers lazy and allows us to use the extra energy on our brains.
In addition, the tips introduced in this article, if you can mitigate the disadvantages of utility-first, you can significantly improve your developer experience.
Thank you.

Top comments (0)