Книга: HTML5 и CSS3. Разработка сайтов для любых браузеров и устройств. 2-е изд.
Назад: 1. Основы адаптивного веб-дизайна
Дальше: 3. Динамически изменяемые разметки и адаптивные изображения

2. Медиазапросы — поддержка различных окон просмотра

В предыдущей главе был дан краткий обзор основных компонентов адаптивной веб-страницы: подстраиваемой разметки, подстраиваемых изображений и медиазапросов.

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

В этой главе нам предстоит:

узнать, зачем медиазапросы нужны в адаптивном веб-дизайне;

• разобраться с синтаксисом медиазапросов;

• научиться использовать медиазапросы в тегах link с CSS-инструкциями @import и внутри самих файлов CSS;

• разобраться с тем, какие именно свойства устройств поддаются тестированию;

• воспользоваться медиазапросами для обеспечения визуальных изменений в зависимости от доступного пространства экрана;

• решить вопрос о том, нужно ли группировать медиазапросы или записывать их по мере необходимости там, где это потребуется;

• разобраться в том, что представляет собой метатег viewport, позволяющий медиазапросам работать надлежащим образом на устройствах под управлением iOS и Android;

• рассмотреть возможности, которые будут предложены в будущих спецификациях медиазапросов.

Спецификация CSS3 состоит из нескольких модулей. Одним из таких модулей является Media Queries (Level 3). Медиазапросы позволяют нам определить целевое назначение конкретных CSS-стилей в зависимости от возможностей устройства. Например, с помощью всего лишь нескольких строк кода CSS мы можем изменить способ отображения содержимого в зависимости от таких параметров, как ширина окна просмотра, соотношение сторон экрана, ориентация экрана (альбомная или портретная) и т. д.

Медиазапросы получили довольно широкую реализацию. Их поддерживают практически все браузеры, кроме самых ранних версий Internet Explorer (8 и ниже). Короче говоря, не существует абсолютно никаких причин для того, чтобы не пользоваться ими!

Sovet.tif совет

Спецификации в W3C проходят через процесс ратификации. Если выдастся свободный денек, не поленитесь ознакомиться с официальным объяснением этого процесса по адресу 51014/tr. Простейшая версия состоит в том, что спецификация начинается с рабочего проекта (Working Draft (WD)), проходит стадии кандидата в рекомендации (Candidate Recommendation (CR)), предложения в рекомендации (Proposed Recommendation (PR)) и, наконец, спустя много лет добирается до рекомендации (W3C Recommendation (REC)). Как правило, безопаснее использовать модули, находящиеся на более высоком уровне становления. Например, CSS Transforms Module Level 3 (/) пребывал в статусе WD с марта 2009 года, а его поддержка со стороны браузеров была гораздо скуднее, чем поддержка модулей, пребывающих в статусе CR, например, медиазапросов.

Зачем в адаптивном веб-дизайне нужны медиазапросы

Медиазапросы CSS3 позволяют нацеливать конкретные CSS-стили на определенные возможности устройств или возникающие ситуации. Если углубиться в W3C-спецификацию, относящуюся к модулю медиазапросов CSS3 (/), можно увидеть их следующее официальное представление:

«Медиазапрос состоит из типа среды и выражений в количестве от нуля и более, которые ведут проверку условий конкретных медиасвойств. К медиасвойствам, используемым в медиа­запросах, относятся ширина —'width', высота — 'height' и цвет — 'color'. За счет использования медиазапросов представления без изменения своего содержимого могут быть привязаны к конкретному диапазону устройств вывода информации».

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

Хотя подстраиваемая разметка может справляться с выдерживанием определенного дизайна в довольно широком диапазоне изменений с учетом всего диапазона размеров экрана, который мы надеемся охватить, бывают случаи, когда требуется более глубокий пересмотр разметки. Возможности такого пересмотра дают медиазапросы. Их нужно рассматривать в качестве основной условной логики для CSS.

