Как реализовать responsive-дизайн в CSS?
Вопрос
Как устроен адаптивный (responsive) дизайн в CSS: что такое медиазапросы, чем отличается mobile-first подход от desktop-first, и какие единицы измерения для этого используются?
Короткий ответ
Responsive-дизайн строится на медиазапросах (@media), которые применяют разные стили в зависимости от характеристик viewport, и на относительных единицах измерения, которые сами масштабируются под контекст. Mobile-first означает, что базовые стили пишутся под маленький экран, а медиазапросы min-width добавляют/переопределяют стили для больших экранов.
Подробный ответ
Медиазапросы (@media) позволяют применять блок CSS-правил только при выполнении условий: ширина viewport, ориентация, тип устройства, prefers-color-scheme и т.д. Чаще всего используются брейкпоинты по ширине: @media (min-width: 768px) { ... }.
Mobile-first vs desktop-first:
- Mobile-first — базовые (не обёрнутые в медиазапрос) стили пишутся для самого маленького экрана, а дальше через
min-widthдобавляются стили для больших экранов, постепенно "достраивая" макет. Это соответствует принципу прогрессивного улучшения: мобильный CSS проще и легче, а сложные многоколоночные раскладки — это надстройка поверх базы. - Desktop-first — обратный подход: базовые стили под десктоп, а
max-widthмедиазапросы упрощают макет для меньших экранов. Часто приводит к более тяжёлому и запутанному CSS, так как приходится "отменять" десктопные стили.
В современной практике mobile-first считается предпочтительным: он лучше соответствует приоритету производительности на мобильных устройствах и естественному потоку блочных элементов (которые по умолчанию складываются в колонку, что и нужно на маленьком экране).
Относительные единицы для адаптивности:
%— относительно родителя.em— относительноfont-sizeтекущего элемента (или родителя для не-font свойств).rem— относительноfont-sizeкорневого элемента (html), удобен тем, что не накапливает эффект вложенности какem.vw/vh— относительно ширины/высоты viewport.clamp()— функция, задающая значение с минимумом, предпочтительным (обычно воvw) и максимумом, что позволяет плавно масштабировать без медиазапросов вовсе.
Пример
/* mobile-first: базовые стили под маленький экран */
.grid {
display: grid;
grid-template-columns: 1fr;
gap: 12px;
padding: 16px;
}
.title {
font-size: clamp(1.25rem, 4vw + 0.5rem, 2.5rem);
}
/* планшет и выше */
@media (min-width: 768px) {
.grid {
grid-template-columns: repeat(2, 1fr);
gap: 20px;
}
}
/* десктоп и выше */
@media (min-width: 1200px) {
.grid {
grid-template-columns: repeat(3, 1fr);
padding: 32px;
}
}
Дополнительные вопросы
- Почему mobile-first обычно даёт более компактный итоговый CSS?
- Чем
clamp()может заменить набор медиазапросов для типографики? - Как container queries (
@container) меняют подход к адаптивности по сравнению с@media?