Создание HTML5 приложений: Применение media-запросов CSS3 для адаптивного веб-дизайна

OSzone.net » Microsoft » Разработка приложений » HTML5 » Создание HTML5 приложений: Применение media-запросов CSS3 для адаптивного веб-дизайна
Автор: Брэндон Сэтром
Иcточник: MSDN Magazine
Опубликована: 26.06.2012

Несколько лет назад ко мне обратился один клиент, который хотел создать веб-сайт только в мобильной версии для своей аудитории технически подкованных молодых людей. Проект был представлен нам как «сайт для iPhone», и его дизайн уже был полностью сформулирован. Обрадовавшись возможности создать такое передовое мобильное приложение, мы рьяно взялись за работу и продвигались в приличном темпе, пока не пришла пора подумать о других мобильных устройствах на рынке. Наш клиент хотел поддерживать практически все мобильные устройства. С этого момента и начались наши героические усилия в попытке ответить на два важнейших вопроса, которые возникают у веб-разработчиков при создании мобильных версий сайтов: как узнать, когда следует подстраивать интерфейс для данного мобильного браузера, и как вносить эти изменения, когда такая потребность возникает?

Адаптивный веб-дизайн

Эти вопросы лежат в основе адаптивного веб-дизайна (responsive Web design); данный термин был придуман Этаном Маркотт (Ethan Marcotte) (bit.ly/aO2cFa). Суть адаптивного веб-дизайна в использовании контекстных подсказок от браузера с целью адаптации представления сайта и даже его поведения. Сайт должен реагировать на информацию, передаваемую браузером, и подстраиваться под ожидания пользователя этого устройства. Если подсказки дают достаточный объем информации о браузере и устройстве, становится возможной адаптация, например изменение изображений и использование текучих («резиновых») разметок (fluid layouts).

По традиции, вы получаете такие контекстные подсказки, разбирая строку User Agent, предоставляемую браузером (этот метод называют распознаванием браузера или UA-распознаванием), а затем используете эту информацию, чтобы определить, что делать дальше. О UA-распознавании я писал в своей статье «No Browser Left Behind: An HTML5 Adoption Strategy» за сентябрь 2011 г. (msdn.microsoft.com/magazine/hh394148). Как я тогда отмечал, распознавание браузера — методика ненадежная, и в конечном счете от нее отказались в пользу распознавания функций (feature detection), которое помогает принимать решения о разметке, CSS и JavaScript, исходя из доступной функциональности, а не конкретного браузера и версии.

В контексте адаптивного веб-дизайна все современные настольные и основные мобильные браузеры поддерживают такую функцию, как media-запросы. Это модуль CSS3, расширяющий концепцию медиа-типов, введенных в CSS 2.1; он позволяет указывать альтернативные таблицы стилей для печати, вывода на экран и т. п. с возможностью определять некоторые из физических характеристик устройства, с которого пользователь заходит на сайт. По аналогии с принципом, лежащим в основе распознавания функций, media-запросы дают возможность сосредоточиться на получении правильных контекстных подсказок от текущего посетителя, которые можно потом использовать для подстройки представления сайта. Мощь media-запросов заключается в том, что они предоставляют такие подсказки вашим таблицам стилей.

В этой статье я дам обзор CSS3-модуля media-запросов. Мы вкратце обсудим его синтаксис и способы использования, а потом я покажу простой пример, в котором применяются media-запросы для формирования представлений онлайновой фотогалереи, дружественных к смартфонам и планшетам. Затем я поделюсь с вами одним приемом, важным для разработки всех видов мобильных приложений, а в заключение кратко рассмотрю слушатели media-запросов. Эти слушатели определяются отдельной W3C-спецификацией (bit.ly/wyYBDG), в соответствии с которой предоставляется API для реагирования на изменения в media-среде через JavaScript. К концу этой статьи вы должны получить твердый фундамент для создания адаптивных веб-сайтов и приложений, использующих только CSS и некоторые специально оптимизированные стили.

Media-запросы в CSS

Как упоминалось, CSS 2.1 в настоящее время поддерживает зависимые от media таблицы стилей на основе объявлений типов media (bit.ly/xhD3HD). Следующая разметка иллюстрирует, как с помощью этих типов можно указывать условные таблицы стилей:

<link rel="stylesheet" type="text/css" href="main.css"  media="screen" />
<link rel="stylesheet" type="text/css" href="print.css"  media="print" />

При наличии этих элементов сайт будет загружать таблицу стилей, отличную от таблицы по умолчанию (или «screen»), когда страница будет загружаться в режиме предварительного просмотра перед печатью. Как бы ни была полезна эта функция (исторически сложилось так, что ее недостаточно часто использовали), она не дает никаких контекстных подсказок к созданию по-настоящему адаптивных веб-сайтов. И хотя в спецификации типов media подробно описано использование десяти media-типов, поставщики браузеров никогда не задействовали все эти типы.

Однако атрибут media образует хороший фундамент, и W3C решил формировать media-запросы (bit.ly/zbIeDg) непосредственно на его основе. Так как вы указываете тип media (например, print, screen или all), media-запросы позволяют добавлять выражения к атрибуту media, которые выполняют проверку определенных media-характеристик, таких как ширина, высота, ориентация и даже разрешение экрана текущего устройства. Вот пример, где загружается таблица стилей main.css, если тип media является экраном (screen), а ширина устройства равна 800 пикселям минимум:

<link rel="stylesheet" media="screen and (min-width: 800px)"  href="main.css" />

Media-запрос — это то, что находится в скобках. Левая часть указывает проверяемое свойство (width) с дополнительным (необязательным) модификатором min- или max-, а в правой части задается значение этого свойства. Если устройство или браузер обеспечивает экран с шириной минимум 800 пикселей, будут применены стили из main.css. В ином случае эти стили не применяются. Это иллюстрирует, как media-запросы дают разработчикам полезные контекстные подсказки для создания адаптивных веб-сайтов и приложений.

Приступаем

Как отмечалось, media-запросы в CSS3 поддерживаются новейшими версиями всех основных браузеров (bit.ly/wpamib), поэтому в настоящее время вы можете без проблем задействовать их. Использовать media-запросы для своих сайтов можно тремя способами. Первый — это условная загрузка полных таблиц стилей, как показано в предыдущем примере. Второй — применение директив @import в таблицах стилей. Вот та же проверка, но на этот раз в виде директивы @import:

@import url("main.css") screen and (min-width: 800px);

Как и в первом примере, это выражение будет оценивать ширину экрана текущего устройства и, если она не меньше 800 пикселей, загружать main.css и применять его стили.

Наконец, вы можете использовать media-запросы, встраиваемые в CSS с помощью директив @media:

@media screen and (min-width: 800px) { ... }

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

Теперь посмотрим на media-запросы в действии и начнем с простого примера. Если вы хотите опробовать его, скачайте пакет исходного кода для этой статьи или откройте любимую IDE-среду либо текстовый редактор и добавьте разметку, как на рис. 1.

Рис. 1. Пример HTML-документа

<!doctype html>
<html>
  <head>
    <meta charset="utf-8">
    <link rel="stylesheet" type="text/css" href="media.css">
  </head>
  <body>
    <article id="small">This is a small screen</article>
    <article id="medium">This is a medium screen</article>
    <article id="large">This is a large screen</article>
    <article id="landscape">... and you're in landscape mode...</article>
  </body>
</html>

Затем создайте таблицу стилей с именем media.css в той же папке и добавьте стили, определенные на рис. 2. Заметьте, что я определил все директивы @media в конце файла; скорее всего вы захотите сделать то же самое. Если вы определяете в разметке несколько таблиц стилей, вам также понадобится помещать элементы <link> для специфических таблиц стилей после основных. Из-за каскадной природы CSS ваши правила, специфичные для конкретной среды (media), по-видимому, должны заменять основные правила, а занчит, их нужно определять соответствующим образом. Обратите внимание, что я определил стили для своих элементов article и body, а за ними разместил media-запросы (и связанные с ними правила) для каждого типа устройств, которые мне требуется поддерживать. Устройства с экранами меньше 480 пикселей будут получать один набор дополнительных стилей, устройства с экранами от 480 до 1024 пикселей — другой, а устройства с экранами более 1024 пикселей — третий. Я также добавил запрос для определения ориентации экрана и буду применять еще один набор стилей, если устройство находится в ландшафтном режиме.

Рис. 2. Media-запросы CSS, определенные как встраиваемые с помощью директивы @media

