);
}
// Usage with Tailwind
function ProductGrid({ products }) {
return (
{products.map((product) => (
))}
);
}
```
### Pattern 4: Responsive Navigation
```tsx
function ResponsiveNav({ items }) {
const [isOpen, setIsOpen] = useState(false);
return (
);
}
```
### Pattern 5: Responsive Images
```tsx
// Responsive image with art direction
function ResponsiveHero() {
return (
{/* Art direction: different crops for different screens */}
{/* Fallback */}
);
}
// Responsive image with srcset for resolution switching
function ProductImage({ product }) {
return (
);
}
```
### Pattern 6: Responsive Tables
```tsx
// Responsive table with horizontal scroll
function ResponsiveTable({ data, columns }) {
return (
{columns.map((col) => (
{col.label}
))}
{data.map((row, i) => (
{columns.map((col) => (
{row[col.key]}
))}
))}
);
}
// Card-based table for mobile
function ResponsiveDataTable({ data, columns }) {
return (
<>
{/* Desktop table */}
{/* ... standard table */}
{/* Mobile cards */}
{data.map((row, i) => (
{columns.map((col) => (
{col.label}
{row[col.key]}
))}
))}
>
);
}
```
## Viewport Units
```css
/* Standard viewport units */
.full-height {
height: 100vh; /* May cause issues on mobile */
}
/* Dynamic viewport units (recommended for mobile) */
.full-height-dynamic {
height: 100dvh; /* Accounts for mobile browser UI */
}
/* Small viewport (minimum) */
.min-full-height {
min-height: 100svh;
}
/* Large viewport (maximum) */
.max-full-height {
max-height: 100lvh;
}
/* Viewport-relative font sizing */
.hero-title {
/* 5vw with min/max bounds */
font-size: clamp(2rem, 5vw, 4rem);
}
```
## Best Practices
1. **Mobile-First**: Start with mobile styles, enhance for larger screens
2. **Content Breakpoints**: Set breakpoints based on content, not devices
3. **Fluid Over Fixed**: Use fluid values for typography and spacing
4. **Container Queries**: Use for component-level responsiveness
5. **Test Real Devices**: Simulators don't catch all issues
6. **Performance**: Optimize images, lazy load off-screen content
7. **Touch Targets**: Maintain 44x44px minimum on mobile
8. **Logical Properties**: Use inline/block for internationalization
## Common Issues
- **Horizontal Overflow**: Content breaking out of viewport
- **Fixed Widths**: Using px instead of relative units
- **Viewport Height**: 100vh issues on mobile browsers
- **Font Size**: Text too small on mobile
- **Touch Targets**: Buttons too small to tap accurately
- **Aspect Ratio**: Images squishing or stretching
- **Z-Index Stacking**: Overlays breaking on different screens
## Resources
- [CSS Container Queries](https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_container_queries)
- [Utopia Fluid Type Calculator](https://utopia.fyi/type/calculator/)
- [Every Layout](https://every-layout.dev/)
- [Responsive Images Guide](https://web.dev/responsive-images/)
- [CSS Grid Garden](https://cssgridgarden.com/)