Медиазапросы CSS

Язык CSS («каскадные таблицы стилей») является базовой основой для разработки современных веб-сайтов — наряду с HTML и JavaScript. CSS — это язык программирования, но он не описывает отдельные шаги, которые вы предпринимаете для решения проблемы. Вместо этого определяется цель, которая должна быть достигнута. Это делает CSS декларативным языком, похожим на SQL.

Частью CSS являются так называемые медиазапросы, которые запрашивают свойства устройства вывода. Они используются для отзывчивого веб-дизайна. Так как же именно это работает?

Что такое медиазапросы CSS?

Медиазапросы CSS были введены вместе с распространением спецификации CSS3. Медиазапрос связывает назначение CSS-свойств элемента с одним или несколькими условиями среды. В простейшей форме делается различие между носителями, на которых представлена информация — например, на экране, на печатной странице (PDF) или в виде текста:

Носитель Пояснение
все Любой носитель вывода
экран Представление содержимого веб-сайта на прокручивающемся экране
печать Представление содержимого сайта на нескольких страницах с фиксированными размерами
речь Чтение содержимого сайта с помощью синтезатора речи

Медиазапрос CSS определяется в блоке кода CSS с помощью специального правила «@ media». Содержащиеся в нем селекторы и правила CSS активируются только при указанном условии. Это означает, что вы можете скрыть не отображаемые элементы при печати страницы:

/* Hide non-displayable elements */
@media print {
  video, audio {
    display: none;
  }
}

Помимо используемого носителя, медиазапросы CSS могут использоваться для запроса определенных свойств соответствующего носителя. Таким образом, CSS Media Queries — это центральный технический элемент, обеспечивающий отзывчивый веб-дизайн в первую очередь.

CSS Media Queries как центральный элемент управления для отзывчивого веб-дизайна

Отзывчивый веб-дизайн направлен на то, чтобы как можно лучше адаптировать веб-сайт к устройству, на котором он просматривается. Медиазапросы используются для запроса различных свойств устройства отображения, так называемых медиахарактеристик. Это позволяет установить правила стиля для различных размеров экрана. Кроме того, можно определить оптимизированные правила стиля, если мобильное устройство наклонено.

Ниже приведен обзор медиафункций, наиболее часто используемых в отзывчивом дизайне:

Медиафункция Объяснение
width Запрос ширины экрана в пикселях
высота Запрос высоты экрана в пикселях
ориентация Определение ориентации экрана портрет/ландшафт
разрешение Определить доступное разрешение экрана

Давайте рассмотрим несколько примеров. Представьте себе основной заголовок для веб-сайта. В HTML он обозначается как «h1». Сначала мы определяем правила стиля для элемента h1 независимо от устройства, на котором он отображается:

h1 {
	font-size: 24px;
	line-height: 1.25;
}

Далее мы определяем медиазапрос, который запрашивает ширину экрана. Внутри запроса мы определяем правила стиля, которые должны применяться к заголовку в зависимости от ширины. В приведенном ниже примере мы хотим увеличить размер шрифта заголовка h1 на экранах шириной не менее 1024 пикселей:

@media screen and (min-width: 1024px) {
	h1 {
		font-size: 36px;
	}
}

Обратите внимание, что мы изменяем только свойство «font-size» заголовка h1. Межстрочный интервал определяется как относительная единица с помощью свойства «line-height» и наследуется — поскольку он явно не перезаписывается. В данном примере межстрочный интервал элемента h1 в базовом состоянии составляет 24px * 1.25 = 30px. На экранах с шириной 1 024 пикселей и более межстрочный интервал пропорционально составляет 36px * 1.25 = 45px.

В «CSS» смешение существующих и вновь определенных стилевых правил выражается словом «каскадный»: элемент наследует стилевые правила от родительских элементов или общие правила, которые были предварительно определены. Обычно вы определяете основные свойства элементов, а затем выборочно перезаписываете свойства при определенных условиях.

Давайте рассмотрим другой пример. Представьте, что мы хотим отобразить три элемента в контейнере. Элементы должны отображаться один под другим на экране мобильного устройства, когда оно находится в вертикальном положении. При наклоне устройства в альбомный формат макет должен переключиться так, чтобы элементы отображались рядом друг с другом. С помощью модуля Flexbox Layout и CSS Media Query, который запрашивает выравнивание устройства, макет можно реализовать с помощью нескольких строк HTML и CSS. Сначала мы определяем контейнер и элементы, которые он содержит, в HTML:

<div class="container">
  <div class="element">…</div>
  <div class="element">…</div>
  <div class="element">…</div>
</div>

