CSS3 - мобильные интерфейсы

145

Если вы когда-либо работали в Интернете более-менее продолжительное время с мобильного устройства, то, несомненно, обнаружили, что крохотный экранчик (каким бы большим он не был для мобильного устройства) — не лучшее окно в Интернет.

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

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

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

Представляем запросы о возможностях отображения (media queries). Эта возможность CSS3 предоставляет простой способ изменять стили веб-страницы для разных устройств и разных настроек просмотра. Аккуратное использование таких запросов может помочь вам предоставить свою веб-страницу любому устройству — от сверхширокого экрана домашнего компьютера до экрана смартфона iPhone. И все это без изменения ни единой строчки кода HTML.

Запросы о возможностях отображения

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

Страница в экранном режиме
Страница с применением свойства @media

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

<link href="styles.css" rel="stylesheet" media="screen">
   ...
<link href="print_styles.css" rel="stylesheet" media="print">

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

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

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

<article>
   ...
</article>
<aside>
   ...
</aside>

А таблица стилей начинается с двух правил, по одному для каждого блока:

article    {
    border: solid 1px black;
    padding: 15px;
    margin: 5px;
    background: yellow;
    float: left;
    width: 330px;
}

aside    {
    border: solid 1px black;
    padding: 15px;
    margin: 5px;
    background: yellow;
    position: absolute;
    float: left;
    margin-left: 370px;
}

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

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

@media (имя-свойства-запроса-о-возможностях: value) { 
    /* Новые стили вставляются сюда. */
}

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

@media (max-width: 480px) { }

В настоящее время самыми популярными свойствами запросов о возможностях являются max-device-width (для создания мобильных версий веб-страниц), max-width (для применения разных стилей в зависимости от текущего размера окна браузера) и orientation (для изменения компоновки страницы, в зависимости от расположения устройства — горизонтального или вертикального).

Хотя внутри блока запроса о возможностях можно вставить все, что угодно, в этом примере просто добавляются новые правила таблицы стилей для элементов <article> И <aside>:

@media (max-width: 480px) {
    article {
        float: none;
        width: auto;
    }

    aside {
        position: static;
        float: none;
        background: pink;
        margin-left: 5px;
    }
}

Эти стили применяются в дополнение к уже определенным обычным стилям. Поэтому может потребоваться сбросить уже измененные свойства в их значения по умолчанию. В этом примере стили запроса о возможностях присваивают свойству position значение static, свойству float — значение none, а свойству width — значение auto. Это значения по умолчанию, которые были изменены исходным правилом стиля для боковой панели.

Браузеры, которые не понимают запросов о возможностях, такие как Internet Explorer, просто игнорируют новые стили и применяют исходные стили независимо от размера окна браузера.

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

@media (max-width: 250px) {
   ...
}

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

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

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

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

@media (min-width: 600px) and (max-width: 700px) {
	/* Замещаем стили для окон шириной 600-700 пикселов. */
}

@media (min-width: 400px) and (max-width: 599.99px) {
	/* Замещаем стили для окон шириной 400-600 пикселов. */
}

@media (max-width: 399.99px) {
	/* Замещаем стили для окон шириной до 400 пикселов. */
}

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

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

Можно еще использовать ключевое слово not. Функционально, по сути, это такая же таблица стилей, но, может быть, более понятная:

@media (not min-width: 600px) and (max-width: 700px) {
	/* Замещаем стили для окон шириной 600-700 пикселов. */
}

@media (not min-width: 400px) and (max-width: 600px) {
	/* Замещаем стили для окон шириной 400-600 пикселов. */
}

@media (max-width: 400px) {
	/* Замещаем стили для окон шириной до 400 пикселов. */
}

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

Полная замена таблицы стилей

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

<head>
   <link rel="stylesheet" href="standart_styles.css">
   <link rel="stylesheet" href="mobile_styles.css" media="(max-width: 480px)">
</head>

Хотя браузер загрузит со страницей и вторую таблицу стилей, она не будет применена, если только ширина окна браузера не отвечает указанному минимуму.

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

<head>
   <link rel="stylesheet" href="standart_styles.css" media="(min-width: 480.01px)">
   <link rel="stylesheet" href="mobile_styles.css" media="(max-width: 480px)">
</head>

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

<head>
   <link rel="stylesheet" href="standart_styles.css" media="(min-width: 480.01px)">
   <link rel="stylesheet" href="mobile_styles.css" media="(max-width: 480px)">
   <!--[if lt IE 9]>
      <link rel="stylesheet" href="standart_styles.css">
   <![endif]-->
</head>

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

Распознавание мобильных устройств

Как мы уже узнали, выяснить, где просматривается веб-страница — на экране обычного компьютера или мобильного устройства, можно с помощью запроса о возможностях отображения, содержащего свойство max-device-width. Но какие значения ширины следует использовать для этого свойства?

Если вы пытаетесь идентифицировать смартфоны, проверяйте свойство max-device-width на значение, равное 480 пикселам. Это наилучшее, общеприменимое правило, которое определяет существующие сегодня телефоны iPhone и Android:

<head>
   <link rel="stylesheet" href="mobile_styles.css" media="(max-width: 480px)">
</head>

Но если вы фанат железа, это правило может вызвать у вас подозрение, т.к. современные мобильные устройства оснащены крохотными экранами со сверхвысокой разрешающей способностью. Например, размер экрана Samsung Galaxy S4 — 1920x1080 пикселов. В связи с этим можно подумать, что для этих устройств нужно использовать большее значение ширины экрана. Но, как это ни удивительно, это не так. Большинство смартфонов продолжает сообщать, что ширина их экрана — 480 пикселов, даже если они в действительности оснащены экраном высокого разрешения. Это объясняется применением этими устройствами поправочного коэффициента, который называется соотношением пикселов (pixel ratio).

Например, в iPhone 4 каждому пикселу CSS соответствует в ширину два физических пиксела, т.е. соотношение пикселов равно 2. В действительности можно создать запрос о возможностях, который определяет iPhone 4, но игнорирует более старые версии iPhone:

<head>
   <link rel="stylesheet" href="mobile_styles.css" 
            media="(max-width: 480px) and
                   -webkit-min-device-pixel-ratio: 2">
</head>

A iPad представляет особую проблему: пользователи могут поворачивать его, сориентировав экран горизонтально или вертикально. Но хотя это меняет значение ширины окна max-width, значение ширины экрана max-device-width не меняется. Как и книжной, так и альбомной ориентации экрана iPad сообщает, что его ширина экрана равна 768 пикселов. К счастью, если требуется менять стили в зависимости от ориентации экран iPad, в запросах о возможностях свойство max-device-width можно применять совместно со свойством orientation:

<head>
   <link rel="stylesheet" href="mobile_styles_vertical.css" 
            media="(max-width: 768px) and
                   orientation: portrait">
   <link rel="stylesheet" href="mobile_styles_horizontal.css" 
            media="(max-width: 768px) and
                   orientation: landscape">
</head>

Конечно же, это правило можно применять не только с устройствами iPad, но и с другими устройствами с подобными размерами экрана (в данном случае 768 пикселов или меньше).

Пройди тесты
Лучший чат для C# программистов