Основная условная логика в CSS. Во всех настоящих языках программирования имеются средства, благодаря применению которых обслуживается одна или несколько возможных ситуаций. Обычно такие средства существуют в виде условной логики, примером которой может послужить инструкция if else.

Если выражения, характерные для программирования, непривычны вашему глазу, не волнуйтесь: данная концепция довольно проста. Наверняка вы используете условную логику, когда в кафе просите друга заказать себе что-нибудь: «Если у них есть тройные шоколадные кексы, то я бы взял один, а если нет, то я бы не отказался от кусочка морковного пирога». Это простая условная инструкция с двумя возможными результатами, которых в данном случае вполне достаточно.

Когда я работал над этой книгой, в CSS еще не было возможности использования настоящей условной логики или свойств, присущих программированию. Циклы, функции, итерации и сложные математические вычисления все еще не вышли за пределы прерогативы CSS-процессоров (не помню, упоминал ли я о прекрасной книге на тему препроцессора Sass, которая называется Sass and Compass for Designers?). И тем не менее медиазапросы являются одним из механизмов CSS, позволяющих нам создавать основную условную логику. В том случае, когда при использовании медиазапроса складываются конкретно оговоренные в нем условия, в область видимости попадают именно те стили, которые в нем объявляются.

Primechanie.tif Пути создания возможностей программирования

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

Но поддержка со стороны браузеров ограничивается Firefox, поэтому в настоящее время об их повсеместном использовании не может быть и речи.

Синтаксис медиазапроса

Так как же выглядят медиазапросы и, что более важно, как они работают?

Введите в конце любого файла CSS следующий код и посмотрите на связанную с ним веб-страницу. Как вариант, можете открыть пример из файла каталога example_02-01:

body {

    background-color: grey;

}

@media screen and (min-width: 320px) {

    body {

        background-color: green;

    }

}

@media screen and (min-width: 550px) {

    body {

        background-color: yellow;

    }

}

@media screen and (min-width: 768px) {

    body {

        background-color: orange;

    }

}

@media screen and (min-width: 960px) {

    body {

        background-color: red;

    }

}

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

Медиазапросы в тегах link. Все, кому приходилось работать с CSS, начиная со второй версии (Version 2), знают о возможности указывать тип устройства (например, screen или print) применительно к таблице стилей с атрибутом media тега <link>. Рассмотрим следующий пример, который следует помещать в теги <head> своей разметки:

<link rel="style sheet" type="text/css" media="screen" href="screen-

styles.css">

Медиазапросы добавляют к возможности простого указания типа устройства возможность указания целевого назначения стилей на основе возможностей или характерных особенностей устройства. Их нужно рассматривать в качестве вопросов к браузеру. Если браузер даст положительный ответ, применяются стили, заключенные в медиазапрос. Если ответ будет отрицательным, эти стили применяться не будут. Вместо того чтобы просто спросить: «Это экран?» — все, что по максимуму можно сделать, используя только CSS2, — медиазапросы задают более сложные вопросы. С их помощью можно спросить: «Экран ли это и просматривается ли он в портретной ориентации?» Рассмотрим соответствующий пример:

<link rel="stylesheet" media="screen and (orientation: portrait)"

href="portrait-screen.css" />

Сначала с помощью выражения медиазапроса задается вопрос о типе (экран ли это?), а затем о свойстве (находится ли экран в портретной ориентации?). Таблица стилей portrait-screen.css будет применяться для любого экранного устройства с портретной ориентацией и игнорироваться для любых других вариантов устройств и свойств. Логику любого выражения медиазапроса можно поменять на противоположную, добавляя вначале отрицание not. Например, результат нашего предыдущего примера будет прямо противоположным, и файл с таблицей стилей будет применяться для всего, что не является экраном с портретной ориентацией:

<link rel="stylesheet" media="not screen and (orientation: portrait)"

href="portrait-screen.css" />

Объединение медиазапросов

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

<link rel="stylesheet" media="screen and (orientation: portrait) and