Мы также задаем следующие правила CSS. Мы устанавливаем свойство «display: flex» в контейнере и условно регулируем свойство «flex-direction» для него с помощью CSS Media Query. Если устройство удерживается в альбомном формате, элементы отображаются в ряд рядом друг с другом. Если устройство используется в портретном формате, элементы располагаются в линию один под другим:

.container {
	display: flex;
}
/* Landscape format */
@media screen and (orientation: landscape) {
	.container {
		flex-direction: row;
	}
}
/* Horizontal format */
@media screen and (orientation: portrait) {
	.container {
		flex-direction: column;
	}
}

Помимо размеров экрана и выравнивания устройства, мы также можем запросить физическое разрешение экрана с помощью медиазапроса. Это представляет особый интерес для отображения пикселированных изображений. В качестве примера представьте логотип, доступный в двух версиях — оптимизированной для экранов с низким и высоким разрешением. Простой прием для отображения подходящего логотипа для каждого из них — поместить на страницу оба варианта. Мы используем CSS Media Query для запроса разрешения экрана и скрываем версию, которая не требуется, с помощью «display: none». Следующий код показывает, как это может выглядеть в коде HTML и CSS:

<!--—Image in high resolution ---->
<img class="logo--high-res" src="/img/logo-high-res.png" alt="Logo in high resolution">
<!--—Image in low resolution ---->
<img class="logo--low-res" src="/img/logo-low-res.png" alt="Logo in low resolution">
/* Hide high resolution image on low resolution screen */
@media (max-resolution: 149dpi) {
	.logo--high-res {
		display: none;
	}
}
/* Hide low resolution image on high resolution screen */
@media (min-resolution: 150dpi) {
	.logo--low-res {
		display: none;
	}
}
Совет

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

Активация переменной области просмотра для отзывчивого дизайна

Ранее мы говорили об «экране» в связи с доступной шириной среды вывода. Это концептуально правильно, но технически не совсем так. Браузер оперирует понятием «область просмотра». Чтобы ширина области просмотра соответствовала ширине экрана, в «<head>» HTML-документа требуется спецификация «meta-viewport». Без этой информации страница будет отображаться на мобильных устройствах так же, как и на настольных, только сильно уменьшится в размерах.

<head>
  <!—Activate CSS Media Queries -->
  <meta name="viewport" content="width=device-width, initial-scale=1">
</head>

Понимание блоков CSS для отзывчивого веб-дизайна

При отзывчивом веб-дизайне элементы должны адаптироваться к существующему экрану. Часто речь идет об определении размеров элементов при различных условиях. В спецификации CSS определены различные единицы измерения, самой простой из которых является пиксель. Например, изображение 1080p имеет размеры 1 920 пикселей в ширину на 1 080 пикселей в высоту.

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

Ниже мы определяем изображение в HTML с помощью тега «<img>»:

<img class="img-1080p" src="/image-1080p.png">

С помощью CSS мы фиксируем ширину до 1 920 пикселей:

.img-1080p {
	width: 1920px;
}

В этом сценарии лучше использовать относительную единицу измерения вместо пикселей. На заре табличной верстки в CSS в качестве относительной единицы используется процент. Если мы зададим ширину изображения в «100%» с помощью CSS, изображение плавно адаптируется к доступному пространству. Это работает потому, что проценты всегда относятся к охватывающему элементу.

img {
	width: 100%;
}

Теперь мы ближе к нашей цели — адаптировать ширину изображения к доступному пространству. Однако мы создали новую проблему: на экране, ширина которого превышает 1 920 пикселей, изображение отображается увеличенным и, следовательно, пикселированным. Поэтому мы также должны ограничить максимальную ширину изображения его реальными размерами в пикселях:

.img-1080p {
	/* implicitly inherited from `img` */
	/* width: 100%; */
	max-width: 1920px;
}

Помимо пикселей и процентов, CSS понимает еще несколько единиц измерения. Относительные единицы em, rem и vw, vh полезны для отзывчивого дизайна. В таблице ниже приведен краткий обзор распространенных единиц CSS для отзывчивого дизайна:

Единица CSS Использование
Rem Размер шрифта основного текста, «максимальная ширина» элементов макета; «ширина» элементов
% «Ширина» изображений и элементов макета, возможно ограничена «max-width»
vw, vh Размер шрифта заголовков, текстов героев, размеры элементов заполнения экрана
Em Определение точек разрыва, «максимальная ширина» элементов макета
Px Определение точек разрыва, «максимальной ширины» изображений

Понимание расширенных медиазапросов

В дополнение к простым медиазапросам можно составлять сложные медиазапросы CSS. Для этого полезны логические операторы «and», «or» и «not». Вот пример сложного запроса:

@media screen and (min-width: 30em) and (orientation: landscape) { /* … */ }

В дополнение к уже существующим медиафункциям, которые можно запросить с помощью CSS Media Query, в будущих версиях CSS планируется реализовать несколько интересных функций. Например, спецификация «CSS Media Queries Level 5» (CSS5) включает следующие новые параметры запроса (среди прочих):

Media Feature Объяснение
уровень освещенности Определяет яркость окружающей среды
prefers-color-scheme Выбор светлой или темной цветовой схемы
prefers-contrast Выбрать высококонтрастный режим

С запуском CSS5 ожидается добавление контейнерных запросов. С их помощью впервые можно будет связать правила стиля элементов со свойствами окружающего их контейнера. Это означает, что контейнерные запросы противопоставляются CSS Media Queries, которые запрашивают глобальные свойства отображаемого устройства. Использование контейнерных запросов позволит обрабатывать особые случаи, для которых ранее использовался JavaScript или сложные медиа-запросы.

Понимание точек останова CSS

В связи с отзывчивым веб-дизайном и медиазапросами CSS часто используются «точки останова». Точка останова — это определенная ширина экрана, для которой активируется набор правил CSS, определенный медиазапросом CSS. Вы можете визуализировать точки останова на сайте, открыв инструменты разработчика в браузере. Если активен отзывчивый вид, точки останова отображаются в виде цветных полос над реальным сайтом.

Понимание mobile-first, CSS-процессоров и фреймворков CSS-утилит

Одной из признанных лучших практик отзывчивого веб-дизайна является подход mobile-first. Когда веб-дизайн и разработка следуют этому подходу, сначала задаются спецификации стилей для самых маленьких экранов. Эти определения составляют основу дизайна. На их основе устанавливаются несколько точек разрыва для последовательно увеличивающихся размеров экрана. Новые правила стиля для элементов выборочно определяются в пределах точек останова, тем самым переписывая существующие правила для меньших экранов.

Подход, ориентированный на мобильные устройства, легко понять, взглянув на утилиту CSS «Tachyons». По умолчанию он определяет три точки останова: «не маленький», «средний» и «большой»:

/* Tachyons breakpoints */
/* 'not-small' breakpoint */
@media screen and (min-width: 30em) { /* … */ }
/* 'medium' breakpoint */
@media screen and (min-width: 30em) and (max-width: 60em) { /* … */ }
/* 'large' breakpoint */
@media screen and (min-width: 60em)  { /* … */ }

Обратите внимание, что, следуя подходу mobile-first, нет отдельной «маленькой» точки останова. Детали для маленьких устройств просто определяются без точки останова.

Точка останова Tachyons Объяснение
not-small Включает ширину экрана, соответствующую точкам останова «средний» и «большой»
средний Охватывает ширину экрана между точками останова «не маленький» и «большой»
большой Включает только большие экраны

Правила стиля для элементов определяются в пределах точек останова, и их отображение адаптируется к различным размерам экрана. Вы можете заметить, что централизация кодовой базы CSS веб-проекта проблематична. Обычно предпочтительнее собирать все CSS-свойства элемента в отдельном файле.

Понимание пре- и постпроцессоров CSS

Для модулизации CSS-кода проекта изначально использовались различные пре-процессоры CSS. Возможно, вы уже знакомы с языками Sass, Less или Stylus. В Node.js проекте PostCSS позже был добавлен постпроцессор CSS. Все упомянутые технологии позволяют заключать CSS Media Queries под CSS-селектором. Таким образом, правила стиля элемента могут быть определены коллективно для всех медиа условий. Вот пример с использованием стилуса:

Файл стилуса «text.styl» для свойств текста:

// Mobile-first definitions
p
  font-size: 16px

  // Definitions for 'not-small' breakpoint
  @media screen and (min-width: 30em)
    font-size: 18px

Файл стилуса ‘link.styl’ для свойств ссылок:

// Mobile-first definitions
a
  color: blue

  // Definitions for 'not-small' breakpoint
  @media screen and (min-width: 30em)
    text-decoration: underline

Препроцессор stylus переводит эти файлы в CSS и собирает правила CSS Media Query с отступами в одной точке останова. Показанный код stylus преобразуется в следующий код CSS:

/* Mobile-first definitions */
p {
  font-size: 16px;
}
a {
  color: blue;
}

/* Definitions for 'not-small' breakpoint */
@media screen and (min-width: 30em) {
  p {
    font-size: 18px;
  }
  a {
    text-decoration: underline;
  }
}

Понимание утилит CSS

