- mobile-patterns.md: Mobile layout & pattern systems (18.5KB) Fluid typography, container queries, safe-area, CSS architecture, touch-optimized components, iOS/Android specifics, testing checklist - mobile-layout-patterns.md: Mobile layout systems (11.5KB) CSS grid, single-column stack, full-bleed hero, card stack, swipeable carousel, split-screen, off-canvas nav, bottom sheet, FAB, component patterns - mobile-navigation-patterns.md: Mobile navigation (9.8KB) Bottom tab bar, top nav, hamburger menu, bottom sheet nav, pill nav, comparison matrix, navigation rules, swipe navigation, breadcrumbs, tab content - mobile-form-patterns.md: Mobile form patterns (10.3KB) Input types, keyboards, floating labels, validation patterns, progressive disclosure, autocomplete, masked inputs, toggle/radio, form anti-patterns - mobile-interaction-patterns.md: Touch & gestures (16.7KB) Swipe detection, long press, pull-to-refresh, touch feedback, scroll-reveal, parallax, sticky scroll, CSS scroll animations, touch carousel, haptic feedback, passive listeners - mobile-performance-patterns.md: Performance optimization (12.3KB) Core Web Vitals (LCP/INP/CLS), LCP optimization, INP debugging, CLS prevention, image optimization, lazy loading, service workers, CSS/JS optimization, network optimization - mobile-landing-patterns.md: Landing page patterns (21.3KB) Section sequencing, hero, social proof, feature cards, CTA patterns (inline/sticky/full-bleed), testimonials, pricing, FAQ accordion, footer, mobile checklist
18 KiB
title, created, updated, type, tags, sources, confidence
| title | created | updated | type | tags | sources | confidence | ||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|
| Mobile Layout & Pattern Systems | 2026-07-03 | 2026-07-03 | system |
|
high |
Mobile Layout & Pattern Systems — Мобильные паттерны верстки
1. Базовые принципы
Mobile-First: философия, а не техника
Мобильный дизайн — это дисциплина приоритизации. На экране 360×800px каждое пиксельное решение имеет вес.
| Принцип | Описание |
|---|---|
| Progressive Enhancement | Базовый контент → улучшенные компоненты → desktop-роскошь |
| One-thumb Zone | Основные интерактивные элементы в нижней половине экрана |
| Content-First Flow | Сначала контент, потом декор (всегда) |
| Touch-Optimized | 44×44px минимальный tap target, 8px gap между touch-элементами |
| Performance-Aware | Каждый миллисекунда LCP на мобильном важнее десктопа |
Глобальные CSS Variables для Mobile
:root {
/* Safe Area — iOS notch, Android gesture bar */
--safe-top: env(safe-area-inset-top, 20px);
--safe-bottom: env(safe-area-inset-bottom, 34px);
--safe-left: env(safe-area-inset-left, 0px);
--safe-right: env(safe-area-inset-right, 0px);
/* Typography — fluid on mobile */
--text-xs: clamp(0.75rem, 2vw, 0.875rem);
--text-sm: clamp(0.875rem, 2.5vw, 1rem);
--text-base: clamp(1rem, 3vw, 1.125rem);
--text-lg: clamp(1.125rem, 3.5vw, 1.25rem);
--text-xl: clamp(1.25rem, 4vw, 1.5rem);
/* Spacing — mobile-optimized */
--space-xs: 0.25rem;
--space-sm: 0.5rem;
--space-md: 1rem;
--space-lg: 1.5rem;
--space-xl: 2rem;
--space-2xl: 3rem;
/* Touch targets */
--touch-min: 44px;
--touch-gap: 8px;
/* Breakpoints — content-based, not device-based */
--bp-sm: 480px; /* Large phones */
--bp-md: 768px; /* Tablets portrait */
--bp-lg: 1024px; /* Tablets landscape */
--bp-xl: 1280px; /* Desktops */
}
2. Breakpoints: Content-Based, Not Device-Based
Современная система breakpoints
/* Content-first breakpoints */
@media (min-width: 640px) { /* sm: Large phones, small tablets */ }
@media (min-width: 768px) { /* md: Tablets */ }
@media (min-width: 1024px) { /* lg: Small laptops */ }
@media (min-width: 1280px) { /* xl: Desktops */ }
@media (min-width: 1536px) { /* 2xl: Large desktops */ }
/* Container Queries — component-level адаптивность */
.card-container {
container-type: inline-size;
container-name: card;
}
@container card (min-width: 400px) {
.card {
grid-template-columns: 1fr 2fr;
}
}
@container card (min-width: 600px) {
.card {
grid-template-columns: 1fr 1fr 1fr;
}
}
Почему container queries > media queries
| Media Queries | Container Queries |
|---|---|
| Адаптация по viewport | Адаптация по родительскому контейнеру |
| Один layout для всей страницы | Разные layout для разных компонентов |
| Медленные перерасчеты | Реакция на изменение контейнера |
| Не работает в iframe/grid | Работает везде |
3. Mobile Layout Patterns
3.1 Single-Column Stack (Базовый)
Все элементы вертикально, 16-24px gap между секциями.
.mobile-stack {
display: flex;
flex-direction: column;
gap: var(--space-lg);
padding: var(--space-lg) var(--space-md) calc(var(--safe-bottom) + var(--space-lg)) var(--space-md);
}
.mobile-stack > * {
width: 100%;
max-width: 100%;
}
Где использовать: Лендинги, product pages, статьи, landing pages для мобайла.
3.2 Full-Bleed Sections
Секции, выходящие за границы контейнера, создают глубину.
.full-bleed-section {
margin-left: calc(var(--space-md) * -1);
margin-right: calc(var(--space-md) * -1);
}
.full-bleed-section .container {
padding-left: var(--space-lg);
padding-right: var(--space-lg);
}
Где использовать: Hero, testimonials, image-heavy sections.
3.3 Bento Grid (Mobile Adaptation)
На мобайле bento grid превращается в single-column с карточками разной высоты.
.bento-grid {
display: grid;
grid-template-columns: 1fr;
gap: var(--space-md);
}
.bento-card {
min-height: var(--touch-min);
padding: var(--space-lg);
border-radius: var(--space-md);
}
.bento-card.featured {
order: -1; /* featured card first */
}
3.4 Sticky Bottom CTA
Кнопка действия всегда видна внизу экрана, над клавиатурой.
.sticky-bottom-cta {
position: fixed;
bottom: 0;
left: 0;
right: 0;
padding: var(--space-md) var(--space-lg) calc(var(--safe-bottom) + var(--space-md));
background: linear-gradient(to top, rgba(0,0,0,0.9), transparent);
z-index: 100;
}
.sticky-bottom-cta button {
min-height: var(--touch-min);
width: 100%;
font-size: var(--text-lg);
font-weight: 600;
}
Где использовать: E-commerce, формы, booking-системы.
3.5 Card-First Layout
Контент карточками — основной паттерн мобайла.
.card-list {
display: flex;
flex-direction: column;
gap: var(--space-md);
padding: var(--space-md) var(--space-lg);
}
.card {
background: var(--surface-1);
border-radius: var(--space-md);
padding: var(--space-lg);
box-shadow: 0 1px 3px rgba(0,0,0,0.08);
/* Touch-friendly */
min-height: var(--touch-min);
display: flex;
flex-direction: column;
justify-content: center;
}
.card__media {
width: 100%;
aspect-ratio: 16/9;
object-fit: cover;
border-radius: var(--space-sm) var(--space-sm) 0 0;
margin: calc(var(--space-lg) * -1) calc(var(--space-lg) * -1) var(--space-md);
}
.card__title {
font-size: var(--text-lg);
font-weight: 600;
margin-bottom: var(--space-xs);
}
.card__meta {
font-size: var(--text-xs);
color: var(--text-secondary);
}
3.6 Masonry (Mobile)
.masonry {
columns: 2;
column-gap: var(--space-sm);
}
.masonry-item {
break-inside: avoid;
margin-bottom: var(--space-sm);
border-radius: var(--space-sm);
}
/* Single column on very small screens */
@media (max-width: 360px) {
.masonry { columns: 1; }
}
3.7 Swipeable Sections
CSS scroll-snap для горизонтальных секций.
.swipe-section {
display: flex;
gap: var(--space-md);
overflow-x: auto;
scroll-snap-type: x mandatory;
scroll-behavior: smooth;
-webkit-overflow-scrolling: touch;
padding: var(--space-md) var(--space-lg);
scrollbar-width: none; /* Firefox */
}
.swipe-section::-webkit-scrollbar {
display: none;
}
.swipe-item {
scroll-snap-align: start;
flex: 0 0 auto;
width: min(280px, 80vw);
}
Где использовать: Карусели, product carousels, category pills, testimonial sliders.
4. Mobile Typography
Fluid Typography Formula
/* Base size scales proportionally */
--text-base-size: clamp(1rem, 0.875rem + 0.5vw, 1.25rem);
/* Scale multiplier */
--scale-ratio: 1.25; /* Major Third */
--text-sm: calc(var(--text-base-size) / var(--scale-ratio));
--text-lg: calc(var(--text-base-size) * var(--scale-ratio));
--text-xl: calc(var(--text-lg) * var(--scale-ratio));
--text-2xl: calc(var(--text-xl) * var(--scale-ratio));
Line Height & Readability
/* Body text — line-height для мобильных */
.text-body {
font-size: var(--text-base);
line-height: 1.6; /* 1.5 на десктопе, 1.6 на мобайле */
max-width: 65ch; /* Оптимальная ширина строки */
}
/* Headings — tighter on mobile */
.text-heading {
line-height: 1.2;
font-weight: 700;
letter-spacing: -0.02em;
}
5. Touch-Optimized Components
Touch-First Button
.btn {
min-height: var(--touch-min);
min-width: var(--touch-min);
padding: var(--space-md) var(--space-xl);
display: inline-flex;
align-items: center;
justify-content: center;
gap: var(--space-sm);
font-size: var(--text-base);
font-weight: 600;
border: none;
border-radius: var(--space-md);
cursor: pointer;
transition: transform 0.1s ease, background 0.2s ease;
/* Touch feedback */
-webkit-tap-highlight-color: transparent;
-webkit-touch-callout: none;
}
.btn:active {
transform: scale(0.98);
}
Touch-Optimized Form Input
.form-input {
min-height: var(--touch-min);
padding: var(--space-md) var(--space-lg);
font-size: var(--text-base); /* Prevents iOS zoom on focus */
border: 2px solid var(--border-1);
border-radius: var(--space-md);
background: var(--surface-1);
transition: border-color 0.15s ease;
width: 100%;
}
.form-input:focus {
border-color: var(--primary);
outline: none;
box-shadow: 0 0 0 3px color-mix(in srgb, var(--primary) 20%, transparent);
}
/* iOS zoom prevention */
@media screen and (max-width: 480px) {
.form-input {
font-size: 16px; /* Minimum to prevent zoom on iOS */
}
}
6. Mobile-First CSS Architecture
Base → Component → Layout
styles/
base/
_reset.css /* Normalize, box-sizing */
_typography.css /* Fluid type scale */
_colors.css /* CSS Variables, tokens */
_accessibility.css /* Focus states, reduced motion */
components/
_buttons.css /* Touch-optimized buttons */
_inputs.css /* Form fields */
_cards.css /* Card patterns */
_nav.css /* Mobile nav */
layout/
_stack.css /* Single-column layout */
_grid.css /* Responsive grids */
_sections.css /* Section patterns */
utilities/
_spacing.css /* Margin/padding utilities */
_display.css /* Flex, grid utilities */
_accessibility.css /* sr-only, reduced-motion */
Reduced Motion
@media (prefers-reduced-motion: reduce) {
*,
*::before,
*::after {
animation-duration: 0.01ms !important;
animation-iteration-count: 1 !important;
transition-duration: 0.01ms !important;
scroll-behavior: auto !important;
}
}
7. Performance Patterns for Mobile
Image Optimization
<!-- Progressive image loading -->
<img
src="thumb.webp"
srcset="small.webp 400w, medium.webp 800w, large.webp 1200w"
sizes="(max-width: 768px) 100vw, 50vw"
loading="lazy"
decoding="async"
width="800"
height="600"
alt="Description"
class="lazy-image"
/>
<style>
.lazy-image {
background: color-mix(in srgb, var(--surface-2) 50%, transparent);
animation: image-reveal 0.4s ease forwards;
opacity: 0;
aspect-ratio: attr(width) / attr(height);
}
@keyframes image-reveal {
to { opacity: 1; }
}
</style>
Critical CSS for Mobile
/* Inlined in <head> for mobile LCP optimization */
/* Critical path CSS — < 14KB gzipped */
body {
font-family: system-ui, -apple-system, sans-serif;
margin: 0;
padding: 0;
color: var(--text-primary);
}
.hero {
min-height: 60vh;
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
padding: var(--space-xl) var(--space-lg);
text-align: center;
}
Lazy Loading with Intersection Observer
// Lightweight lazy loader (no dependencies)
const lazyObserver = new IntersectionObserver((entries) => {
entries.forEach(entry => {
if (entry.isIntersecting) {
const el = entry.target;
if (el.dataset.src) {
el.src = el.dataset.src;
}
if (el.dataset.bg) {
el.style.backgroundImage = `url(${el.dataset.bg})`;
}
lazyObserver.unobserve(el);
}
});
}, {
rootMargin: '200px 0px', // Start loading 200px before visible
threshold: 0.01
});
document.querySelectorAll('.lazy').forEach(el => {
lazyObserver.observe(el);
});
8. iOS & Android Specific Patterns
Viewport Meta Tag
<meta name="viewport" content="width=device-width, initial-scale=1, viewport-fit=cover">
iOS-Specific Fixes
/* Prevent iOS Safari bounce effect */
body {
overscroll-behavior-y: contain;
-webkit-overflow-scrolling: touch;
}
/* Full viewport height fix for iOS */
.mobile-container {
min-height: 100dvh; /* Dynamic viewport height */
}
/* Prevent pull-to-refresh on specific elements */
.prevent-pull-to-refresh {
overscroll-behavior-y: none;
}
Dark Mode (iOS & Android)
/* System dark mode — auto-applied */
@media (prefers-color-scheme: dark) {
:root {
--text-primary: #ffffff;
--text-secondary: rgba(255,255,255,0.7);
--surface-1: #1c1c1e;
--surface-2: #2c2c2e;
--border-1: rgba(255,255,255,0.1);
}
}
/* Force dark mode toggle */
[data-theme="dark"] {
--text-primary: #ffffff;
--surface-1: #1c1c1e;
}
9. Mobile Testing Checklist
| Category | Check | Tool |
|---|---|---|
| Layout | Single-column flow at 320px width | Chrome DevTools |
| Touch | All tap targets ≥ 44×44px | Lighthouse |
| Typography | No zoom on iOS input focus | Real device test |
| Performance | LCP < 2.5s, INP < 200ms, CLS < 0.1 | PageSpeed Insights |
| Safe Area | Content doesn't overlap notch/home indicator | iPhone real device |
| Scroll | Horizontal scrolls fixed, vertical smooth | Real device test |
| Forms | Correct keyboard types for each input | Lighthouse |
| Dark Mode | All components readable in dark | Developer tools |
| Orientation | Portrait & landscape tested | Real device test |
| Accessibility | Touch targets, contrast, labels | axe DevTools |
10. Mobile-First Development Workflow
Step 1: Wireframe at 360px
Начинай всегда с самого маленького экрана. Если не помещается — режь контент.
Step 2: Base Styles Mobile-First
/* Mobile first — base styles for 320px+ */
.component {
display: flex;
flex-direction: column;
gap: var(--space-md);
padding: var(--space-lg);
}
/* Tablet landscape & up */
@media (min-width: 768px) {
.component {
flex-direction: row;
gap: var(--space-xl);
padding: var(--space-2xl);
}
}
/* Desktop */
@media (min-width: 1024px) {
.component {
max-width: 1200px;
margin: 0 auto;
}
}
Step 3: Progressive Enhancement
- Level 1 (Mobile base): Content, navigation, forms
- Level 2 (Tablet+): Two-column layouts, side-by-side components
- Level 3 (Desktop+): Animations, complex interactions, floating elements
- Level 4 (Desktop+): Parallax, 3D transforms, advanced effects
Step 4: Test on Real Devices
Chrome DevTools — хорошо для макета, но не для производительности. Всегда тестируй на реальном устройстве:
- iOS Safari (Zoom, pull-to-refresh, safe area)
- Android Chrome (Variable refresh rate, different touch behavior)
- 3G/4G throttling (реальная скорость загрузки)
11. Mobile Anti-Patterns
| ❌ Плохо | ✅ Хорошо |
|---|---|
| Hamburger-меню для всех навигаций | Bottom tab bar для 3-5 основных разделов |
| Hover-эффекты | Active/pressed states для touch |
| Фиксированные ширины | Fluid typography + container queries |
| Полноценные изображения на всех экранах | Responsive images + lazy loading |
| Inline JS анимации | CSS transitions + GPU-accelerated transforms |
| 100vh для full-height секций | 100dvh (dynamic viewport) |
| Скрытые CTA | Sticky bottom CTA на scrollable страницах |
| Автоплей видео | Play/pause по тапу, muted по умолчанию |
| Popup-формы на мобайле | Inline-формы, progressive disclosure |
12. Mobile Component Library Checklist
Базовые компоненты
- Button — primary, secondary, ghost, icon-only
- Input — text, password, email, tel, number, search
- Select — native select (мобильные picker'ы)
- Card — image card, text card, media card
- List — simple, divider, avatar
- Navigation — bottom tab, top nav, breadcrumbs
- Modal — full-screen on mobile, centered on desktop
- Toast/Alert — dismissible, auto-dismiss
- Tab Bar — scrollable on overflow
- Accordion — expandable sections (FAQ, settings)
Mobile-Specific
- Swipeable Carousel — touch-enabled
- Pull-to-Refresh — native iOS/Android feel
- Bottom Sheet — slide-up from bottom
- Floating Action Button — contextual actions
- Sticky Footer — always-visible CTA