(min-width: 800px)" href="800wide-portrait-screen.css" />

К тому же у нас может быть список медиазапросов. Файл будет применен, если будет получен положительный ответ на любой из перечисленных запросов. Если положительных ответов не окажется, файл применен не будет. Рассмотрим следующий пример:

<link rel="stylesheet" media="screen and (orientation: portrait) and

(min-width: 800px), projection" href="800wide-portrait-screen.css" />

В нем есть две интересные особенности. Во-первых, для разделения медиазапросов используются запятые. Во-вторых, следует заметить, что в скобках после ключевого слова projection отсутствует следующая пара «свойство — значение» и/или сочетание свойств и значений. Дело в том, что при отсутствии таких значений медиа­запрос применяется ко всем устройствам, относящимся к данному типу медиа­устройств. В нашем примере стили будут применяться ко всем проекторам.

Sovet.tif совет

Следует иметь в виду, что для указания медиазапросов можно использовать любую единицу измерения длины, применяемую в CSS. Наиболее часто используются пикселы (px), но подойдут также em и rem. Чтобы дать более подробную информацию о качествах каждой единицы измерения, я привел расширенное толкование этой темы на ресурсе .

Таким образом, если нужна контрольная точка на 800 пикселах, но указанная в em, нужно просто разделить количество пикселов на 16. Например, 800 пикселов можно также указать как 50 em (800 / 16 = 50).

Медиазапросы с использованием @import

Для условной загрузки таблиц стилей в существующую таблицу стилей можно использовать также CSS-конструкцию @import. Например, следующий код импортирует таблицу стилей под названием phone.css при условии, что устройством является экран с максимальной шириной окна просмотра 360 пикселов:

@import url("phone.css") screen and (max-width:360px);

Следует помнить, что при использовании CSS-конструкции @import код добавляется к HTTP-запросам, что влияет на скорость загрузки, поэтому данный метод нужно использовать осмотрительно.

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

До сих пор медиазапросы включались нами в виде ссылок на CSS-файлы, а сами ссылки помещались в раздел <head></head> кода HTML и в виде инструкций @import. Но, скорее всего, нам захочется использовать медиазапросы внутри самих таблиц стилей. Например, если в таблицу стилей добавить следующий код, все элементы h1 приобретут зеленый цвет при условии, что ширина экрана устройства — не более 400 пикселов:

@media screen and (max-device-width: 400px) {

    h1 { color: green }

}

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

Здесь, видимо, следует заметить, что в большинстве ситуаций указывать экран (screen) не нужно. Основное положение спецификации звучит следующим образом:

«Сокращенный синтаксис предлагается для тех медиазапросов, которые применяются ко всем типам медиаустройств; ключевое слово all может быть опущено (наряду со следующим за ним and). То есть если тип медиаустройства не задан конкретным образом, подразумевается настройка all».

Следовательно, пока не возникнет потребность нацелить стили на конкретные типы медиаустройств, screen и and можно опустить. Впредь все медиазапросы в примерах будут записываться с учетом этой возможности.

Что можно тестировать с помощью медиазапросов

При построении адаптивного дизайна чаще всего используются медиазапросы, относящиеся к ширине окна просмотра (width). Исходя из личного опыта, могу сказать: другие возможности мне особо не пригодились (за редким исключением использования разрешения и высоты окна просмотра). Но на случай возникновения таких потребностей представляю вам перечень всех возможностей Media Queries Level 3, которыми можно будет воспользоваться. Может быть, некоторые из них вас смогут заинтересовать:

width: — ширина окна просмотра;

• height: — высота окна просмотра;

• device-width: — ширина поверхности отображения (для нас это, как правило, ширина экрана устройства);

• device-height: — высота поверхности отображения (для нас это, как правило, высота экрана устройства);

• orientation: — возможность проверки портретной или альбомной ориентации устройства;

• aspect-ratio: — соотношение ширины к высоте на основе ширины и высоты окна просмотра. Дисплей с соотношением сторон 16:9 может быть описан как aspect-ratio: 16/9;

