Files
wow-design-wiki/layout/sticky-feature.md
T
neo 76c4c5b4fe design-systems: add 74 brand DESIGN.md files (VoltAgent/awesome-design-md)
- 74 brands: airbnb, stripe, apple, figma, linear, vercel, etc.
- 147 files: DESIGN.md + README.md per brand (~2.1 MB)
- Each DESIGN.md contains structured brand analysis (colors, typography, components)
- Updated 00-overview.md with new design-systems directory
2026-06-21 20:40:35 +05:00

365 lines
8.4 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
---
name: layout/sticky-feature
title: Sticky Feature Section (Scroll Reveal)
description: Text scrolls while image/visual stays pinned. Classic premium pattern from Stripe, Linear, Apple.
tags: [layout, sticky, scroll, parallax, reveal, premium]
source: stripe.com, linear.app, apple.com, raycast.com
---
# Sticky Feature Section
## Что это
Секция где текст скроллится, а визуальный элемент (скриншот, видео, анимация) остаётся прилипшим (sticky). Классический паттерн Stripe.com и Apple.
## Ключевые параметры
| Параметр | Значение |
|----------|----------|
| `min-height` | `100vh` |
| `sticky top` | `0` или `100px` |
| `padding` | `128px 0` |
| `gap between text blocks` | `80–120px` |
| `scroll duration` | `100–200vh` (время просмотра) |
## Pattern 1: Stripe-Style (text left, sticky image right)
```html
<section class="feature-sticky">
<div class="feature-sticky-container">
<!-- Sticky visual -->
<div class="feature-sticky-visual">
<img src="/feature-demo.png" alt="Feature demo" loading="lazy">
</div>
<!-- Scrolling text -->
<div class="feature-sticky-texts">
<div class="feature-block">
<span class="feature-number">01</span>
<h3>Молниеносная скорость</h3>
<p>Загрузка страниц менее чем за 100мс. Оптимизированный движок, CDN по всему миру.</p>
</div>
<div class="feature-block">
<span class="feature-number">02</span>
<h3>Умная аналитика</h3>
<p>AI-анализ данных в реальном времени. Прогнозирование трендов и автоматические отчёты.</p>
</div>
<div class="feature-block">
<span class="feature-number">03</span>
<h3>Безопасность данных</h3>
<p>Шифрование end-to-end. Соответствие GDPR, PCI DSS, SOC 2 Type II.</p>
</div>
</div>
</div>
</section>
```
```css
.feature-sticky {
min-height: 100vh;
padding: 128px 0;
background: var(--color-bg);
}
.feature-sticky-container {
max-width: 1200px;
margin: 0 auto;
padding: 0 var(--space-6);
display: grid;
grid-template-columns: 1fr 1fr;
gap: var(--space-16);
align-items: start;
}
/* Sticky visual */
.feature-sticky-visual {
position: sticky;
top: 100px;
height: 500px;
border-radius: 20px;
overflow: hidden;
background: var(--color-surface);
border: 1px solid var(--color-border);
}
.feature-sticky-visual img {
width: 100%;
height: 100%;
object-fit: cover;
}
/* Scrolling text blocks */
.feature-block {
padding: 64px 0;
border-bottom: 1px solid var(--color-border);
}
.feature-block:first-child {
padding-top: 0;
}
.feature-block:last-child {
border-bottom: none;
}
.feature-number {
display: block;
font-size: 14px;
font-weight: 700;
color: var(--color-accent);
letter-spacing: 0.1em;
margin-bottom: 16px;
}
.feature-block h3 {
font-size: 2rem;
font-weight: 700;
margin-bottom: 16px;
}
.feature-block p {
font-size: 1.125rem;
color: var(--color-text-secondary);
line-height: 1.7;
max-width: 400px;
}
/* Responsive */
@media (max-width: 768px) {
.feature-sticky-container {
grid-template-columns: 1fr;
}
.feature-sticky-visual {
position: relative;
top: 0;
height: 300px;
margin-bottom: 48px;
}
}
```
## Pattern 2: Apple-Style (image center, text fades in)
```html
<section class="feature-fade">
<div class="feature-fade-visual">
<img src="/product-shot.png" alt="Product" loading="lazy">
</div>
<div class="feature-fade-texts">
<div class="feature-fade-block" data-target="1">
<h3>Тонкий дизайн</h3>
<p>Всего 6.1мм толщина.</p>
</div>
<div class="feature-fade-block" data-target="2">
<h3>Мощный чип</h3>
<p>A17 Pro — самый быстрый в смартфоне.</p>
</div>
<div class="feature-fade-block" data-target="3">
<h3>Камера 48MP</h3>
<p>Детали, которые вы не увидите.</p>
</div>
</div>
</section>
```
```css
.feature-fade {
min-height: 300vh; /* 3 экрана скролла */
position: relative;
}
.feature-fade-visual {
position: sticky;
top: 50%;
transform: translateY(-50%);
height: 70vh;
display: flex;
align-items: center;
justify-content: center;
}
.feature-fade-visual img {
max-height: 100%;
max-width: 100%;
object-fit: contain;
}
.feature-fade-block {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
text-align: center;
opacity: 0;
transition: opacity 0.3s ease;
}
.feature-fade-block.active {
opacity: 1;
}
.feature-fade-block h3 {
font-size: 3rem;
font-weight: 800;
margin-bottom: 16px;
}
.feature-fade-block p {
font-size: 1.25rem;
color: var(--color-text-secondary);
}
```
```javascript
// Intersection Observer для fade-эффекта
const blocks = document.querySelectorAll('.feature-fade-block');
const visual = document.querySelector('.feature-fade-visual');
const container = document.querySelector('.feature-fade');
if (blocks.length && container) {
const observer = new IntersectionObserver((entries) => {
entries.forEach(entry => {
blocks.forEach(block => block.classList.remove('active'));
if (entry.isIntersecting) {
entry.target.classList.add('active');
}
});
}, {
root: container,
rootMargin: '0px',
threshold: 0.5
});
blocks.forEach(block => observer.observe(block));
}
```
## Pattern 3: GSAP ScrollTrigger (scroll-based animations)
```javascript
import gsap from 'gsap';
import { ScrollTrigger } from 'gsap/ScrollTrigger';
gsap.registerPlugin(ScrollTrigger);
// Image zoom on scroll
gsap.to('.feature-sticky-visual img', {
scale: 1.1,
scrollTrigger: {
trigger: '.feature-sticky',
start: 'top bottom',
end: 'bottom top',
scrub: 1
}
});
// Text color change on scroll
gsap.utils.toArray('.feature-block').forEach((block, i) => {
gsap.from(block.querySelector('h3'), {
opacity: 0,
y: 40,
duration: 0.8,
scrollTrigger: {
trigger: block,
start: 'top 80%',
toggleActions: 'play none none reverse'
}
});
});
```
## Pattern 4: Horizontal Scroll Cards
```html
<section class="horizontal-scroll">
<div class="horizontal-scroll-track">
<div class="scroll-card">
<h3>Feature 1</h3>
<p>Description</p>
</div>
<div class="scroll-card">
<h3>Feature 2</h3>
<p>Description</p>
</div>
<div class="scroll-card">
<h3>Feature 3</h3>
<p>Description</p>
</div>
</div>
</section>
```
```css
.horizontal-scroll {
overflow: hidden;
padding: 128px 0;
}
.horizontal-scroll-track {
display: flex;
gap: 24px;
padding: 0 24px;
width: max-content;
}
.scroll-card {
min-width: 400px;
padding: 48px;
background: var(--color-surface);
border: 1px solid var(--color-border);
border-radius: 20px;
}
.scroll-card h3 {
font-size: 2rem;
font-weight: 700;
margin-bottom: 16px;
}
```
## Anti-patterns
| ❌ Плохо | ✅ Хорошо |
|----------|-----------|
| `top: 0` — прилипает к самому верху | `top: 100px` — отступ от навигации |
| `min-height: 200vh` — слишком длинно | `min-height: 100–200vh` |
| Без `position: sticky` fallback | `position: relative` на мобильных |
| Text без `max-width` | `max-width: 400px` для читаемости |
| Нет scroll-анимации | GSAP ScrollTrigger или CSS scrub |
## Mobile Considerations
```css
@media (max-width: 768px) {
/* Sticky не работает так же на мобильных */
.feature-sticky-visual {
position: relative;
top: 0;
height: 300px;
}
/* Уменьшаем секцию */
.feature-sticky {
padding: 64px 0;
}
}
```
## CV Service Validation
```bash
# Проверить UX heuristics sticky секции
curl -s -X POST http://localhost:8001/design/analyze-dom \
-H "Content-Type: application/json" \
-d '{"html": "..."}' | python3 -c "
import sys, json
d = json.load(sys.stdin)
ux = d['analyzers'].get('ux_heuristics', {})
print(f\"UX Heuristics: {ux.get('score', 'N/A')}/10\")
"
```
Ожидается: `ux_heuristics` > 6.