1. Введение

Медиа-запросы (media queries) - это основа отзывчивого дизайна. Мы используем их для определения того, как должен меняться дизайн на основе размеров области просмотра (viewport). Но синтаксис min-width и max-width может вызывать путаницу, и в некоторых случаях вызывает проблемы макета (layout), которые трудно выявить.

Цель этой статьи - убедить вас использовать запросы диапазонов (range queries), начиная с сегодняшнего дня.

2. Проблема медиа-запросов

В следующем демо представлено типичное меню навигации. На телефоне видны только логотип и переключатель (toggle) меню. На больших экранах видна навигация, а переключатель скрыт.

Взгляните.

Соответствующие медиа-запросы:

/* Скрываем навигацию на маленьких экранах */
.nav {
  @media (max-width: 300px) {
    display: none;
  }
}

/* Скрываем переключатель на больших экранах */
.toggle {
  @media (min-width: 300px) {
    display: none;
  }
}

Проблема возникает, когда обе контрольные точки (breakpoints) достигают одинакового значения (300px). Оба элемента будут скрыты одновременно.

max-width - эквивалент <=
min-width - эквивалент >=

Вот как это выглядит:

Когда очень сосредоточен на работе, легко это пропустить, а потом потратить 45 минут на отладку.

Я тратил, поэтому знаю, насколько это неприятно. Для решения проблемы нам нужны два разных значения контрольных точек:

  • max-width: 299px - меньше или равно 299px

  • min-width: 300px - больше или равно 300px

.nav {
  @media (max-width: 299px) {
    display: none;
  }
}

.toggle {
  @media (min-width: 300px) {
    display: none;
  }
}

Теперь при ширине области просмотра 300px, навигация будет видна, а переключатель скрыт:

Как далеко это может зайти? Для одного случая это нормально. Но при наличии множества контрольных точек ситуация быстро выходит из-под контроля.

3. Диапазоны медиа-запросов

Диапазоны медиа-запросов позволяют обойтись без явного определения отступа между контрольными точками. Мы можем использовать операторы сравнения для достижения такого же результата более читаемым способом:

/* Меньше или равно 300px */
.nav {
  @media (width <= 300px) {
    display: none;
  }
}

/* Больше 300px */
.toggle {
  @media (width > 300px) {
    display: none;
  }
}

Мы видим операторы сравнения и легко понимаем логику, а не гадаем о контрольных точках на основе синтаксиса min- и max-.

Диапазоны являются частью медиа-запросов 4 уровня.

4. Преимущества диапазонов

4.1. Читаемость

Их легче читать и понимать. При взгляде на CSS мы сразу понимаем его значение. Это облегчает отладку.

4.2. Хорошая поддержка

Диапазоны поддерживаются всеми основными браузерами с марта 2023 года:

4.3. Облегчение определения диапазонов

Легче писать CSS для дизайна между двумя контрольными точками:

/* До */
.section {
  @media (min-width: 300px)  and (max-width: 500px) {
    /* стили для карточки */
  }
}

/* После */
.section {
  @media (300px <= width <= 500px) {
    /* стили для карточки */
  }
}

Визуально это можно представить так:

5. Не только медиа-запросы

Синтаксис диапазонов также можно использовать в запросах к контейнеру (container queries). Пример использования диапазонов для шапки страницы (просто используем @container вместо @media):

h1 {
  @container (width >= 300px) {
    color: #fff;
    background-color: var(--brand-1);
  }

  @container (width >= 500px) {
    background-color: hsl(from var(--brand-1) calc(h + 100) s l);
  }
}

6. Дальнейшее чтение

7. Узнать больше

Макетирование может быть непростой задачей, особенно если вы не владеете ключевой ментальной моделью макетов CSS. Вам больше не нужно об этом переживать. Я подготовил интерактивный курс по макетам CSS под названием “Маэстро макетов”.

Найти его можно здесь.

8. Заключение

Диапазоны медиа-запросов легко читаются, упрощают отладку и хорошо поддерживаются. Попробуйте их и сами убедитесь в их полезности.

Комментарии (1)


  1. Pavel-E-F
    09.05.2026 14:33

     Вы наступили на мою больную мозоль (фигурально).

    .nav {
      @media (max-width: 299px) {
        display: none;
      }
    }
    
    .toggle {
      @media (min-width: 300px) {
        display: none;
      }
    }

    Очень плохой пример. Даже показывать его нельзя.
    Ибо если ширина будет 299.5px, то что будет?
    Может лучше использовать оператор not?

    .nav {
      @media not (min-width: 300px) {
        display: none;
      }
    }
    
    .toggle {
      @media (min-width: 300px) {
        display: none;
      }
    }
    /* Меньше или равно 300px */
    .nav {
      @media (width <= 300px) {
        display: none;
      }
    }
    
    /* Больше 300px */
    .toggle {
      @media not (width <= 300px) {
        display: none;
      }
    }

    И никаких проблем.
    Есть у меня подозрение, что даже сейчас, даже современные браузеры с округлением значений в медиа запросах будут лажать. А одинаковые запросы с not на одном из них точно дадут ожидаемый результат.