• device-aspect-ratio: — эта возможность аналогична предыдущей, но основывается на ширине и высоте не окна просмотра, а поверхности отображения устройства;

• color: — количество битов, приходящееся на каждую составляющую цвета. Например, min-color: 16 задаст проверку того, обладает ли устройство цветом с глубиной 16 бит;

• color-index: — количество записей в таблице поиска цветов устройства. Значения должны быть числовыми и не могут быть отрицательными;

• monochrome: — возможность проверки количества битов на пиксел в буфере монохромного кадра. Значение должно быть целым числом, например monochrome: 2, и не может быть отрицательным;

• resolution: — эта возможность может использоваться для проверки разрешения экрана или принтера, например min-resolution: 300dpi. Может также приниматься единица измерения в точках на сантиметр, например min-resolution: 118dpcm;

• scan: — это свойство может отображать значение развертки (прогрессивной или чересстрочной), которое имеет отношение в основном к телевизионным устройствам. Например, нацеливание на устройство с параметрами 720p HD TV (буква «p» в 720p означает progressive — «прогрессивная») может быть обозначено с помощью выражения scan: progressive, a на устройство 1080i HD TV (буква «i» в 1080i означает interlaced — «чересстрочная») — с помощью выражения scan: interlace;

• grid: — эта возможность показывает, на какой основе построено устройство, сеточной или растровой.

Все перечисленные возможности, за исключением scan и grid, для создания диапазонов могут использоваться с префиксом min или max. Рассмотрим, к примеру, следующий фрагмент кода:

@import url("tiny.css") screen and (min-width:200px) and (max-width:360px);

Здесь минимум (min) или максимум (max) применены для задания диапазона ширины — width. Файл tiny.css может быть импортирован для экранных устройств с минимальной шириной окна просмотра 200 пикселов и максимальной шириной окна просмотра 360 пикселов.

Primechanie.tif Свойства, не рекомендуемые в медиазапросах спецификации CSS Media Queries Level 4

Следует знать, что в предварительной спецификации медиазапросов Media Queries Level 4 не рекомендуется использование ряда возможностей (), в частности, device-height, device-width и device-aspect-ratio. Поддержка этих запросов останется в браузерах, но от написания новых таблиц стилей с их использованием рекомендуется воздержаться.

Использование медиазапросов для изменения дизайна

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

Посмотрим на то, как это может выглядеть на практике (example_02-02). Сначала разметка:

<a href="#" class="CardLink CardLink_Hearts">Hearts</a>

<a href="#" class="CardLink CardLink_Clubs">Clubs</a>

<a href="#" class="CardLink CardLink_Spades">Spades</a>

<a href="#" class="CardLink CardLink_Diamonds">Diamonds</a>

А теперь CSS:

.CardLink {

    display: block;

    color: #666;

    text-shadow: 0 2px 0 #efefef;

    text-decoration: none;

    height: 2.75rem;

    line-height: 2.75rem;

    border-bottom: 1px solid #bbb;

    position: relative;

}

@media (min-width: 300px) {

    .CardLink {

        padding-left: 1.8rem;

        font-size: 1.6rem;

    }

}

 

.CardLink:before {

    display: none;

    position: absolute;

    top: 50%;

    transform: translateY(-50%);

    left: 0;

}

 

.CardLink_Hearts:before {

    content: "♥";

}

 

.CardLink_Clubs:before {

    content: "♣";

}

 

.CardLink_Spades:before {

    content: "♠";

}

 

.CardLink_Diamonds:before {

    content: "♦";

}

 

@media (min-width: 300px) {

    .CardLink:before {

        display: block;

    }

}

Вот как выглядит фрагмент экрана при небольшом окне просмотра.

02_01.tif 

А вот так — при более просторном окне просмотра.

02_02.tif 

В медиазапрос может быть заключен любой код CSS

