Tailwind

Explore the use of Tailwind CSS features in ZippyStarter, including fluid typography, container queries, and class concatenation.

Config

The majority of tailwind.config.js was generated by ShadCN, with some exceptions, feel free to extend it further.

Customisations

I introduced the following utilities to enhance responsive layouts.

const config: Config = {
  theme: {
    extend: {
      screens: {
        xs: "440px",
      },
      fontSize: {
        "fluid-2xl": "clamp(2rem, 10cqw, 5.625rem)",
        "fluid-xxl": "clamp(2rem, 10cqw, 4rem)",
        "fluid-xl": "clamp(1.5rem, 6cqw, 2.25rem)",
        "fluid-lg": "clamp(1.25rem, 4vw, 2rem)",
        "fluid-md": "clamp(1rem, 5cqw, 1.5rem)",
        "fluid-sm": "clamp(1rem, 4cqw, 1.25rem)",
        "fluid-xs": "clamp(0.9rem, 5cqw, 1.5rem)",
      },
      lineHeight: {
        fluid: "1.125",
      },
    },
  },
};

Any of the fontSize utilities can be used with Tailwind Container Queries, they apply fluid typography, meaning you only need a single class that responds to the size of it's container, rather than using traditional @media query breakpoints which can bloat your code.

Tailwind Container Queries

Anywhere you see a @container class used, declares that element as a container.

You container cannot query itself, only it's children can. This is why you always have an outer element with @container applied to it.

You can combine global CSS and tailwind container queries if you want, in the end it's all CSS, the following example demonstrates that, it has a parent @container and the next element has bodyContent applied

<div id="main" className="@container">
  <main className="bodyContent">...</main>
</div>

Concatenation of classes

the sheer number of Tailwind classes can become overwhelming, especially when you add variations. To aid management, I introduced theclsx() util, it's a widely used npm package.

With it, you can apply logic without the code looking like hieroglyphics.

<Link
  className={clsx(
    "dark:text-neutral-400/[0.8] py-1 inline-grid",
    "underline",
    "decoration-transparent",
    "hover:decoration-current",
    "transition",
    {
      "dark:text-primary": isActive
    },
  )}
>
  Click me
</Link>