CSS медиазапросы: практическое руководство для начинающих с примерами

CSS медиазапросы: практическое руководство для начинающих с примерами

CSS медиазапросы: практическое руководство для начинающих с примерами

Медиазапросы (CSS Media Queries) — основа адаптивной верстки. С их помощью вы меняете стили в зависимости от ширины экрана, ориентации устройства, плотности пикселей, тёмной темы и даже предпочтений пользователя по анимациям. Ниже — практическое руководство: от синтаксиса до отладки и типичных ошибок.

Что такое медиазапросы и как они работают

Медиазапрос — это условие, при котором к стилям применяется дополнительный набор правил. Браузер проверяет условие и, если оно истинно, подключает описанные внутри стили.

/* Базовые мобильные стили (mobile-first) */
.card { padding: 16px; font-size: 16px; }

/* При ширине окна от 768px и больше — усиливаем стили */
@media (min-width: 768px) {
  .card { padding: 24px; font-size: 18px; }
}

/* Только для очень широких экранов */
@media (min-width: 1200px) {
  .card { max-width: 960px; margin: 0 auto; }
}

Мобильный-first vs Desktop-first

  • Mobile-first: пишем базовые стили для маленьких экранов, затем добавляем @media (min-width: …). Это удобнее, код короче и лучше для производительности.
  • Desktop-first: базовые стили — для больших экранов, затем сужаем через @media (max-width: …). Подходит реже, например, при переносе старых макетов.
  • /* Mobile-first (рекомендуется) */
    .btn { padding: 10px 12px; }
    @media (min-width: 768px) { .btn { padding: 12px 16px; } }
    @media (min-width: 1024px) { .btn { padding: 14px 20px; } }
    
    /* Desktop-first (альтернатива) */
    .btn { padding: 14px 20px; }
    @media (max-width: 1023px) { .btn { padding: 12px 16px; } }
    @media (max-width: 767px)  { .btn { padding: 10px 12px; } }
    

    Выбирайте брейкпоинты по контенту, а не «по моде». Типовые ориентиры: 480px, 768px, 1024px, 1280px. Но ставьте точку только там, где верстка реально «ломается».

    Диапазоны: современный синтаксис Level 4

    Новый синтаксис позволяет писать читаемые условия с диапазонами. Он уже хорошо поддерживается современными браузерами.

    /* Между 480px и 1024px включительно */
    @media (480px <= width <= 1024px) {
      .sidebar { display: none; }
    }
    
    /* Альтернатива для старых браузеров */
    @media (min-width: 480px) and (max-width: 1024px) {
      .sidebar { display: none; }
    }
    

    Полезные медиа-фичи помимо ширины

    Ориентация экрана

    /* Горизонтальная ориентация — показываем расширенное меню */
    @media (orientation: landscape) {
      .nav--desktop { display: flex; }
    }
    
    /* Вертикальная ориентация — компактная навигация */
    @media (orientation: portrait) {
      .nav--compact { display: block; }
    }
    

    Предпочтения темы: тёмная/светлая

    /* Светлая тема по умолчанию */
    body { background: #ffffff; color: #1a1a1a; }
    
    / * Тёмная, если пользователь её предпочитает * /
    @media (prefers-color-scheme: dark) {
      body { background: #0f1115; color: #e6e9ef; }
      .card { background: #171a21; border-color: #2a2f3a; }
    }
    

    Снижение анимаций для пользователей с укачиванием

    /* Базовая анимация */
    .modal[open] { animation: fade-in 200ms ease-out; }
    
    /* Уважайте предпочтение пользователя */
    @media (prefers-reduced-motion: reduce) {
      .modal[open] { animation: none; }
      * { scroll-behavior: auto; }
    }
    
    @keyframes fade-in { from { opacity: 0; } to { opacity: 1; } }
    

    Наведение и тип указателя (мышь/тач)

    /* На устройствах с точным указателем (мышь) показываем ховер-эффекты */
    @media (hover: hover) and (pointer: fine) {
      .btn:hover { transform: translateY(-1px); }
    }
    
    /* На тач-экранах увеличиваем кликабельные области */
    @media (hover: none) and (pointer: coarse) {
      .btn { padding: 14px 18px; }
    }
    

    Retina/HiDPI графика

    .hero { background: url('hero@1x.jpg') center/cover no-repeat; }
    @media (min-resolution: 2dppx) {
      .hero { background-image: url('hero@2x.jpg'); }
    }
    

    Стили для печати

    @media print {
      /* Скрываем навигацию, фоны и анимации */
      nav, .footer, .btn { display: none !important; }
      * { background: transparent !important; box-shadow: none !important; }
      body { color: #000; font-size: 12pt; }
    }
    

    Шаблон стартовой структуры

    /* 1) База (мобильные стили) */
    :root { color-scheme: light dark; }
    body { margin: 0; font: 16px/1.5 system-ui, -apple-system, Segoe UI, Roboto, sans-serif; }
    .header { padding: 16px; }
    .grid { display: grid; gap: 16px; grid-template-columns: 1fr; }
    
    /* 2) Брейкпоинт: >= 600px */
    @media (min-width: 600px) {
      .grid { grid-template-columns: repeat(2, 1fr); }
    }
    
    /* 3) Брейкпоинт: >= 900px */
    @media (min-width: 900px) {
      .header { padding: 24px 32px; }
      .grid { grid-template-columns: repeat(3, 1fr); }
    }
    
    /* 4) Предпочтения */
    @media (prefers-reduced-motion: reduce) {
      * { animation: none; transition: none; }
    }
    

    Отладка: как быстро понять, какой брейкпоинт сработал

    Удобный приём — «бейдж» активного брейкпоинта через псевдоэлемент. Он сразу покажет вам состояние прямо на странице.

    body::before {
      position: fixed; z-index: 9999; right: 8px; bottom: 8px;
      padding: 4px 8px; border-radius: 4px; font: 12px/1.2 monospace;
      background: #111; color: #fff; content: 'base';
    }
    @media (min-width: 600px) { body::before { content: '>=600'; } }
    @media (min-width: 900px) { body::before { content: '>=900'; } }
    

    Ещё: используйте режим Responsive в DevTools, проверяйте ориентацию, эмулируйте «hover: none» и «prefers-reduced-motion».

    Когда медиазапросы бессильны: контейнерные запросы

    Если нужно менять виджет в зависимости от ширины его родителя, а не окна — рассмотрите Container Queries. Короткий пример:

    /* Родителю нужен контейнер */
    .card-list { container: cards / inline-size; }
    
    /* Меняем .card, когда контейнер достаточно широкий */
    @container cards (min-width: 700px) {
      .card { display: grid; grid-template-columns: 160px 1fr; gap: 16px; }
    }
    

    Медиазапросы и контейнерные запросы отлично дополняют друг друга: первые — про окно, вторые — про блоки.

    Частые ошибки и как их избежать

  • Слишком много брейкпоинтов. Держите минимум: только там, где контент реально «ломается».
  • Смешивание min-width и max-width без системы. Выберите стратегию и следуйте ей.
  • Дублирование одинаковых правил в разных медиа. Выносите общие стили в базовый слой.
  • Пиксель-перфекционизм. Учитывайте плотность пикселей и субпиксельный рендеринг — принимайте «чуть-чуть иначе» как норму.
  • Игнорирование доступности. Добавляйте @media (prefers-reduced-motion) и корректные контрастные цвета для тёмной темы.
  • Что дальше

    Закрепить знания по адаптиву проще на практике: от сеток и типографики до продвинутых паттернов. Рекомендую пошаговую программу с упражнениями и разбором ошибок — Хочу уверенно освоить вёрстку с нуля и адаптив под реальные проекты.

    Источник

    НЕТ КОММЕНТАРИЕВ

    Оставить комментарий