Следует запомнить, что все подлежащее описанию в коде CSS также может быть заключено в медиазапрос. По существу, с помощью медиазапросов можно полностью изменить разметку и внешний вид сайта в различных ситуациях (обычно для разных размеров окна просмотра).

Медиазапросы для HiDPI-устройств

Еще одним широко распространенным способом использования медиазапросов является изменение стилей, когда сайт просматривается на устройстве с высоким разрешением. Рассмотрим следующий код:

@media (min-resolution: 2dppx) {

    /* стили */

}

Здесь медиазапрос определяет, что заключенные в него стили мы желаем применить при разрешении экрана 2 точки на пиксел (2 dppx). Они будут применены к таким устройствам, как iPhone 4 (HiDPI-устройствам компании с условным наименованием Retina), и к целому комплексу Android-устройств. Этот медиазапрос можно изменить с целью применения к более широкому кругу устройств путем уменьшения значения dppx.

Sovet.tif совет

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

Рассмотрение аспектов организации и разработки медиазапросов

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

Привязка различных CSS-файлов с помощью медиазапросов

С точки зрения браузера CSS рассматривается как ресурс, приостанавливающий отображение. Браузеру нужно извлечь и проанализировать привязанные CSS-файлы до полного вывода страницы на экран.

Но современные браузеры достаточно разумны для того, чтобы определять, какие таблицы стилей (связанные в head-разделе страницы с медиазапросами) должны быть проанализированы немедленно, а какие могут быть отложены и проанализированы уже после вывода на экран начальной страницы.

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

Подробности по данной теме можно найти на страницах разработчиков компании Google: .

Но я хочу обратить ваше внимание, в частности, на следующий фрагмент:

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

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

Следовательно, современный браузер загружает адаптивную веб-страницу (посмотрите файл каталога example_02-03) с четырьмя разными таблицами стилей, привязанными с помощью различных медиазапросов (для применения разных стилей для различных диапазонов окон просмотра) с загрузкой всех четырех CSS-файлов, но, возможно, с начальным анализом до вывода страницы на экран только одного из них, применимого в сложившихся условиях.

Практические аспекты разделения медиазапросов

Несмотря на то что мы только что узнали о потенциальных преимуществах разделения медиазапросов, ощутимость преимуществ разделения различных стилей в медиазапросах с помещением их в отдельные файлы не всегда достаточно высока (если не брать в расчет персональные предпочтения и/или обособление кода).

В конце концов, использование отдельных файлов повышает количество HTTP-запросов, необходимых для отображения страницы, что, в свою очередь, может сделать страницу медленнее в некоторых других ситуациях. Ничто в Интернете легко не дается! Поэтому возникает вопрос вычисления общей производительности вашего сайта и тестирования каждого сценария на различных устройствах.

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

сжаты все изображения;

• объединены и минимизированы все сценарии;

• средством gzip обработаны все ресурсы;

• все статическое содержимое кэшировано посредством CDN-сетей;

• удалены все избыточные CSS-правила.

Возможно, после этого я приступлю к решению вопроса о разбиении медиазапросов на отдельные файлы с целью повышения производительности.

Sovet.tif совет

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

Вложение медиазапросов путем их встраивания

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

Если вам удается придерживаться этой рекомендации, возникает следующий вопрос: должны ли медиазапросы объявляться ниже связанного с ними селектора? Или же они должны разбиваться в конце на отдельные блоки кода для всех одинаковых медиазапросов? Если у вас возник такой вопрос, я этому весьма рад.

Как поступать — объединять медиазапросы или же записывать их там, где они пригодятся?

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

.thing {

    width: 50%;

}

 

@media screen and (min-width: 30rem) {

    .thing {

        width: 75%;

    }

}

 

/* Здесь между рассматриваемыми фрагментами кода помещаются другие стили */

 

.thing2 {

    width: 65%;

}

 

@media screen and (min-width: 30rem) {

    .thing2 {

        width: 75%;

    }

}

