Styling
Styling isn’t only about aesthetics, it’s about maintainability, scalability, and consistency across the UI. Whether you’re using utility-first CSS like Tailwind, scoped styles like CSS Modules, or CSS-in-JS libraries, the goal is to make styles predictable and easy to reason about. A clear styling strategy ensures that teams can work faster without sacrificing quality or introducing UI inconsistencies.
Preferred styling approaches
To keep things consistent across the codebase, we generally follow two styling methods:
- Tailwind CSS (with shadcn/ui)
- Tailwind offers a utility-first approach that accelerates development while keeping styles consistent. It offers a utility-first approach that works great for design consistency and rapid development.
- When paired with shadcn/ui, you get a head start with accessible, pre-styled components that are easy to customize.
- Utility classes make it easy to build responsive, maintainable UIs without managing large CSS files.
- Shadcn/ui
- A well-structured component library built on Tailwind CSS and Radix UI.
- Provides accessible, composable, and theme-ready components out of the box.
- . Ideal for modern React projects, by encouraging consistency and reducing the time spent reinventing common UI patterns.
Guideline: Stick to Tailwind + shadcn/ui for all new code. Avoid mixing in other styling systems to maintain a unified approach.
Styling best practices
- Understand Tailwind Core Concepts
- Understand utility classes, responsive prefixes, variants, and theming before diving deep.
- We highly recommend that you first read the Tailwind Core concepts.
- Avoid Inline Styles
- Do not use inline styles unless absolutely necessary. They make theming harder, limit CSS features like hover or media queries, and reduce code clarity.
- Use Tailwind utility classes or customize shadcn/ui components instead.
- Use Design Tokens
- Stick to spacing, color, and typography tokens defined in the Tailwind config.
- Avoid hardcoding values like
#ff0000or16px. Instead, use semantic classes liketext-primarybg-mutedp-4
This ensures consistency, supports theming/dark mode, and simplifies large-scale design update.
- Minimal Global Styles
- Keep global styles limited to CSS resets and base typography rules.
- Avoid attaching styles directly to raw HTML elements unless part of the design system. Let shadcn/ui and Tailwind handle most of the layout and visual concerns.
- Consistent Naming for Custom Classes
- If you need custom classes, use descriptive, functional names (e.g., btn-primary, card-header)
- Avoid abstract or unclear labels like “box1” or “redText.”
- Prefer Tailwind utilities. In most cases, custom classes should not be needed.
- Mobile-First & Responsive Design
- Always build mobile-first UIs using Tailwind’s responsive prefixes:
- sm: Small screens and up.
- md: Medium screens and up.
- lg: Large screens and up.
- Always build mobile-first UIs using Tailwind’s responsive prefixes:
- Keep responsiveness in mind from the start instead of patching it in later. Dark Mode and Theming.
- Use the “class=dark” strategy for enabling dark mode. Always use semantic tokens like “bg-muted” or “text-primary” instead of raw values to support theming.
- Tailwind and shadcn/ui both support this pattern.
- Do Not Mix Styling Approaches
- Avoid using multiple competing styling solutions (CSS Modules, SASS, raw CSS-in-JS).
- Stick to Tailwind + shadcn/ui for a consistent, scalable, and predictable styling system
Additional recommendations
- Accessibility (a11y): Ensure styles do not harm accessibility (e.g., sufficient color contrast, focus states).
- Theming Strategy: Define clear rules for light/dark themes and brand-specific themes.
- Reusable Components: Extend shadcn/ui components when required instead of creating new ones from scratch.
- Performance: Avoid generating unnecessary utility classes in Tailwind. Use PurgeCSS (built-in with Tailwind) to keep bundles lean.







