---
name: mobile-responsiveness
description: Build responsive, mobile-first web applications. Use when implementing responsive layouts, touch interactions, mobile navigation, or optimizing for various screen sizes. Triggers on responsive design, mobile-first, breakpoints, touch events, viewport.
---
# Mobile Responsiveness
Build responsive, mobile-first web applications.
## Mobile-First Breakpoints
```css
/* Mobile first - no media query needed for mobile base */
.container {
padding: 1rem;
}
/* Tablet */
@media (min-width: 768px) {
.container {
padding: 2rem;
}
}
/* Desktop */
@media (min-width: 1024px) {
.container {
padding: 3rem;
max-width: 1200px;
margin: 0 auto;
}
}
/* Large desktop */
@media (min-width: 1280px) {
.container {
max-width: 1400px;
}
}
```
## Tailwind Breakpoints
```tsx
Responsive Heading
```
## Fluid Typography
```css
:root {
/* Fluid font size: 16px at 320px viewport, 20px at 1200px viewport */
--font-size-base: clamp(1rem, 0.9rem + 0.5vw, 1.25rem);
/* Fluid heading */
--font-size-h1: clamp(2rem, 1.5rem + 2.5vw, 4rem);
}
body {
font-size: var(--font-size-base);
}
h1 {
font-size: var(--font-size-h1);
}
```
## Touch Interactions
```tsx
import { useState } from 'react';
function SwipeableCard({ onSwipeLeft, onSwipeRight, children }) {
const [touchStart, setTouchStart] = useState(null);
const [touchEnd, setTouchEnd] = useState(null);
const minSwipeDistance = 50;
const onTouchStart = (e: React.TouchEvent) => {
setTouchEnd(null);
setTouchStart(e.targetTouches[0].clientX);
};
const onTouchMove = (e: React.TouchEvent) => {
setTouchEnd(e.targetTouches[0].clientX);
};
const onTouchEnd = () => {
if (!touchStart || !touchEnd) return;
const distance = touchStart - touchEnd;
const isLeftSwipe = distance > minSwipeDistance;
const isRightSwipe = distance < -minSwipeDistance;
if (isLeftSwipe) onSwipeLeft?.();
if (isRightSwipe) onSwipeRight?.();
};
return (
{children}
);
}
```
## Mobile Navigation
```tsx
import { useState } from 'react';
function MobileNav() {
const [isOpen, setIsOpen] = useState(false);
return (
<>
{/* Hamburger button - visible on mobile */}
{/* Mobile menu */}
{/* Backdrop */}
{isOpen && (
setIsOpen(false)}
/>
)}
>
);
}
```
## Safe Areas (Notch/Home Indicator)
```css
/* Account for iPhone notch and home indicator */
.container {
padding-left: env(safe-area-inset-left);
padding-right: env(safe-area-inset-right);
padding-bottom: env(safe-area-inset-bottom);
}
/* Fixed bottom navigation */
.bottom-nav {
position: fixed;
bottom: 0;
left: 0;
right: 0;
padding-bottom: max(1rem, env(safe-area-inset-bottom));
}
```
## Viewport Meta Tag
```html
```
## useMediaQuery Hook
```tsx
import { useState, useEffect } from 'react';
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
function Component() {
const isMobile = useMediaQuery('(max-width: 767px)');
const isTablet = useMediaQuery('(min-width: 768px) and (max-width: 1023px)');
const isDesktop = useMediaQuery('(min-width: 1024px)');
return isMobile ? : ;
}
```
## Resources
- **Responsive Design**: https://web.dev/learn/design/
- **Mobile-First CSS**: https://developer.mozilla.org/en-US/docs/Learn/CSS/CSS_layout/Responsive_Design
- **Viewport Units**: https://developer.mozilla.org/en-US/docs/Web/CSS/length#viewport-percentage_lengths