article {
  display: none;
}
body {
  font-size: 24px;
  font-weight: 800;
  color: white;
}
@media screen and (max-width: 480px) {
  body {
    background-color: #ff2a18;
  }
  #small {
    display: inline;
  }
}
@media screen and (min-width: 480px) and (max-width: 1024px) {
  body {
    background-color: #00ff00;
  }
  #medium {
    display: inline;
  }
}
@media screen and (min-width: 1024px) {
  body {
    background-color: #0000ff;
  }
  #large {
    display: inline;
  }
}
@media screen and (orientation: landscape) {
  body {
    background-color: #ff7f00;
  }
  #landscape {
    display: inline;
  }
}

Создав страницу (рис. 1) и таблицу стилей (рис. 2), откройте эту страницу в любом браузере. Проверить ваши media-запросы несложно; вы можете сделать это даже без мобильного устройства. Просто изменяйте размеры окна браузера и наблюдайте за тем, как меняются цвета текста и фона при изменении контекста видимого окна.

Теперь, когда вы знаете основы media-запросов, сделаем еще один шаг и изучим более реалистичный пример. В этом примере я добавлю media-запросы в онлайновую фотогалерею для поддержки смартфонов и планшетов. Исходный код для этого примера, который использует шаблон Photo Gallery, поставляемый с WebMatrix (webmatrix.com), вы найдете по ссылке code.msdn.microsoft.com/mag201204HTML5.

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

*
Рис. 3. Мобильное представление без media-запросов

В конец файла desktop.css, созданного для этого примера, добавьте директиву и условие для своего media-запроса. Поскольку в данный момент меня больше всего волнуют самые малые экраны, я создам следующее определение:

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

Теперь в этом определении давайте создадим некоторые правила для масштабирования и изменения позиции изображений на таких экранах. Эти правила показаны на рис. 4.

Рис. 4. Модификация стилей для мобильных устройств

body {
  min-width: 120px;
  max-width: 320px;
}
h1 {
  font-size: 1.5em;
}
img {
  width: 250px;
  height: 187.5px;
}
ul.thumbnails li {
  width: 265px;
    height: 200px;
    line-height: 200px;
}
ul.thumbnails li span.image-overlay {
    width: 265px;
}

Если вы обновите страницу после добавления этих стилей, то заметите нечто вроде того, что показано на рис. 5. Изображения выглядят лучше, но основная панель навигации не выровнена. Более того, галерея использует псевдоселектор CSS :hover для отображения дополнительной информации о каждом изображении, как представлено на рис. 6. Поскольку это не имеет смысла в среде, где события наведения курсора (hover) не столь распространены (смартфоны и планшеты), нам нужно позаботиться об альтернативном представлении и этого аспекта страницы. Мы сделаем это, добавив стили, приведенные на рис. 7, в текущую директиву @media.

*
Рис. 5. Мобильное представление с улучшенными изображениями

*
Рис. 6. Изображение с примененным эффектом наведения курсора

Рис. 7. Стили для навигации и отображения сведений об изображениях в удобном на мобильных устройствах виде

#banner {
  height: 110px;
  background: #eaeaea;
}
#menu li {
  display: block;
  margin-top: 3px;
  margin-bottom: 3px;
}
#menu li.tags a,
#menu li.galleries a,
#menu li.account a {
  background: none;
}
#menu li.login {
  display: none;
}
ul.thumbnails li span.image-overlay {
  display:block;
  position: absolute;
  top: 0;
  left: 0;
  line-height: normal;
  width: 515px;
    padding: 5px;
}
ul.thumbnails li {
    background: #f3f6f7;
    border-color: #dbe2e5;
    border-radius: 7px;
    box-shadow: 0px 0px 20px 5px #A9A9A9;
}

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

*
Рис. 8. Галерея с более качественной навигацией и окнами изображений

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

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

@media screen and (min-width:480px) and (max-width:1024px)

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

Рис. 9. Стили для представления, дружественного к планшетам

body {
  min-width: 480px;
  max-width: 800px;
}
img {
  width: 500px;
  height: 375px;
  align: center;
}
ul.thumbnails li {
  width: 515px;
    height: 390px;
    line-height: 200px;
}

Теперь обновите экран в браузере на своем планшете и вы увидите примерно то же, что и на рис. 10. С этого момента мы поддерживаем экраны нескольких размеров, а значит, и несколько типов устройств; все, что для этого понадобилось, — некоторое время на создание альтернативных стилей.

