← BACK TO DOCS

Responsive Design Guide

Mobile-first · Tailwind CSS 4 · touch-optimized · app-like experience · v7.0 April 2026

← Back to Docs

📱 Responsive Breakpoints

📱
Mobile
< 640px
Default (no prefix)
📱
sm:
640px+
Small tablet, touch-first
📱
md:
768px+
Tablet, 2 columns, hybrid
💻
lg:
1024px+
Desktop, 3 cols, full features
🖥️
xl / 2xl:
1280px / 1536px
Large, max-width centered
// Tailwind CSS 4 — Responsive Breakpoints
sm:  640px   // Small tablet (portrait)
md:  768px   // Tablet (landscape) / large phone
lg:  1024px  // Desktop / laptop
xl:  1280px  // Large desktop
2xl: 1536px  // Extra large (wide monitors)

// Mobile-first: default styles = mobile, overrides go up
<div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3">
    {/* Stacks on mobile, 2-col tablet, 3-col desktop */}
</div>

// Layout components
// apps/web/src/components/layout/MobileFirstLayout.tsx  → mobile
// apps/web/src/components/layout/AppLayout.tsx          → desktop

📲 Mobile Optimizations

👆 Touch Targets

Minimum 44x44px touch targets voor betere touch accuracy

// Minimum touch target
className="p-4"  // Good
className="p-2"  // Too small

↔️ Adequate Spacing

Voldoende ruimte tussen interactive elements

// Adequate spacing
className="gap-3"  // Good
className="gap-1"  // Too tight

👉 Touch Gestures

Swipe, pinch, long-press support

  • Swipe left/right: Navigate between views
  • Pull to refresh: Update content
  • Long press: Context menu
  • Pinch zoom: Images & maps

Active States

Visual feedback on touch

className="active:scale-95 active:bg-purple-700"

📐 Sidebar: No Horizontal Scroll

Critical: Prevent Horizontal Overflow

Sidebars moeten NOOIT een horizontale scrollbar hebben. Dit zorgt voor slechte UX.

❌ FOUT:
Deze content is te breed en forceert horizontal scroll
}
✅ GOED:
Deze content past netjes binnen de sidebar en wordt afgeknipt met ellipsis...
// Sidebar CSS - Prevent horizontal scroll
.sidebar {
    width: 320px;
    max-width: 100%;        /* Never exceed viewport */
    overflow-x: hidden;      /* Hide horizontal scroll */
    overflow-y: auto;        /* Allow vertical scroll */
}

// Content truncation
.sidebar-item {
    width: 100%;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

// OR use word-wrap
.sidebar-text {
    width: 100%;
    word-wrap: break-word;
    overflow-wrap: break-word;
}
Tailwind Classes
<div className="w-full max-w-full overflow-x-hidden overflow-y-auto">
    <div className="truncate">Long text here...</div>
    <div className="break-words">LongURLorTextHere</div>
</div>

🧭 Mobile Navigation Patterns

Bottom Navigation Bar

Role-based menu items — verschillende tabs per rol (Viewer / Member / Creator / Provider).

Content Area

Slide-out Drawer

Menu
Home
Profile
Settings

🏗️ Layout Components

📱 MobileFirstLayout.tsx

apps/web/src/components/layout/MobileFirstLayout.tsx

  • • Fixed bottom navigation bar (role-based)
  • • Swipe-drawer sidebar (geen overlay scroll)
  • • Pull-to-refresh op feed-pagina's
  • • Safe-area insets (iPhone notch / Android)
  • • Min 44px touch targets op alle interacties

🖥️ AppLayout.tsx

apps/web/src/components/layout/AppLayout.tsx

  • • Persistent sidebar (links, collapsible)
  • • 3-kolom grid: sidebar / feed / context panel
  • • Sticky header met zoekbalk
  • • Right panel voor notificaties / chat context
  • • Keyboard shortcuts voor desktop power-users
// Router wiring (react-router-dom v7)
// MobileFirstLayout wraps mobile routes
// AppLayout wraps desktop routes
// Device detection via useMediaQuery hook

function RootLayout() {
  const isMobile = useMediaQuery('(max-width: 768px)');
  return isMobile
    ? <MobileFirstLayout><Outlet /></MobileFirstLayout>
    : <AppLayout><Outlet /></AppLayout>;
}

📲 PWA Production Setup

VitePWA Plugin
• vite.config.ts integratie
• Service Worker auto-registratie
• StaleWhileRevalidate (assets)
• NetworkFirst (API calls)
📋
manifest.json
• name + short_name: "TeezU"
• display: "standalone"
• orientation: "portrait"
• theme_color + icons (192/512px)
📲
Installeerbaar
• Android: Chrome "Add to homescreen"
• iOS: Safari "Share → Add to Home"
• SW update prompt in app
• Offline fallback pagina
// vite.config.ts — VitePWA configuratie
VitePWA({
  registerType: 'autoUpdate',
  workbox: {
    runtimeCaching: [
      { urlPattern: /\/api\//, handler: 'NetworkFirst' },
      { urlPattern: /\.(js|css|png|woff2)$/, handler: 'StaleWhileRevalidate' }
    ]
  }
})

⚡ Mobile Performance

🖼️
Image Optimization
• WebP / AVIF format
• Lazy loading (IntersectionObserver)
• Responsive srcset sizes
📦
Vite 7 Code Splitting
• Route-based lazy chunks
• Dynamic imports + Suspense
• Tree shaking + manualChunks
⚛️
React 19 Concurrent
• useTransition voor non-urgent updates
• Suspense boundaries per route
• Server Components (waar van toepassing)
Virtualization
• TanStack Virtual voor feeds
• Windowing lange lijsten
• TanStack Query v5 infinite scroll