Поначалу все это выглядит весьма странно. У нас есть два медиазапроса, и оба они имеют отношение к экранам с минимальной шириной 30 rem. Неужели повторение @media-объявления не считается многословием и расточительством? Наверное, мне следовало бы сгруппировать все идентичные медиазапросы в единый блок:

.thing {

    width: 50%;

}

 

.thing2 {

    width: 65%;

}

 

@media screen and (min-width: 30rem) {

    .thing {

        width: 75%;

    }

    .thing2 {

        width: 75%;

    }

}

Безусловно, это один из способов такой группировки. Но с точки зрения сопровождения кода он представляется мне более сложным. Правильного способа не существует, но я предпочитаю сначала определить одно правило для отдельного селектора и располагать определения любых изменений этого правила (например, изменения внутри медиазапросов) непосредственно после него. При этом мне не придется искать отдельные блоки кода, чтобы найти объявление, относящееся к конкретному селектору.

Primechanie.tif примечание

Еще более удобным может стать использование препроцессоров и постпроцессоров CSS, поскольку вариант правила, заключенный в медиазапрос, может быть вложен непосредственно в набор правил. В моей книге Sass and Compass for Designers этой теме посвящен целый раздел.

Казалось бы, вполне резонно выступить против вышеупомянутой технологии по причине ее многословия. Неужели один лишь размер файла может стать достаточной причиной для того, чтобы не записывать медиазапросы таким образом? В конце концов, никому не хочется иметь раздутый CSS-файл для обслуживания своих потребностей. Но нужно считаться с тем простым фактом, что gzip-сжатие, которому должны подвергаться все возможные ресурсы на вашем сервере, сокращает разницу до совершенно ничтожных величин. Ранее я провел соответствующие тесты, и если у вас появилось желание получить дополнительные сведения, можете обратиться по адресу /. Суть в том, что я не верю, что вас будет тревожить размер файла, если вы предпочтете записывать медиазапросы непосредственно после стандартных стилей.

Sovet.tif совет

Если вам хочется разрабатывать свои медиазапросы непосредственно после исходных правил, но при этом иметь все идентичные определения медиазапросов объединенными в один запрос, то для этого существует несколько рабочих инструментов (на момент написания данной книги соответствующие дополнительные модули были как у Grunt, так и у Gulp).

Метатег viewport

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

Когда в 2007 году компания Apple выпустила iPhone, она ввела собственный метатег под названием viewport, который теперь поддерживается Android и постоянно растущим количеством других платформ. Предназначением метатега viewport является предоставление веб-страницам способа связи с браузерами мобильных устройств для сообщения им предпочтительного способа вывода страницы на экран.

В обозримом будущем те веб-страницы, которые хотелось бы сделать адаптивными и успешно выводимыми на устройствах с малыми размерами экрана, будут вынуждены использовать этот метатег.

Sovet.tif тестирование адаптивного дизайна на эмуляторах и симуляторах

Хотя замены для тестирования результатов разработки на реальных устройствах нет, существует ряд эмуляторов для Android и симуляторов для iOS. Для особо дотошных поясняю, что симулятор просто симулирует нужное устройство, а эмулятор фактически пытается интерпретировать исходный код устройства.

Android-эмулятор для Windows, Linux и Mac находится в свободном доступе для загрузки и установки по адресу / и применяется в составе программного инструментария разработчика Android Software Development Kit (SDK).

Симулятор для iOS доступен только пользователям Mac OS X и поставляется как часть пакета Xcode, который можно свободно получить в Mac App Store.

У самих браузеров в их средствах разработки также имеются постоянно совершенствуемые инструменты для эмуляции мобильных устройств. Конкретные настройки на эмуляцию различных мобильных устройств и окон просмотра имеются как у Firefox, так и у Chrome.

Метатег viewport добавляется в <head>-теги кода HTML. Он может настраиваться на определенную ширину (которую, к примеру, можно выразить в пикселах) или содержать указание на масштаб, например 2.0 (удваивание текущего размера). Рассмотрим пример использования метатега viewport, настраивающего вывод в браузере в удвоенном по сравнению с исходным размере (200 %):