*
Рис. 10. Фотогалерея: представление, дружественное к планшетам

Разработка с ориентацией в первую очередь на мобильные устройства

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

Если вы кодировали, следуя моему описанию media-запросов в этой статье, то, вероятно, обратили внимание на небольшую проблему при просмотре страницы на смартфоне или в эмуляторе смартфона: на некоторых устройствах эффект слишком мелких изображений не исчез — даже после применения условных правил. Дело в том, что мобильный браузер пытается «оптимизировать» отображение контента на малых экранах, что полезно для сайтов, которые не уделяют внимания мобильным пользователям. Однако для данного сайта такая «оптимизация» нежелательна, и вы можете переопределить это поведение по умолчанию, добавив единственный тег <meta> в тег <head> вашей страницы, например:

<meta name="viewport" content="width=device-width">

Теперь, если вы обновите страницу и ваши media-запросы определены должным образом, вы должны увидеть работу своих правил.

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

Возможно, вы также заметили, что в примере с фотогалереей я добавил поддержку мобильных устройств к существующему сайту. Как разработчик, осваивающий media-запросы, вы скорее всего поступите точно так же. Однако набирает обороты движение, которое провозглашает в проектировании и разработке веб-сайтов и приложений «ориентацию прежде всего на мобильные устройства». Разработка с ориентацией в первую очередь на мобильные устройства заключается в том, что приоритет сразу отдается поддержке мобильных пользователей, а не откладывается на потом (как часто бывало в прошлом). Это имеет смысл, если вспомнить, что за последние пару лет продажи смартфонов и планшетов обогнали продажи ПК и что более половины просмотров в Интернете приходится на мобильных пользователей. Чтобы узнать больше о подходе «mobile first», настоятельно рекомендую одноименную книгу Люка Врублевского (Luke Wroblewski) (она доступна по ссылке bit.ly/zd9UWT).

Слушатели media-запросов

CSS Working Group собирается добавить JavaScript API-средства для расширения поддержки media-запросов в CSS3, что позволит разработчикам оценивать media-запросы в период выполнения и прослушивать изменения в условиях media-запросов. Эти API документированы в спецификации CSSOM View Module (bit.ly/w8Ncq4). На рис. 11 показан пример выполнения media-запросов и создания слушателей из кода на JavaScript.

Рис. 11. Работа со слушателями media-запросов

listener = window.msMatchMedia("(min-width: 480px)");
evaluate(listener); // начальная оценка
// Выполнение оценки при каждом изменении width
listener.addListener(evaluate);
function evaluate(listener) {
  if (mql.matches) {
    expandCommentList(); // width не менее 480 пикселей
  } else {
    shrinkCommentList(); // width меньше этого значения
  }
}

Слушатели потенциально весьма полезны в случаях, где окно просмотра на устройстве может изменяться в период выполнения, например, при изменении ориентации на смартфонах и планшетах. С помощью слушателей media-запросов можно реагировать на эти изменения не только из CSS, но и в ваших скриптах. Спецификация CSSOM View в настоящее время находится в состоянии Working Draft, но Internet Explorer 10 Platform Preview уже поддерживает слушатели media-запросов, поэтому вы можете опробовать эту технологию на Internet Explorer Test Drive (bit.ly/gQk7wZ).

Возможности поддержки множества платформ в веб-приложениях претерпели значительные изменения за последние несколько лет. Если в прошлом было обычным делом создавать версии сайта, специфичные для конкретных устройств, то нынешнее распространение мобильных устройств сделало ориентацию на конкретные устройства неосуществимой. К счастью, введение media-запросов в CSS3 с поддержкой всеми основными настольными и мобильными браузерами означает, что теперь вы можете использовать контекстные подсказки, обеспечивающие настоящую адаптацию сайтов под широкий спектр устройств, — и все это благодаря условным CSS. Подробнее о media-запросах см. соответствующую главу в отличной книге Питера Гасстона (Peter Gasston) «The Book of CSS3» (No Starch Press, 2011). Надеюсь, что эта статья помогла вам получить достаточно информации, чтобы приступить к адаптивному проектированию уже сегодня.

Исходный код можно скачать по ссылке code.msdn.microsoft.com/mag201204HTML5.


Ссылка: http://www.oszone.net/18270/HTML5-CSS3