home / skills / doanchienthangdev / omgkit / responsive
This skill helps you build responsive web layouts using mobile-first CSS, fluid typography, and container queries for adaptive UIs across devices.
npx playbooks add skill doanchienthangdev/omgkit --skill responsiveReview the files below or copy the command above to add this skill to your agents.
---
name: building-responsive-layouts
description: Claude builds responsive web layouts with mobile-first CSS, fluid typography, and container queries. Use when creating adaptive UIs that work across all device sizes.
---
# Building Responsive Layouts
## Quick Start
```tsx
// Responsive grid with auto-fit
export function ResponsiveGrid({ children, minWidth = '300px' }: GridProps) {
return (
<div style={{
display: 'grid',
gridTemplateColumns: `repeat(auto-fit, minmax(min(${minWidth}, 100%), 1fr))`,
gap: '1.5rem'
}}>
{children}
</div>
);
}
// With Tailwind
<div className="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 xl:grid-cols-4 gap-4 md:gap-6">
{items.map(item => <Card key={item.id} {...item} />)}
</div>
```
## Features
| Feature | Description | Guide |
|---------|-------------|-------|
| Mobile-First Breakpoints | sm(640), md(768), lg(1024), xl(1280), 2xl(1536) | `ref/breakpoints.md` |
| Fluid Typography | `clamp()` for responsive font sizes | `ref/fluid-type.md` |
| Container Queries | Component-level responsive design | `ref/container-queries.md` |
| Responsive Images | srcset, sizes, and art direction | `ref/images.md` |
| Touch-Friendly | 44px minimum targets, hover vs touch handling | `ref/touch.md` |
| Safe Areas | Handle notched devices and dynamic viewports | `ref/safe-areas.md` |
## Common Patterns
### useMediaQuery Hook
```tsx
export function useMediaQuery(query: string): boolean {
const [matches, setMatches] = useState(false);
useEffect(() => {
const media = window.matchMedia(query);
setMatches(media.matches);
const listener = (e: MediaQueryListEvent) => setMatches(e.matches);
media.addEventListener('change', listener);
return () => media.removeEventListener('change', listener);
}, [query]);
return matches;
}
// Usage
const isMobile = useMediaQuery('(max-width: 639px)');
const prefersReducedMotion = useMediaQuery('(prefers-reduced-motion: reduce)');
```
### Container Query Component
```css
.card-container {
container-type: inline-size;
}
.card {
display: flex;
flex-direction: column;
}
@container (min-width: 400px) {
.card {
flex-direction: row;
gap: 1rem;
}
.card-image { width: 40%; }
}
```
```tsx
export function ResponsiveCard({ image, title, content }: CardProps) {
return (
<div className="card-container">
<article className="card">
<img src={image} alt="" className="card-image" />
<div className="card-content">
<h3>{title}</h3>
<p>{content}</p>
</div>
</article>
</div>
);
}
```
### Responsive Navigation
```tsx
export function ResponsiveNav() {
const [isOpen, setIsOpen] = useState(false);
return (
<nav className="relative">
<div className="flex justify-between items-center h-16 px-4">
<Logo />
{/* Desktop nav */}
<div className="hidden md:flex items-center space-x-8">
<NavLink href="/">Home</NavLink>
<NavLink href="/about">About</NavLink>
</div>
{/* Mobile menu button */}
<button
className="md:hidden p-2 min-h-[44px] min-w-[44px]"
onClick={() => setIsOpen(!isOpen)}
aria-expanded={isOpen}
>
<span className="sr-only">{isOpen ? 'Close' : 'Open'} menu</span>
{isOpen ? <XIcon /> : <MenuIcon />}
</button>
</div>
{/* Mobile nav */}
{isOpen && (
<div className="md:hidden px-2 pb-3 space-y-1">
<MobileNavLink href="/" onClick={() => setIsOpen(false)}>Home</MobileNavLink>
<MobileNavLink href="/about" onClick={() => setIsOpen(false)}>About</MobileNavLink>
</div>
)}
</nav>
);
}
```
## Best Practices
| Do | Avoid |
|----|-------|
| Start with mobile-first CSS | Hiding essential content on mobile |
| Use relative units (rem, %, vw) | Fixed pixel widths |
| Test on real devices | Relying only on hover states |
| Use 44px minimum touch targets | Small touch targets on mobile |
| Consider reduced motion preferences | Ignoring landscape orientation |
| Use CSS logical properties (inline, block) | Device-specific breakpoints |
| Handle safe-area-inset for notched devices | Assuming mouse input |
This skill builds responsive web layouts using mobile-first CSS, fluid typography, and container queries to create adaptive UIs that work across all device sizes. It provides ready-to-use patterns and components for grids, navigation, cards, and responsive imagery. The goal is predictable, accessible layouts that scale from small phones to large desktops.
The skill supplies small, composable components and patterns: an auto-fit responsive grid, a container-query enabled card, and a mobile-first navigation with a touch-friendly toggle. It uses CSS techniques like clamp() for fluid type, container-type queries for component-level layout changes, srcset/sizes for responsive images, and safe-area handling for notched devices. Optional hooks (useMediaQuery) let you read viewport or preference state in JavaScript when CSS alone isn’t enough.
When should I use container queries versus media queries?
Use container queries when layout changes depend on a component’s available space. Use media queries for global breakpoint changes tied to the viewport.
How do I implement fluid typography safely?
Combine clamp() with a base rem scale. Use min/max limits to prevent overly small or large text and test at multiple widths and devices.