215 lines
6.5 KiB
Markdown
215 lines
6.5 KiB
Markdown
---
|
||
name: layout/bento-grid
|
||
title: Bento Grid Layout
|
||
description: Asymmetric grid layout inspired by Apple's design language. Cards of varying sizes in a cohesive grid.
|
||
tags: [layout, grid, asymmetric, bento, cards]
|
||
source: apple.com, linear.app, raycast.com, godly.website
|
||
---
|
||
|
||
# Bento Grid Layout
|
||
|
||
## Что это
|
||
Сетка карточек разного размера, объединённых общим стилем. Вдохновлена дизайном Apple и Linear. Каждый блок — самостоятельная единица, но вместе они создают целостную композицию.
|
||
|
||
## Ключевые характеристики
|
||
|
||
| Параметр | Значение |
|
||
|----------|----------|
|
||
| `gap` | `16–24px` |
|
||
| `grid-template-columns` | `repeat(auto-fit, minmax(280px, 1fr))` |
|
||
| `border-radius` | `16–24px` (большой радиус) |
|
||
| `padding` | `32–48px` внутри карточек |
|
||
| `border` | `1px solid rgba(255,255,255,0.06)` |
|
||
| `background` | `rgba(255,255,255,0.02)` или `#111` |
|
||
|
||
## Шаблоны раскладок
|
||
|
||
### 2x2 Balanced (4 карточки)
|
||
```
|
||
┌─────────────┬─────────────┐
|
||
│ Card 1 │ Card 2 │
|
||
│ (wide) │ (wide) │
|
||
├─────────────┴─────────────┤
|
||
│ Card 3 │ Card 4 │ │
|
||
│ (tall) │ (tall) │ │
|
||
└─────────────┴─────────────┘
|
||
```
|
||
|
||
### 3-2-1 Asymmetric
|
||
```
|
||
┌────────────┬────────────┬────────────┐
|
||
│ │ Card 2 │ │
|
||
│ Card 1 ├────────────┤ Card 3 │
|
||
│ (tall) │ Card 4 │ (tall) │
|
||
│ ├────────────┤ (tall) │
|
||
│ │ Card 5 │ │
|
||
└────────────┴────────────┴────────────┘
|
||
```
|
||
|
||
### Hero Bento (featured card + smaller)
|
||
```
|
||
┌────────────────────┬────────────┐
|
||
│ │ │
|
||
│ Card 1 (featured) │ Card 2 │
|
||
│ span 2 cols │ │
|
||
│ ├────────────┤
|
||
│ │ Card 3 │
|
||
└────────────────────┴────────────┘
|
||
```
|
||
|
||
## Реализация
|
||
|
||
```html
|
||
<section class="bento-section">
|
||
<div class="bento-grid">
|
||
<!-- Featured card: spans 2 columns -->
|
||
<div class="bento-card featured">
|
||
<span class="bento-label">01</span>
|
||
<h3>Заголовок карточки</h3>
|
||
<p>Описание...</p>
|
||
<div class="bento-visual">
|
||
<!-- Визуальный элемент, скриншот, иконка -->
|
||
</div>
|
||
</div>
|
||
|
||
<!-- Standard cards -->
|
||
<div class="bento-card">
|
||
<span class="bento-label">02</span>
|
||
<h3>Заголовок</h3>
|
||
<p>Описание...</p>
|
||
</div>
|
||
|
||
<div class="bento-card">
|
||
<span class="bento-label">03</span>
|
||
<h3>Заголовок</h3>
|
||
<p>Описание...</p>
|
||
</div>
|
||
|
||
<div class="bento-card">
|
||
<span class="bento-label">04</span>
|
||
<h3>Заголовок</h3>
|
||
<p>Описание...</p>
|
||
</div>
|
||
</div>
|
||
</section>
|
||
```
|
||
|
||
```css
|
||
.bento-grid {
|
||
display: grid;
|
||
grid-template-columns: repeat(3, 1fr);
|
||
gap: 16px;
|
||
}
|
||
|
||
.bento-card {
|
||
background: rgba(255, 255, 255, 0.03);
|
||
border: 1px solid rgba(255, 255, 255, 0.06);
|
||
border-radius: 20px;
|
||
padding: 32px;
|
||
transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
|
||
position: relative;
|
||
overflow: hidden;
|
||
}
|
||
|
||
.bento-card:hover {
|
||
border-color: rgba(255, 255, 255, 0.12);
|
||
background: rgba(255, 255, 255, 0.05);
|
||
transform: translateY(-2px);
|
||
}
|
||
|
||
/* Featured card: spans 2 columns */
|
||
.bento-card.featured {
|
||
grid-column: span 2;
|
||
}
|
||
|
||
/* Tall card: spans 2 rows (requires grid-template-rows) */
|
||
.bento-card.tall {
|
||
grid-row: span 2;
|
||
}
|
||
|
||
.bento-label {
|
||
display: inline-block;
|
||
font-size: 12px;
|
||
font-weight: 600;
|
||
color: rgba(255, 255, 255, 0.3);
|
||
letter-spacing: 0.1em;
|
||
margin-bottom: 16px;
|
||
}
|
||
|
||
.bento-card h3 {
|
||
font-size: 1.5rem;
|
||
font-weight: 700;
|
||
margin-bottom: 8px;
|
||
}
|
||
|
||
.bento-card p {
|
||
color: rgba(255, 255, 255, 0.6);
|
||
font-size: 0.95rem;
|
||
line-height: 1.6;
|
||
}
|
||
```
|
||
|
||
## CSS Grid Layouts
|
||
|
||
### 3-column Bento
|
||
```css
|
||
.bento-grid-3col {
|
||
display: grid;
|
||
grid-template-columns: repeat(3, 1fr);
|
||
grid-auto-rows: minmax(200px, auto);
|
||
gap: 16px;
|
||
}
|
||
```
|
||
|
||
### 4-column Bento
|
||
```css
|
||
.bento-grid-4col {
|
||
display: grid;
|
||
grid-template-columns: repeat(4, 1fr);
|
||
grid-auto-rows: minmax(180px, auto);
|
||
gap: 16px;
|
||
}
|
||
```
|
||
|
||
### Responsive Bento
|
||
```css
|
||
@media (max-width: 768px) {
|
||
.bento-grid {
|
||
grid-template-columns: 1fr;
|
||
}
|
||
.bento-card.featured {
|
||
grid-column: span 1;
|
||
}
|
||
}
|
||
```
|
||
|
||
## Визуальные элементы внутри Bento
|
||
|
||
1. **Скриншоты продукта** — внутри карточки, с `border-radius: 12px` и `box-shadow`
|
||
2. **Иконки/эмодзи** — крупные (48–64px), слева или сверху
|
||
3. **Градиентные фоны** — `radial-gradient` для создания глубины
|
||
4. **Анимированные элементы** — простые CSS-анимации для привлечения внимания
|
||
5. **Цифры** — крупные цифры (48–72px) для метрик
|
||
|
||
## Anti-patterns
|
||
|
||
| ❌ Плохо | ✅ Хорошо |
|
||
|----------|-----------|
|
||
| Все карточки одинакового размера | 1–2 featured + обычные |
|
||
| `gap: 8px` — слишком тесно | `gap: 16–24px` |
|
||
| `border-radius: 8px` — квадратный | `border-radius: 16–24px` |
|
||
| Белый фон карточек на светлом фоне | Полупрозрачный на тёмном фоне |
|
||
| Без hover-эффектов | Hover: lift + border glow |
|
||
|
||
## CV Service Validation
|
||
|
||
```bash
|
||
# Проверить grid adherence
|
||
curl -s -X POST http://localhost:8001/design/analyze-dom \
|
||
-H "Content-Type: application/json" \
|
||
-d '{"html": "...", "full_analysis": false}' | \
|
||
python3 -c "import sys,json; d=json.load(sys.stdin); print(f\"Grid: {d['analyzers'].get('design_tokens',{}).get('score','N/A')}\")"
|
||
```
|
||
|
||
Ожидается: `grid_adherence` > 6 (cv-service меряет по регулярности gap и выравниванию).
|