Tailwind CSS

Utility Classes

Tailwind is the default choice in create-next-app. You style with small classes directly in JSX. Tailwind v4 needs only one line in globals.css:

@import "tailwindcss";
export default function ProductCard({ name, price, mrp }: { name: string; price: number; mrp: number }) {
  return (
    <div className="rounded-xl border p-4 shadow-sm hover:shadow-md transition">
      <h3 className="font-semibold text-gray-900 line-clamp-2">{name}</h3>
      <p className="mt-2">
        <span className="text-lg font-bold">₹{price}</span>
        <span className="ml-2 text-sm text-gray-500 line-through">₹{mrp}</span>
      </p>
      <button className="mt-3 w-full rounded-lg bg-blue-600 py-2 text-white hover:bg-blue-700 md:w-auto md:px-6">
        Add to Cart
      </button>
    </div>
  );
}

Conditional Classes

Projects usually have a tiny cn() helper (often built with the clsx package) to join classes conditionally:

Example

type ClassValue = string | false | null | undefined | Record<string, boolean>;

function cn(...values: ClassValue[]): string {
  const out: string[] = [];
  for (const v of values) {
    if (!v) continue;
    if (typeof v === 'string') out.push(v);
    else for (const [cls, on] of Object.entries(v)) if (on) out.push(cls);
  }
  return out.join(' ');
}

const inStock = false;
const selected = true;
console.log(cn('rounded border p-4', selected && 'ring-2 ring-blue-500', { 'opacity-50': !inStock }));
console.log(cn('btn', null, undefined, { 'btn-primary': true, 'btn-disabled': false }));

Output

rounded border p-4 ring-2 ring-blue-500 opacity-50
btn btn-primary