feat(mobile): comprehensive mobile web design patterns — 6 new articles
- 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
This commit is contained in:
1 parent
76c4c5b4fe
commit
083f6ba783
7 files changed
+4192
No files matched your search
@@ -0,0 +1,663 @@
|
||||
---
|
||||
title: Mobile Layout & Pattern Systems
|
||||
created: 2026-07-03
|
||||
updated: 2026-07-03
|
||||
type: system
|
||||
tags: [mobile, layout, patterns, responsive, touch, mobile-first]
|
||||
sources:
|
||||
- https://www.uxpin.com/studio/blog/mobile-navigation-examples/
|
||||
- https://www.uxpin.com/studio/blog/mobile-navigation-patterns-pros-and-cons/
|
||||
- https://www.letsgroto.com/blog/mobile-first-responsive-design-best-practices
|
||||
- https://www.uxpin.com/studio/blog/best-practices-examples-of-excellent-responsive-design/
|
||||
- https://www.startdesigns.com/blog/responsive-web-design-2026/
|
||||
- https://www.jamesrossjr.com/blog/responsive-web-design-best-practices
|
||||
- https://dev.to/gerryleonugroho/responsive-design-breakpoints-2025-playbook-53ih
|
||||
- https://scrimba.com/articles/responsive-web-design-a-complete-guide-2026-2/
|
||||
confidence: 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
|
||||
|
||||
```css
|
||||
: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
|
||||
|
||||
```css
|
||||
/* 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 между секциями.
|
||||
|
||||
```css
|
||||
.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
|
||||
|
||||
Секции, выходящие за границы контейнера, создают глубину.
|
||||
|
||||
```css
|
||||
.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 с карточками разной высоты.
|
||||
|
||||
```css
|
||||
.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
|
||||
|
||||
Кнопка действия всегда видна внизу экрана, над клавиатурой.
|
||||
|
||||
```css
|
||||
.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
|
||||
|
||||
Контент карточками — основной паттерн мобайла.
|
||||
|
||||
```css
|
||||
.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)
|
||||
|
||||
```css
|
||||
.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 для горизонтальных секций.
|
||||
|
||||
```css
|
||||
.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
|
||||
|
||||
```css
|
||||
/* 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
|
||||
|
||||
```css
|
||||
/* 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
|
||||
|
||||
```css
|
||||
.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
|
||||
|
||||
```css
|
||||
.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
|
||||
|
||||
```css
|
||||
@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
|
||||
|
||||
```html
|
||||
<!-- 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
|
||||
|
||||
```css
|
||||
/* 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
|
||||
|
||||
```javascript
|
||||
// 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
|
||||
|
||||
```html
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1, viewport-fit=cover">
|
||||
```
|
||||
|
||||
### iOS-Specific Fixes
|
||||
|
||||
```css
|
||||
/* 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)
|
||||
|
||||
```css
|
||||
/* 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
|
||||
|
||||
```css
|
||||
/* 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
|
||||
|
||||
1. **Level 1 (Mobile base):** Content, navigation, forms
|
||||
2. **Level 2 (Tablet+):** Two-column layouts, side-by-side components
|
||||
3. **Level 3 (Desktop+):** Animations, complex interactions, floating elements
|
||||
4. **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
|
||||
|
||||
## 13. Source Links
|
||||
|
||||
- [UXPin: Mobile Navigation Examples](https://www.uxpin.com/studio/blog/mobile-navigation-examples/)
|
||||
- [UXPin: Mobile Navigation Patterns Pros/Cons](https://www.uxpin.com/studio/blog/mobile-navigation-patterns-pros-and-cons/)
|
||||
- [James Ross Jr: Responsive Design Best Practices 2026](https://www.jamesrossjr.com/blog/responsive-web-design-best-practices)
|
||||
- [Scrimba: Responsive Web Design 2026](https://scrimba.com/articles/responsive-web-design-a-complete-guide-2026-2/)
|
||||
- [DEV: Responsive Design Breakpoints 2025](https://dev.to/gerryleonugroho/responsive-design-breakpoints-2025-playbook-53ih)
|
||||
Reference in new issue
Block a user