Инкапсуляция CSS Media Queries в стилевые правила элемента и их обработка с помощью CSS-процессора работает, но это заставляет разработчика переключаться туда-сюда между HTML и CSS. Кроме того, им приходится присваивать уникальные имена классов элементам в HTML. Это приводит к нежелательной сложности. Именно здесь на помощь приходят фреймворки утилит CSS.

Система утилит CSS связывает атомарные свойства CSS с точками останова. Полученные CSS-классы могут быть назначены любому элементу HTML. Это позволяет определять отзывчивые макеты и компоненты только в HTML, без необходимости писать код CSS. Использование утилит CSS позволяет быстро создавать прототипы и идеально подходит для разработки компонентов. Поэтому фреймворки утилит CSS часто используются в сочетании с компонентно-ориентированными технологиями, такими как React и Vue.

Рассмотрим еще один пример, заимствованный из фреймворка утилит CSS Tachyon. Посмотрите на следующий код CSS. Во-первых, мы определяем классы «mw1» — «mw3», которые ограничивают максимальную ширину любого элемента значениями от «1rem» до «3rem». Кроме того, в рамках уже введенных точек разрыва «medium» и «large» мы определяем соответствующие CSS-классы, названия которых содержат сокращенные точки разрыва:

/* Tachyons */

/* Mobile-first size */
.mw1  {  max-width: 1rem; }
.mw2  {  max-width: 2rem; }
.mw3  {  max-width: 3rem; }

/* 'medium' breakpoint */
@media screen and (min-width: 30em) and (max-width: 60em) {
  .mw1-m  {  max-width: 1rem; }
  .mw2-m  {  max-width: 2rem; }
  .mw3-m  {  max-width: 3rem; }
}

/* 'large' breakpoint */
@media screen and (min-width: 60em) {
  .mw1-l  {  max-width: 1rem; }
  .mw2-l  {  max-width: 2rem; }
  .mw3-l  {  max-width: 3rem; }
}

Используя эти CSS-классы, мы можем писать отзывчивые элементы полностью в HTML. Следующий фрагмент HTML-кода определяет изображение, которое имеет максимальную ширину «1rem» на маленьких экранах. Изображение автоматически адаптируется к доступной ширине экрана. На экранах среднего размера элемент занимает максимум «2rem», на больших экранах — максимум «3rem».

<img class="mw1 mw2-m mw3-l" src="/image.png" alt="A responsive image">

Утилиты CSS определяют множество атомарных классов, причем каждый класс определяет только одно свойство CSS. Помимо размеров элемента, сюда входит информация о типографике, цвете и всех других возможных свойствах. Для каждого атомарного свойства система утилит CSS содержит классы для каждой определенной точки разрыва. Комбинируя несколько классов, можно собрать практически любые отзывчивые элементы.

Фреймворку Tachyons уже несколько лет, и он больше не находится в активной разработке. Однако, благодаря своей простоте, Tachyons по-прежнему является отличным способом изучения отзывчивого веб-дизайна. Самый простой способ понять подход — посмотреть на компоненты Tachyons. Это примеры элементов, которые полностью определены с помощью классов утилит.

Преемником Tachyons является TailwindCSS. TailwindCSS имеет ряд преимуществ перед Tachyons. Проект продолжает активно развиваться и поддерживает многие популярные системы для разработки внешнего интерфейса. Кроме того, TailwindCSS может быть полностью адаптирован к соответствующим потребностям проекта. Все предварительные настройки, такие как точки останова, шкала размера шрифта и т.д., могут быть легко сконфигурированы.

Несмотря на практичность работы с утилитами CSS, такой подход имеет один существенный недостаток: для определения одного элемента может потребоваться множество атомарных классов. Исходный файл CSS по умолчанию содержит классы для всех комбинаций значений свойств CSS и точек останова. В случае TailwindCSS это тысячи классов, что означает, что файл CSS в несжатом состоянии может увеличиться до размера в несколько мегабайт — неприемлемый размер с точки зрения производительности.

К счастью, TailwindCSS решает эту проблему двумя способами. С одной стороны, фреймворк понимает инструкцию «@ apply», которая используется для объединения многократно используемых комбинаций классов утилит под новым именем класса. С другой стороны, TailwindCSS поддерживает инструмент PurgeCSS. Он используется как часть процесса сборки для удаления любых неиспользуемых классов утилит из производственной сборки. PurgeCSS обрабатывает HTML-шаблоны проекта и включает только классы CSS, найденные в сгенерированном файле исходного текста CSS. Это уменьшает размер исходного текстового файла до приемлемого уровня.

Оцените статью
cdelat.ru
Добавить комментарий