Responsive design patterns for 320px minimum width.
- 320px minimum width. Every feature must be usable on the smallest phones.
- 44x44px touch targets. All interactive elements must meet this minimum.
- No horizontal scroll. Content must wrap or adapt, never overflow.
- Mobile-first CSS. Write base styles for mobile, add complexity with
sm:,md:,lg:.
<div className="flex flex-col lg:flex-row gap-4">
<div className="lg:w-1/2">{/* Input */}</div>
<div className="lg:w-1/2">{/* Output */}</div>
</div>Never constrain input width on mobile:
// Good
<input className="w-full min-w-0" />
// Bad -- may overflow on small screens
<input className="w-96" />The min-w-0 is critical inside flex containers to prevent overflow.
// Good -- meets 44px minimum
<button className="min-h-[44px] min-w-[44px] px-4 py-2">
Submit
</button>
// Bad -- too small for touch
<button className="px-2 py-1 text-xs">
Submit
</button>Native date/time inputs have browser-specific styling. Normalize them:
<input
type="date"
className="appearance-none min-h-[44px] min-w-0 w-full rounded-lg border px-3"
/>When displaying multiple values inline, always allow wrapping:
// Good -- wraps naturally
<div className="flex flex-wrap gap-2">
<span>Value 1</span>
<span>Value 2</span>
<span>Value 3</span>
</div>
// Bad -- pushes content off screen
<div className="flex gap-2">
<span>Very Long Value</span>
<span>Another Long Value</span>
</div>Banners or status bars with variable text should use fixed heights to prevent layout shift:
// Good -- consistent height regardless of content
<div className="h-10 flex items-center overflow-hidden">
{statusMessage}
</div>
// Bad -- height changes based on text length, pushing content around
<div className="py-2">
{statusMessage}
</div>The template uses Tailwind's default breakpoints:
| Prefix | Min Width | Typical Device |
|---|---|---|
| (none) | 0px | Phones (320px+) |
sm: |
640px | Large phones, small tablets |
md: |
768px | Tablets |
lg: |
1024px | Laptops |
xl: |
1280px | Desktops |
Pattern: Design for the smallest screen first, then add overrides:
<div className="text-sm md:text-base lg:text-lg">
{/* Starts small, grows with screen */}
</div>import { useMediaQuery } from '../hooks/useMediaQuery';
function MyFeature() {
const isDesktop = useMediaQuery('(min-width: 1024px)');
return isDesktop ? <DesktopLayout /> : <MobileLayout />;
}- Open Chrome DevTools (F12)
- Toggle Device Toolbar (Ctrl+Shift+M)
- Select "iPhone SE" (375px) or set custom 320px
- Test all interactive elements are reachable and usable