<meta name="viewport" content="initial-scale=2.0,width=device-width" />

Разобьем предыдущий метатег на части, чтобы понять, что происходит. Атрибут name="viewport" разъяснений не требует. Затем в разделе content="initial-scale=2.0 предписывается увеличить размер содержимого вдвое (значение 0.5 уполовинило бы размер, 3.0 — утроило его и т. д.), а раздел width=device-width говорит браузеру о том, что ширина страницы должна быть равна значению device-width.

Метатег может использоваться также для управления пределами возможностей пользователя при масштабировании страницы в обе стороны. Следующий пример позволяет пользователям увеличивать масштаб до трехкратной ширины экрана устройства и уменьшать его до половинной ширины экрана устройства:

<meta name="viewport" content="width=device-width, maximum-scale=3,

minimum-scale=0.5" />

Можно также вообще не давать пользователям возможности масштабирования, но, поскольку масштабирование является важным средством, повышающим удобство просмотра содержимого, применять эту настройку на практике вряд ли придется:

<meta name="viewport" content="initial-scale=1.0, user-scalable=no" />

Ключевой здесь является часть user-scalable=no.

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

<meta name="viewport" content="width=device-width,initial-scale=1.0" />

Sovet.tif совет

Заметив рост популярности использования метатега viewport, консорциум W3C предпринял попытки внедрения такой же возможности в CSS. Зайдите на страницу / и прочитайте все о новом объявлении @viewport. Идея заключается в том, что вместо написания в <head>-разделе вашей разметки метатега вы можете написать в CSS @viewport { width: 320px; }. В результате ширина браузера будет настроена на 320 пикселов. Но поддержка этого объявления со стороны браузеров оставляет желать лучшего, поэтому для охвата всех возможных вариантов и максимального соответствия требованиям завтрашнего дня можно воспользоваться комбинацией метатега и объявления @viewport.

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

Спецификация Media Queries Level 4

На момент написания книги, когда CSS Media Queries Level 4 пребывали в стадии проекта спецификации (/), компоненты этого проекта не могли похвастаться реализацией в множестве браузеров. Это означает, что, несмотря на краткий обзор особенностей этой спецификации, она еще не при­обрела достаточной стабильности. Перед использованием любого из ее компонентов нужно убедиться в его поддержке браузером и дважды проверить, не изменился ли у него синтаксис.

А пока, хотя в спецификации четвертого уровня есть и другие компоненты, мы коснемся только возможностей использования сценариев, реагирования на прохо­ждение указателя мыши над элементами страницы и использования освещенности.

Медиасвойство использования сценариев

Согласно устоявшейся практике тегу HTML присваивается класс, показывающий исходное отсутствие кода JavaScript с последующей заменой этого класса на другой при запуске JavaScript. Тем самым предоставляется легко реализуемая возможность разветвления кода, включая CSS, на основе этого нового класса, присваиваемого тегу HTML. В частности, используя этот прием, можно написать правила, применяемые к конкретным пользователям, у которых включен JavaScript.

Чтобы не запутаться, рассмотрим пример кода. В самом начале это будет тег, созданный в HTML:

<html class="no-js">

Когда на странице запустится JavaScript, одной из первых задач станет замена класса no-js:

<html class="js">

После того как это будет сделано, можно написать конкретные CSS-правила, применимые исключительно при наличии JavaScript, например .js .header { display: block; }.

А вот медиасвойство использования сценариев, имеющееся в спецификации CSS Media Queries Level 4, предназначено для обеспечения более соответствующего общему стандарту способа достижения аналогичного результата непосредственно в коде CSS:

@media (scripting: none) {

    /* стили, предназначенные для применения в отсутствие JavaScript */

}

И при наличии JavaScript:

@media (scripting: enabled) {

    /* стили, предназначенные для применения при наличии JavaScript */

}

