All skills
sergiodxa avatar

/frontend-tailwind-best-practices

@fa6e3fc

Tailwind CSS patterns and conventions for frontend apps. Use when writing component styles, layouts, or working with CSS classes.

Use this Skill: https://skilld.dev/gh/sergiodxa/agent-skills/frontend-tailwind-best-practices

This session only. Nothing lands on disk.

rulesclassname-cn-utility.md

≈863 tokens on demand. Your agent reads this file only when SKILL.md points to it.

Use cn() for className Merging

Always use the cn() utility to merge classNames in components.

Why

  • Properly merges Tailwind classes (handles conflicts)
  • Supports conditional classes with objects
  • Accepts arrays, strings, undefined
  • External className always wins (applied last)

Import

import { cn } from "~/lib/cn";

Definition

import type { ClassValue } from "clsx";
import type { CSSProperties } from "react";

import { clsx } from "clsx";
import { twMerge } from "tailwind-merge";

export type ClassName = ClassValue;
export type ClassNameRecord<Key extends string> = { [K in Key]?: ClassName };

type Style = CSSProperties & { [key: `--${string}`]: string };
export type StyleRecord<Key extends string> = { [K in Key]?: Style };

export function cn(...classes: ClassName[]): string {
  return twMerge(clsx(...classes));
}

Pattern

function Button({ className, variant, size, disabled }: Props) {
  return (
    <button
      className={cn(
        // Base classes always applied
        "inline-flex items-center justify-center rounded-lg font-medium",
        // Variant classes (conditional object)
        {
          "bg-teal-500 text-white": variant === "primary",
          "bg-neutral-100 text-neutral-900": variant === "secondary",
          "bg-transparent text-teal-600": variant === "ghost",
        },
        // Size classes
        {
          "px-3 py-1.5 text-sm": size === "sm",
          "px-4 py-2 text-base": size === "md",
          "px-6 py-3 text-lg": size === "lg",
        },
        // State classes
        disabled && "opacity-50 cursor-not-allowed",
        // External className ALWAYS LAST
        className,
      )}
    />
  );
}

Conditional Classes

Object Syntax (Preferred)

className={cn(
  "base",
  {
    "active-class": isActive,
    "disabled-class": isDisabled,
    "error-class": hasError,
  }
)}

Logical AND

className={cn(
  "base",
  isActive && "active-class",
  isDisabled && "disabled-class"
)}

Ternary

className={cn(
  "base",
  isActive ? "bg-teal-500" : "bg-neutral-100"
)}

External className Last

Always put the className prop last so consumers can override:

// Component
function Card({ className }: { className?: ClassName }) {
  return (
    <div
      className={cn(
        "rounded-xl bg-white p-4",
        className, // Can override padding, background, etc.
      )}
    />
  );
}

// Usage - override works
<Card className="p-8 bg-neutral-50" />;

Arrays

const baseClasses = ["rounded-lg", "font-medium"];
const sizeClasses = size === "lg" ? ["px-6", "py-3"] : ["px-4", "py-2"];

className={cn(baseClasses, sizeClasses, className)}

Handling Undefined

cn() safely ignores undefined/null/false values:

className={cn(
  "base",
  maybeUndefined,             // Ignored if undefined
  condition && "conditional", // Ignored if false
  className                   // Ignored if not passed
)}

Anti-Patterns

// Bad - string concatenation
className={`base ${isActive ? "active" : ""} ${className}`}

// Bad - template literal without cn
className={`base ${className || ""}`}

// Bad - className not last
className={cn(className, "base-classes")}

// Bad - not using cn at all
className="static-classes-only"

Source: SKILL.md on GitHub

No alerts16d5 checks · Risk SAFE
  • Gen Agent Trust Hub16d

    The skill is a collection of architectural guidelines and best practices for Tailwind CSS. It provides documentation on layout utilities, color schemes, and component styling patterns without any executable code or suspicious behaviors.

  • Socket16d

    No alerts

  • Snyk16d

    Risk: LOW · No issues

  • Runlayer7mo

    11 files scanned · No issues

  • ZeroLeaks5mo

    1 finding · Score: 86/100

Signed by skilld at fa6e3fc. This ties the file your Agent reads to that commit on GitHub. It does not review the instructions.

Last checked against GitHub 2 months ago.

Dormantupdated 8 months ago

README badge

README badge for sergiodxa/agent-skills/frontend-tailwind-best-practices