Box-shadow
box-shadowдобавляет тени к элементу: внешние и внутренние, одиночные и множественные. Тени не влияют на размер и поток элемента. Также рассмотримtext-shadowдля текстовых теней.
Зачем нужно
Тени создают глубину, выделяют элементы, имитируют материальные поверхности. Карточки, кнопки, модальные окна, neumorphism — всё использует тени. Множественные тени позволяют создавать сложные визуальные эффекты.
Где используется
- Карточки (elevation)
- Кнопки (pressed/hover state)
- Модальные окна
- Neumorphism дизайн
- Фокус-индикаторы (замена outline)
- Декоративные эффекты
Предпосылки
- Цвета в CSS — цветовые форматы, прозрачность
- Border-radius — тень следует за border-radius
Базовый синтаксис
/* box-shadow: offsetX offsetY blur spread color */
.card {
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
}
/* С spread (расширение) */
.box {
box-shadow: 0 4px 12px 2px rgba(0, 0, 0, 0.15);
}
/* Inset (внутренняя тень) */
.inset {
box-shadow: inset 0 2px 4px rgba(0, 0, 0, 0.2);
}
/* Без тени */
.flat() { box-shadow: none; }
| Параметр | Описание | Обязателен? |
|---|---|---|
inset |
Внутренняя тень | Нет |
offsetX |
Горизонтальное смещение | Да |
offsetY |
Вертикальное смещение | Да |
blur |
Радиус размытия | Нет (default: 0) |
spread |
Расширение/сжатие тени | Нет (default: 0) |
color |
Цвет тени | Нет (default: currentColor) |
Множественные тени
/* Реалистичная тень — несколько слоёв */
.realistic {
box-shadow:
0 1px 2px rgba(0, 0, 0, 0.07),
0 2px 4px rgba(0, 0, 0, 0.07),
0 4px 8px rgba(0, 0, 0, 0.07),
0 8px 16px rgba(0, 0, 0, 0.07);
}
/* Мягкая тень (Material Design подход) */
.soft {
box-shadow:
0 2px 4px rgba(0, 0, 0, 0.06),
0 4px 6px rgba(0, 0, 0, 0.1);
}
Система elevation (уровни возвышения)
:root {
--shadow-sm: 0 1px 2px rgba(0, 0, 0, 0.05);
--shadow-md: 0 4px 6px -1px rgba(0, 0, 0, 0.1),
0 2px 4px -2px rgba(0, 0, 0, 0.1);
--shadow-lg: 0 10px 15px -3px rgba(0, 0, 0, 0.1),
0 4px 6px -4px rgba(0, 0, 0, 0.1);
--shadow-xl: 0 20px 25px -5px rgba(0, 0, 0, 0.1),
0 8px 10px -6px rgba(0, 0, 0, 0.1);
--shadow-2xl: 0 25px 50px -12px rgba(0, 0, 0, 0.25);
}
.card { box-shadow: var(--shadow-md); }
.card:hover { box-shadow: var(--shadow-lg); }
.dropdown { box-shadow: var(--shadow-lg); }
.modal { box-shadow: var(--shadow-2xl); }
Креативные эффекты
Neumorphism
.neumorphic {
background: #e0e5ec;
border-radius: 16px;
box-shadow:
8px 8px 16px #b8bec7,
-8px -8px 16px #ffffff;
}
.neumorphic-pressed {
background: #e0e5ec;
border-radius: 16px;
box-shadow:
inset 8px 8px 16px #b8bec7,
inset -8px -8px 16px #ffffff;
}
Цветная тень
.glow {
background: #3498db;
box-shadow: 0 8px 24px rgba(52, 152, 219, 0.5);
}
.neon {
box-shadow:
0 0 5px #3498db,
0 0 10px #3498db,
0 0 20px #3498db,
0 0 40px #3498db;
}
Одностороняя тень
/* Только нижняя тень */
.bottom-only {
box-shadow: 0 4px 8px -2px rgba(0, 0, 0, 0.1);
/* Отрицательный spread скрывает боковые стороны */
}
/* Только верхняя */
.top-only {
box-shadow: 0 -4px 8px -2px rgba(0, 0, 0, 0.1);
}
Замена outline для фокуса
button:focus-visible {
outline: none;
box-shadow: 0 0 0 3px rgba(52, 152, 219, 0.5);
/* spread без blur = ровная рамка, повторяет border-radius */
}
text-shadow
/* text-shadow: offsetX offsetY blur color */
h1 {
text-shadow: 2px 2px 4px rgba(0, 0, 0, 0.3);
}
/* Несколько теней */
.emboss {
color: #666;
text-shadow:
1px 1px 0 #fff,
-1px -1px 0 #999;
}
/* Свечение текста */
.glow-text {
color: white;
text-shadow:
0 0 10px rgba(52, 152, 219, 0.8),
0 0 20px rgba(52, 152, 219, 0.5);
}
| box-shadow | text-shadow |
|---|---|
Есть inset |
Нет inset |
Есть spread |
Нет spread |
| Тень от бокса | Тень от глифов текста |
Учитывает border-radius |
Следует форме букв |
Производительность
/* box-shadow НЕ вызывает reflow, только repaint */
/* Но анимация box-shadow дороже, чем transform */
/* МЕДЛЕННО — анимация box-shadow */
.card {
transition: box-shadow 0.3s;
}
.card:hover {
box-shadow: 0 20px 40px rgba(0, 0, 0, 0.2);
}
/* БЫСТРО — анимация через pseudo-element */
.card {
position: relative;
}
.card::after {
content: "";
position: absolute;
inset: 0;
border-radius: inherit;
box-shadow: 0 20px 40px rgba(0, 0, 0, 0.2);
opacity: 0;
transition: opacity 0.3s;
}
.card:hover::after {
opacity: 1; /* Анимируем opacity — GPU-ускорение */
}
Частые ошибки
-
Слишком тёмная/резкая тень — реалистичные тени мягкие и полупрозрачные:
/* ГРУБО */ box-shadow: 5px 5px 5px black; /* ХОРОШО */ box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1); -
Анимация box-shadow напрямую — дорого для GPU. Используйте opacity на псевдоэлементе
-
Забыт rgba/hsla для прозрачности —
box-shadow: 0 2px 8px blackслишком жёсткий -
box-shadowдля фокуса без border-radius — если элемент скруглён, box-shadow повторяет его форму (это плюс), но нужно помнить про это
Практика
- Создать систему elevation из 5 уровней теней
- Реализовать neumorphism для кнопки
- Создать hover-эффект с анимированной тенью (через pseudo-element)
- Заменить outline на
box-shadowдля:focus-visible - Создать неоновый эффект свечения
Связанные темы
- Border — границы элемента
- Border-radius — тень повторяет скругления
- Outline — альтернатива для фокуса
- transition -- плавные переходы — анимация теней