В прошлой статье я ознакомил вас с media-запросами CSS3 (
msdn.microsoft.com/magazine/hh882445) — новым модулем, позволяющим адаптировать стили страницы на основе условных правил. Хотя media-запросы широко применяются на целом спектре устройств, о них часто упоминают в контексте создания мобильных сайтов и приложений. В частности, во введении в media-запросы в прошлой статье основное внимание уделялось созданию сайтов, рассчитанных на планшеты и мобильные устройства.
Учитывая трудности в создании мобильных сайтов и приложений, не удивительно, что разработчики ухватились за media-запросы. По сравнению с нежелательными альтернативами вроде анализа браузера (иногда называемого распознаванием устройства) и необходимостью создавать вариации мобильных приложений для каждой платформы индивидуально media-запросы кажутся настоящим подарком. Безусловно, это отличные модули, и причина, по которой я написал о них в прошлом номере, состоит в том, что вы должны использовать их уже сегодня.
Еще раз об адаптивном веб-дизайне
Однако не все так просто: media-запросы CSS — отличная штука, но это не более чем часть того, что вам понадобится на самом деле, чтобы создать по-настоящему удобное в использовании мобильное веб-приложение. В прошлом номере я упомянул термин «адаптивный веб-дизайн» (responsive Web design) — его ввел в употребление Этан Маркотт (Ethan Marcotte) в своей новаторской статье под тем же названием (bit.ly/9AMjxh). Маркотт основное внимание уделяет media-запросам и в то же время указывает на необходимость в двух других частях: «резиновых» (текучих) сетках (fluid grids) и гибких изображений (flexible images). Media-запросы — ядро, управляющее адаптивными сайтами, но они эффективны лишь в том случае, когда дизайн сайта тоже является адаптивным. В этой статье я познакомлю вас с некоторыми идеями, относящимися к двум другим стержням адаптивного веб-дизайна. Я начну с обзора ряда перспективных модулей CSS-разметки (CSS layout modules), а затем расскажу о том, как сделать элементы, отличные от текста, например изображения и встроенное видео, такими же адаптивными. Попутно я отмечу некоторые инфраструктуры и библиотеки, помогающие в этом деле. Я также упомяну кое-какие популярные инфраструктуры для создания мобильных веб-приложений, а в заключение кратко рассмотрю применение HTML5 для создания «родных» приложений. К тому моменту, когда вы прочитаете эту статью, вы должны получить четкое представление о том, как приступить к реализации адаптивного веб-дизайна в своих приложениях.
Резиновые сетки и разметки
Использование сетки для группирования строк (typographic design) — методика, которая в той или иной форме практикуется столетиями и была изобретена даже раньше, чем наборный шрифт (moveable type). Такая двухмерная структура состоит из пересекающихся вертикальных и горизонтальных осей, позволяющих дизайнеру выравнивать и упорядочивать элементы в разметке так, чтобы они приятно смотрелись (рис. 1). За последние несколько лет веб-дизайнеры начали применять многие из тех же принципов в своих цифровых работах, а ряд популярных инфраструктур вроде 960 Grid System (960.gs) и Semantic Grid System (semantic.gs) теперь делают разметку сеткой доступной всем.
Рис. 1. Типографская сетка
Однако прямое использование типографской сетки в Web имеет явный недостаток: печатные разметки фиксированы, а веб-разметки — нет. Более того, многие реализации сеток не особо поддерживают семантику, что требует добавления разметки для определения сетки и приводит к смешению визуализируемых элементов с контентом ваших HTML-страниц.
Чтобы сетки (или разметки) были по-настоящему резиновыми, они должны подстраиваться под изменения.
А это ведет нас к понятию «резиновый» (fluid) в термине Маркотта «резиновая сетка» (fluid grid). Чтобы сетки (или разметки) были по-настоящему резиновыми, они должны подстраиваться под изменения. Как я говорил в прошлой статье, media-запросы помогают определять правила для изменения позиции элементов, но для эффективного применения этих правил такие элементы нужно сначала определить в резиновом или гибком контейнере. Ранее упомянутые мной инструменты (равно как и многие другие) действительно решают эту проблему либо «родными» средствами (Semantic Grid), либо через использование дополняющей библиотеки (Adapt.js для 960 Grid, см. adapt.960.gs), но, помимо этого, появляются новые CSS-модули, которые помогают в создании резиновых разметок.
Заметьте, что я несколько вольно обращаюсь с термином Маркотта «резиновые сетки», называя их также и резиновыми разметками (fluid layouts). Я делаю так потому, что некоторые из новых CSS-модулей, хоть и не основаны на сетке, все равно помогают создавать резиновые, адаптируемые контейнеры.
Давайте сначала рассмотрим CSS3 Flexible Box Layout Module (или Flexbox), который можно найти по ссылке bit.ly/yguOHU. Flexbox помогает создавать контейнеры разметки для элементов, которые будут автоматически позиционировать свои дочерние элементы в горизонтальном или вертикальном направлении, и предоставляет поддержку автоматического изменения интервалов (Goodbye "ul li { float: right; }"!). Этот модуль поддерживается (с префиксами поставщиков браузеров) в Internet Explorer 10 Platform Preview, Firefox, Chrome, Safari, iOS Safari и Android (детали см. по ссылке caniuse.com/flexbox).
Мы начнем с применения Flexbox к сайту Photo Gallery, о котором я говорил в прошлый раз. При использовании CSS, показанной на рис. 2, вы увидите результат, слегка стилизованный в иллюстративных целях на рис. 3. Пожалуйста, обратите внимание на то, что в CSS с рис. 2 используется только префикс поставщика «-ms-». В пример кода, который содержится в пакете скачиваемого кода для этой статьи (code.msdn.microsoft.com/mag201205HTML5), я включил и другие префиксы поставщиков (-webkit, -moz, -o).
Рис. 2. CSS для использования модуля Flexbox
ul.thumbnails {
width: 100%;
background: #ababab;
display: -ms-box;
-ms-box-orient: horizontal;
-ms-box-pack: center;
-ms-box-align: center;
}
ul.thumbnails li {
-ms-box-flex: 1;
}
Рис. 3. Изображения Photo Gallery с примененным Flexbox
Симпатично, конечно, но выглядит примерно так же, как и раньше. Чтобы увидеть гибкость Flexbox, измените размер окна своего браузера или откройте эту страницу на мобильном устройстве или в их эмуляторе. В этом примере не определены никакие media-запросы, и тем не менее разметка оказывается более гибкой. Скомбинируйте эти два модуля и вы сможете создать резиновые контейнеры, которые выравнивают, сдвигают элементы и меняют интервалы между ними в зависимости от изменения размеров окна. Например, можно создать правило media-запроса для экранов менее 480 пикселей, изменить ориентацию прямоугольника на вертикальную, и вуаля — у вас появилась начальная разметка для мобильных устройств.
CSS Grid Layout (или просто CSS Grid), которую можно найти по ссылке bit.ly/ylx7Gq, — более новая спецификация, переданная на рассмотрение в W3C CSS Working Group в апреле 2011 года и в настоящее время реализованная только в Internet Explorer 10 Consumer Preview. Идея в том, чтобы предоставить надежную «родную» поддержку сеток в браузерах. Разработчики и дизайнеры получат богатую типографскую сетку, которая избавит их от необходимости создавать табличные структуры или семантически нейтральную разметку.
CSS Grid позволяет разметить страницу заранее определенными строками и столбцами, а также определить правила, указывающие, как контент будет размещаться в этих элементах и вокруг них. Первый шаг — определение контейнера сетки (grid container) с указанием «grid» в качестве значения свойства display для выбранных элементов:
body {
display: -ms-grid; // префикс поставщика обязателен
}
Здесь я выбираю элемент body, что приведет к охвату моей сеткой всего документа. Это не обязательно, и я мог бы легко смастерить сетку из меньшей секции страницы или даже определить несколько сеток на одной странице. После определения сетки нужно определить размеры ее строк и столбцов:
body {
display: -ms-grid;
-ms-grid-rows: 50px 30% 20% auto;
-ms-grid-columns: 75px 25px 2fr 1fr;
}
А здесь указываю сетку из четырех столбцов и четырех строк, для одних делая размер абсолютным (например, 50px, 75px), для других — относительным размеру окна (30%, 20%) и автоматически изменяемым в зависимости от ширины его контента (auto). Я также использую новую числовую единицу fr (fraction), которая определена в спецификации CSS Grid как «…доля доступного пространства». Значения fr вычисляются после присваивания фиксированных размеров пропорциональным делением оставшегося пространства между всеми строками и столбцами, определенными с этими значениями. В контексте моего примера это означает, что, поскольку под столбцы 1 и 2 суммарно зарезервировано 100 пикселей, столбец 3 получит две трети оставшегося пространства, а столбец 4 — одну треть.
Определив сетку, можно легко позиционировать дочерние элементы в сетке, присваивая им номера строк и столбцов, например:
#main {
-ms-grid-row: 2;
-ms-grid-column: 2;
-ms-grid-row-span: 2;
-ms-grid-row-align: center;
}
Я помещаю свой главный (main) секционирующий элемент (sectioning element) во вторую строку и второй столбец сетки. Также разрешаю этому элементу охватить две строки и центрирую контент внутри этого контейнера. На сайте Microsoft Internet Explorer Test Drive Demo используется своя реализация CSS Grid Layout для создания точной реализации популярного сайта Grid System (thegridsystem.org), и вы можете сами убедиться в этом по ссылке bit.ly/gEkZkE.
Если вы когда-нибудь пробовали сделать нечто подобное с помощью обычной разметки и CSS2.1, то, несомненно, поймете ту гибкость, которую может обеспечить CSS Grid. Более того, CSS Grid в сочетании с media-запросами можно использовать для создания адаптивных структур, которые легко настраиваются изменением меньшего количества правил, когда пользователи подстраивают размер устройства и меняют его ориентацию.
Последняя спецификация разметки, которую я хотел представить в этой статье, — CSS Multi-Column Layout Module, которую вы найдете по ссылке bit.ly/yYEdts. CSS Multi-Column находится на стадии «Candidate Recommendation» (bit.ly/x5IbJv) и широко поддерживается всеми браузерами, в том числе планируется поддержка в Internet Explorer 10. Multi-Column позволяет размечать столбцы на странице без позиционирования вручную. Вам достаточно применить свойство column-width (с префиксами, если это необходимо) к контейнеру, например:
article {
width: 960px;
column-width: 240px;
}
При таком правиле элементы статьи будут разделены на столбцы (колонки) по 240 пикселей — их будет создано столько, сколько позволит контейнер (в данном случае четыре столбца по 240 пикселей заполнят контейнер размером 960 пикселей). Я мог бы также воспользоваться свойством column-count для определения фиксированного количества столбцов, и тогда размеры столбцов были бы равномерно распределены по ширине моего контейнера.
Как и в случае с модулями Flexbox и Grid, комбинирование этого модуля с media-запросами дает возможность быстро определять простые, адаптивные правила для обеспечения удобства использования на мобильных устройствах.
Описанные мной три модуля имеют много общего, и каждый из них предлагает свои функции, позволяющие создавать вариации резиновых разметок, который являются обязательными для веб-сайтов с настоящей адаптивностью. Я советую поэкспериментировать с каждым из них, чтобы вы могли выбрать подходящий модуль, когда будете решать конкретную задачу, связанную с разметкой.
В мире адаптивного веб-дизайна — особенно для мобильных решений — наибольшие затруднения вызывает медийная информация.
Советую также изучить появляющиеся инфраструктуры, которые используют эти спецификации. Применение одной из них может резко ускорить создание резиновых разметок для ваших сайтов. Две достойные внимания инфраструктуры — это Skeleton (getSkeleton.com) и Bootstrap (twitter.github.com/bootstrap), начальный набор от Twitter. Недавно я перестроил один из своих сайтов с помощью Skeleton (зайдите на html5tx.com).
Медийная информация в адаптивном веб-дизайне
В мире адаптивного веб-дизайна — особенно для мобильных решений — наибольшие затруднения вызывает медийная информация. Начнем с изображений. Один из простейших способов применения стилей к изображениям для повышения их адаптивности — добавить в таблицы стилей следующее:
img {
max-width: 100%;
}
Это правило будет всегда масштабировать ваши изображения (увеличивать или уменьшать) под размеры родительского контейнера. Таким образом, если элементы-контейнеры отвечают требованиям адаптивного веб-дизайна (возможно, по одной из ранее описанных методик), то и ваши изображения будут адаптивными.
Трудность этого способа в том, что изображения на сайте должны быть достаточно большими, чтобы их можно было масштабировать до любого размера без потерь качества. На сайте Photo Gallery, которым я пользовался, исходные изображения весьма велики, и поэтому их размеры можно изменять как угодно.
Однако использование огромных масштабируемых изображений создает крупные проблемы на мобильных устройствах: издержки передачи таких изображений слишком высоки. Даже если вы масштабируете крупное изображение под окно размером 320 × 240, на устройство все равно передается полное изображение. Это означает, что потенциально возможны ситуации, когда вы передаете картинку размером 2 Мб, когда для устройства требуется та же картинка, но размером всего 10 Кб. В мире мобильных устройств полоса пропускания все еще имеет значение, поэтому нужны другие подходы.
К сожалению, эта задача по-прежнему остается трудной, и в настоящее время W3C официально не поддерживает никаких конкретных подходов. Для работы с адаптивными изображениями существует ряд способов, но все они попадают в одну из двух категорий: либо задача решается на сервере, либо попытка ее решения возлагается на клиент. Многие серверные подходы вроде описанного по ссылке bit.ly/rQG0Kw опираются на использование изображений-заполнителей (placeholder images) размером 1 × 1 пиксель, клиентские cookie и правила, модифицируемые сервером (server-rewrite rules), чтобы передавать корректные изображения на соответствующие устройства. Клиентские подходы (один из них описан по ссылке bit.ly/tIdNYh) часто используют JavaScript, переключение на <noscript>, условные комментарии и некоторые любопытные трюки в CSS. Оба типа подходов смахивают на хакерские фокусы (и по сути ими являются), но они отражают максимум возможного, что можно сделать на данный момент с ограничениями тега <img>. В краткосрочной перспективе будет разумным изучить оба подхода и решить, какой из них подойдет для ваших приложений.
Однако в долгосрочной перспективе вы можете надеяться на лучшее. В статье «HTML5 Semantics» в журнале «Smashing Magazine» (bit.ly/rRZ5Bl) Брюс Лосон (Bruce Lawson), один из разработчиков Opera, агитирует за добавление элемента <picture>, который вел бы себя аналогично тегам <audio> и <video>, подразумевая, что программисты должны иметь возможность доступа к нескольким дочерним элементам <source> внутри родительского <picture>. В сочетании с подставляемыми в строку media-запросами, новый элемент <picture> мог бы наконец-то предоставить надежное решение для поддержки адаптивных изображений:
<picture alt="cat gallery">
<source src="nyan-high.png" media="min-width:800px" />
<source src="nyan-med.png" media="min-width:480px" />
<source src="nyan-low.png" />
<!-- резервный вариант для старых браузеров -->
<img src="nyan-med.png" alt="cat gallery" />
</picture>
Хотя это решение завоевало популярность и вокруг него была сформирована W3C Community Group (bit.ly/AEjoNt), официальной рабочей группы W3C так и не было создано, насколько мне известно. Возможно, в свое время, в HTML6, мы увидим этот элемент.
Аналогичные трудности вызывает и добавление адаптивного видео на сайты или в приложения, хотя в HTML5 для видео существуют более надежные, чем для изображений решения. Начнем с того, что для <video> поддерживается элемент <source>, расширенный поддержкой media-запросов (как это предлагалось для ранее упомянутого вымышленного элемента <picture>):
<video>
<source src="nyan-mashup-high.webm"
media="min-width:800px" />
<source src="nyan-mashup-med.webm" media="min-width:480px" />
<source src="nyan-mashup-low.webm" />
<!-- Здесь вставьте резервный вариант
с Silverlight или Flash -->
</video>
Если вы обслуживаете видеопотоки со своих серверов или используете сервис, который предоставляет несколько версий для встраивания, то я настоятельно рекомендую применять этот синтаксис, чтобы передавать пользователям подходящие для их устройств видеопотоки.
В мире мобильных устройств полоса пропускания все еще имеет значение.
Хотя это решение поможет сэкономить полосу пропускания сетевых соединений ваших пользователей, вам все равно нужно подумать о масштабировании этих встраиваемых элементов — так же, как и в случае с изображениями. С помощью media-запросов эти элементы video легко адаптировать в зависимости от размеров экрана, но, если вы ищете более автоматизированное решение, рассмотрите FitVids.js (fitvidsjs.com), jQuery-плагин, который будет автоматически делать ваши элементы video резиновыми и адаптивными. Но учтите, что это решение (как jQuery-плагин) не будет работать для пользователей, в браузерах которых отключена поддержка JavaScript.
Создание мобильных веб-приложений с использованием HTML5-инфраструктур
Теперь. когда вы знаете о двух других стержнях адаптивного веб-дизайна (резиновых разметках и гибких изображениях), давайте немного поговорим о тех случаях, где вы создаете не просто дружественные к мобильным устройствам веб-сайты или приложения, а ориентируетесь исключительно на такие устройства.
В мире разработки традиционные настольные (или клиентские) и веб-парадигмы открыли путь третьему типу приложений, часто называемых «родными» (native applications), так как они размещаются на определенном устройстве (смартфоне на основе Windows Phone или на iPad, например), создаются с использованием инфраструктур, специфичных для данных устройств (iOS и Android) и устанавливаются через App Store или Marketplace.
Как бы ни были функциональны и надежны эти инфраструктуры, иногда веб-разработчики хотят добиться аналогичного «духа и буквы» в своих мобильных веб-приложениях. Такие приложения по-прежнему работают на серверах и могут доставляться вне рамок App Store или Marketplace.
Хотя вы определенно можете создавать приложения этих типов вручную, гораздо удобнее использовать для этого инфраструктуры. Одна из популярных инфраструктур для мобильных веб-приложений — jQuery Mobile (jquerymobile.com), которая обеспечивает UI-систему на основе HTML5, ориентированную практически на каждую мобильную платформу. На рис. 4 показан пример мобильного приложения для OpenTable.com, построенного с применением jQuery UI.
Рис. 4. Пример экрана, созданного с помощью jQuery Mobile
Другой популярный вариант для создания мобильных приложений с «родным» для мобильных устройств внешним видом — Kendo UI Mobile (kendoui.com), инфраструктура на основе HTML5, JavaScript и CSS от Telerik Inc. Kendo UI позволяет создавать мобильные приложения, которые выглядят точно так же, как родные программы для устройств на базе iOS и Android, и используют единую кодовую базу. На рис. 5 и 6 показана эта функциональность, которую вы можете проверить сами по ссылке bit.ly/wBgFBj.
Рис. 5. Мобильное демонстрационное приложение Kendo UI, просматриваемое на устройстве с iOS
Рис. 6. Пример мобильного приложения Kendo UI, просматриваемого на устройстве с Android
Создание родных приложений с помощью HTML5
Придание веб-приложениям родного для мобильных устройств внешнего вида — отличный способ не только применения на практике ваших знаний как веб-разработчика, но и создания приложений, удовлетворяющих ожиданиям пользователей мобильных устройств. Тем не менее, эти приложения пока не могут заходить дальше использования встроенных датчиков и родных API на этих устройствах. Если некоторые функции вроде геопозиционирования предоставляются мобильным браузерам, то многие другие (например, акселерометр или видео) — нет. Чтобы получить доступ к таким функциям, по-прежнему приходится разрабатывать программы, родные для каждой платформы.
Но есть и хорошие новости: популярность веб-программирования подтолкнула технологии HTML5, JavaScript и CSS к тому, что они «становятся родными». Популярные инфраструктуры наподобие PhoneGap (phonegap.com) и Titanium Appcelerator (appcelerator.com) позволяют использовать HTML5 и JavaScript для создания родных приложений под iOS, Android и Windows Phone с доступом к аппаратным API. Более того, инфраструктуры разработки мобильных приложений вроде jQuery Mobile и Kendo UI Mobile работают так же хорошо в этих средах, как и в браузере. На рис. 7 показано родное для iOS приложение, построенное с использованием PhoneGap и Kendo UI. Подробнее на эту тему см. публикацию в блоге по ссылке bit.ly/zpIAPY.
Рис. 7. Приложение iOS, построенное с помощью HTML, JavaScript и CSS
Microsoft вывела разработку родных веб-программ на новый уровень, официально добавив в Windows 8 поддержку создания приложений с применением HTML5, JavaScript и CSS, причем без дополнительных абстракций или инфраструктур. Вы можете посмотреть предварительную версию Windows 8 для потребителей, а также новые средства разработки для различных платформ по ссылке dev.windows.com.
Когда дело доходит до мобильной Web, у вас появляется выбор! Если вы являетесь веб-разработчиком, желающим создавать родные приложения с функциональностью дополненной реальности (augmented reality), подумайте о применении Windows 8 или одной из инфраструктур, такой как PhoneGap или Titanium Appcelerator. Если вас интересует лишь родной внешний вид программ, выполняемых в браузере, присмотритесь к jQuery UI и Kendo UI Mobile. Наконец, если ваша цель — создание единого веб-сайта или приложения, которое отвечает на запросы с разнообразных мобильных устройств, попробуйте использовать адаптивные стратегии, обсуждавшиеся в этой и прошлой статьях. Несомненно, что сейчас мобильные устройства — самый лакомый кусочек рынка для всевозможных разработок. Лучший вариант для вас (независимо от выбранных стратегий или платформ) — сделать разработку мобильных приложений высшим приоритетом.