# Feature Grid

> A three-column icon feature grid with a heading and subtitle.

- Author: Atelier UI
- License: MIT
- Page: https://chromotion.dev/en/components/feature-grid
- Site: Atelier UI (https://chromotion.dev)

## Install

```bash
npx shadcn@latest add https://chromotion.dev/r/feature-grid.json
```

Stack: React + TypeScript + Tailwind CSS v4, shadcn/ui conventions. `cn` comes from `@/lib/utils`.

## Dependencies

No extra dependencies.

## Usage

```tsx title="components/feature-grid-demo.tsx"
import { Blocks, Gauge, Lock, Palette, Rocket, Sparkles } from "lucide-react"

import { FeatureGrid } from "@/components/feature-grid"

export default function FeatureGridDemo() {
  return (
    <div className="w-full max-w-5xl rounded-2xl border bg-background">
      <FeatureGrid
        title="Everything you need to ship faster"
        subtitle="A thoughtful set of primitives and patterns, ready to drop into your next product."
        features={[
          { icon: <Blocks />, title: "Composable by design", description: "Small, focused building blocks that snap together without fighting your layout." },
          { icon: <Palette />, title: "Themeable tokens", description: "Light and dark modes come from a single set of CSS variables you control." },
          { icon: <Gauge />, title: "Fast by default", description: "Zero runtime styling cost and server-friendly components keep pages snappy." },
          { icon: <Lock />, title: "Accessible", description: "Keyboard navigation, focus rings and ARIA wiring are handled for you." },
          { icon: <Rocket />, title: "Copy and paste", description: "Own the source. Tweak every detail without waiting on a package release." },
          { icon: <Sparkles />, title: "Polished details", description: "Subtle motion and refined spacing that make interfaces feel finished." },
        ]}
      />
    </div>
  )
}
```

## Source

```tsx title="components/feature-grid.tsx"
import * as React from "react"

import { cn } from "@/lib/utils"

export interface FeatureGridItem {
  icon: React.ReactNode
  title: string
  description: string
}

export interface FeatureGridProps extends Omit<React.ComponentProps<"section">, "title"> {
  title?: React.ReactNode
  subtitle?: React.ReactNode
  features: FeatureGridItem[]
}

export function FeatureGrid({ title, subtitle, features, className, ...props }: FeatureGridProps) {
  return (
    <section className={cn("w-full px-6 py-16", className)} {...props}>
      <div className="mx-auto max-w-5xl">
        {(title || subtitle) && (
          <div className="mx-auto mb-12 max-w-2xl text-center">
            {title && <h2 className="text-3xl font-semibold tracking-tight text-balance sm:text-4xl">{title}</h2>}
            {subtitle && <p className="mt-3 text-base text-muted-foreground text-pretty">{subtitle}</p>}
          </div>
        )}
        <ul className="grid gap-x-8 gap-y-10 sm:grid-cols-2 lg:grid-cols-3">
          {features.map((feature) => (
            <li key={feature.title} className="flex flex-col items-start gap-3">
              <span className="flex size-11 items-center justify-center rounded-xl border bg-card text-primary shadow-sm [&_svg]:size-5">
                {feature.icon}
              </span>
              <h3 className="text-base font-semibold">{feature.title}</h3>
              <p className="text-sm leading-relaxed text-muted-foreground">{feature.description}</p>
            </li>
          ))}
        </ul>
      </div>
    </section>
  )
}
```