И наконец, это свойство предназначено также для выявления факта применения JavaScript только при начальном отображении страницы. В спецификации W3C приводится пример задания отображаемой страницы, которая может быть размечена при начальном выводе на экран, после чего JavaScript на ней использоваться не будет:

@media (scripting: initial-only) {

    /* стили для страницы, применяющей JavaScript только при ее начальном выводе */

}

О текущем редакторском проекте этого свойства можно прочитать на странице .

Медиасвойства, связанные с взаимодействием со страницей

В W3C медиасвойство указателя pointer, представлено следующим образом:

«Медиасвойство pointer используется для запроса наличия и точности указывающего устройства, например мыши. Если у устройства имеется несколько механизмов ввода, медиасвойство pointer должно отражать характеристики первичного механизма ввода в соответствии с определением пользовательского агента (user agent)».

Существует три возможных состояния указателя pointer: none (отсутствует), coarse (грубый) и fine (тонкий).

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

@media (pointer: coarse) {

    /* стили на случай присутствия указателя, имеющего состояние coarse */

}

Устройством со свойством pointer, имеющим значение fine, может быть мышь, а также стилус-перо или любой другой указательный механизм высокой точности:

@media (pointer: fine) {

    /* стили на случай присутствия указателя с высокой точностью */

}

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

Sovet.tif совет

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

Более подробный обзор проблем разработки для устройств с сенсорным вводом и устройств, использующих указатель типа «мышь», представлен в наборе слайдов под названием Getting touchy, созданном Патриком Лауке (Patrick H. Lauke) и опубликованном на сайте /.

О редакторском проекте (editor’s draft) этого свойства можно прочитать на сайте .

Медиасвойство hover

Как вы, наверное, уже догадались, медиасвойство hover тестирует пользовательскую возможность проведения указателя над элементами экрана. Если пользователь располагает несколькими устройствами ввода (например, сенсором и мышью), используются характеристики основного устройства ввода. Далее перечислены возможные значения и показаны примеры кода.

Для пользователей, не имеющих возможности провести указатель над элементами экрана, можно нацелить стили для значения этого свойства, равного none:

@media (hover: none) {

    /* стили для тех случаев, когда провести указатель над элементами невозможно */

}

Для тех пользователей, которые имеют такую возможность, но должны для ее инициирования предпринять определенные действия, можно воспользоваться значением on-demand:

@media (hover: on-demand) {

    /* стили для тех случаев, когда пользователь

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

    элементами, но от него требуются определенные

    действия */

}

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

@media (hover) {

    /* стили для тех случаев, когда пользователь

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

}

Существуют также медиасвойства any-pointer и any-hover. Они похожи на рассмотренные ранее hover и pointer, но проверяют возможности любого из возможных устройств ввода.

Медиасвойства среды

Правда, неплохо было бы иметь возможность изменять наш дизайн на основе свойств окружающей среды, например уровня освещенности? Тогда при переходе пользователя в хуже освещенное помещение можно будет переключиться на использование более яркого цветового оформления. Или же, наоборот, повысить контрастность при переходе в место с ярким солнечным светом. Медиасвойства среды предназначены для решения разнообразных задач подобного рода. Рассмотрим следующие примеры:

@media (light-level: normal) {

    /* стили для стандартной освещенности */

}

@media (light-level: dim) {

    /* стили для приглушенной освещенности */

}

@media (light-level: washed) {

    /* стили для яркой освещенности */

}

Следует помнить, что в разрабатываемой спецификации Level 4 Media Queries предусматривается несколько реализаций таких свойств. Возможно также, что до возникновения надежных реализаций эти спецификации претерпят изменения. Но все же будет полезно иметь некоторое представление о том, какие новые возможности ждут нас в ближайшие дни.

О редакторском проекте этих свойств можно узнать на сайте .

Резюме

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

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

Назад: 1. Основы адаптивного веб-дизайна
Дальше: 3. Динамически изменяемые разметки и адаптивные изображения