Современные приложения
Создание современного UI с помощью CSS для WinJS-приложений
Работа с CSS вызывает вопросы у многих разработчиков, так как в ней полно всяких нюансов. Даже малозначимые изменения в одном селекторе или HTML-элементе зачастую распространяются и влияют на другие элементы. Сохранение четкости и эффективности CSS может оказаться трудной задачей, учитывая массу странностей в поведении, особенно при ориентации на несколько браузеров. К счастью, если вы разрабатываете приложения с применением Windows Library for JavaScript (WinJS), то CSS, встроенный в шаблоны проектов Visual Studio, является достаточно гибким и в то же время согласованным и поддающимся сопровождению. Шаблоны проектов Visual Studio содержат код, который служит фундаментом для дизайна современных и адаптивных UI.
Встроенный CSS для приложений Windows Store
Все шаблоны проектов для приложений Windows Store, создаваемых на JavaScript, содержат две базовых таблицы стилей, или тем (themes) — темную (по умолчанию) и светлую — в файлах с именами ui-dark.css и ui-light.css соответственно. Эти файлы являются частью базового набора файлов проекта в папке CSS в узле ссылок проекта Visual Studio. В этих базовых CSS-файлах примерно 4000 строк CSS-кода, поскольку они конструируют UI, соответствующий всем принципам дизайна UI в Windows, в том числе реакцию на режим прикрепления (snap view) в Windows и изменения в media-типах. Не пытайтесь модифицировать встроенные таблицы стилей (они доступны только для чтения) — для замены встроенных стилей используйте собственные CSS-файлы.
Чтобы задействовать CSS, встроенный в приложение Windows Store, добавьте следующую ссылку на раздел <head> какой-либо страницы (заметьте, что «2.0» в ссылке предназначено для Windows 8.1, а для Windows 8 нужно указывать «1.0»):
<link href="//Microsoft.WinJS.2.0/css/ui-dark.css" rel="stylesheet" />
Два прямых слеша в начале пути указывают ссылку на базовую библиотеку WinJS (также называемую как общие библиотеки в противоположность локальным файлам проекта в вашем пакете приложения). Пути в приложениях Windows Store, создаваемых на JavaScript, которые начинаются с одного прямого слеша обозначают начало пути от корневой папки проекта и относятся к локальным файлам проекта.
Приложения Windows Store, создаваемые на JavaScript, используют префиксы поставщика (например, -ms-grid, -flexbox и др.), чтобы приложениям был доступен наиболее продвинутый с технологической точки зрения CSS. Другие продвинутые средства CSS, которые могут включаться в WinJS-приложение, — это цвета CSS3 RGBA, шрифты Web Open Font Format (WOFF) и media-запросы.
Стилизация элементов управления WinJS с помощью CSS
Элементы управления WinJS являются расширениями HTML-элементов, поэтому вы применяете стиль к элементам управления WinJS с помощью CSS точно так же, как вы делали бы это с любым HTML-тегом. Шаблоны проектов Visual Studio содержат ссылки на CSS, который создает стили современного UI для каждого HTML-элемента и элемента управления WinJS — в темной и светлой темах. Конечно, вы не ограничены только этими стилями и можете свободно модифицировать их так, как вам нужно. Однако важно поддерживать согласованность с новым Windows UI, чтобы не сбивать с толку пользователей.
На рис. 1 показан код для нескольких базовых и распространенных элементов управления HTML и WinJS, использующих как темную, так и светлую темы. Вывод, получаемый при выполнении этого кода, представлен на рис. 2.
Рис. 1. Код для базовых элементов управления HTML и WinJS
<div id="grid">
<div style="-ms-grid-column: 1; -ms-grid-row: 1">
<label for="textbox">Textbox:</label>
<input id="textbox" type="text" />
</div>
<div style="-ms-grid-column: 2; -ms-grid-row: 1">
<label for="button">Button:</label>
<button id="button" value="Button">Clickety Click</button>
</div>
<div style="-ms-grid-column: 1; -ms-grid-row: 2">
<label for="radio">Radio:</label>
<input type="radio" id="radio" name="radio" />
<label for="radio">One</label>
<input type="radio" id="radio" name="radio" />
<label for="radio">Two</label>
<input type="radio" id="radio" name="radio" />
<label for="radio">Three</label>
</div>
<div style="-ms-grid-column: 2; -ms-grid-row: 2">
<label for="select">Select:</label>
<select id="select">
<option value="One">One</option>
<option value="Two">Two</option>
<option value="Three">Three</option>
</select>
</div>
<div style="-ms-grid-column: 2; -ms-grid-row: 3">
<label for="rating">Rating:</label>
<div id="rating" data-win-control="WinJS.UI.Rating"></div>
</div>
<div style="-ms-grid-column: 1; -ms-grid-row: 3">
<label for="toggle">Toggle:</label>
<div id="toggle" data-win-control="WinJS.UI.ToggleSwitch"></div>
</div>
<div style="-ms-grid-column: 1; -ms-grid-row: 4">
<label for="datepicker">Date Picker:</label>
<div id="datepicker" data-win-control="WinJS.UI.DatePicker"></div>
</div>
<div style="-ms-grid-column: 2; -ms-grid-row: 4">
<label for="timepicker">Time Picker:</label>
<div id="timepicker" data-win-control="WinJS.UI.TimePicker"></div>
</div>
</div>
Рис. 2. Распространенные элементы управления HTML и WinJS в темном и светлом стилях
Как видно из рис. 2, стили по умолчанию для элементов управления отражают новый дизайн Windows UI. Полный список элементов управления HTML и WinJS доступен в Windows Dev Center (bit.ly/w1jLM5).
Подробное обсуждение элементов управления WinJS см. в моей статье «Mastering Controls and Settings in Windows Store Apps Built with JavaScript» (msdn.microsoft.com/magazine/dn296546). Тем временем я рассмотрю правила стилизации нескольких важных элементов управления: AppBar, Flyout и ListView.
AppBar Эти элементы являются важными компонентами UI в любом приложении Windows Store. CSS-селекторы существуют для применения стилей к любой части AppBar, в том числе к AppBar в целом, меткам, изображениям и всплывающим подсказкам индивидуальных элементов Button в разных состояниях (обычным и при задержке курсора мыши над элементом). Это означает, что вы получаете полный контроль над внешним видом элементов AppBar. Применив свои стили к самому AppBar путем перезаписи класса .win-appbar, вы можете переходить к индивидуальным командам. Поскольку кнопки в AppBar являются элементами управления WinJS, атрибут data-win-options содержит всю необходимую информацию для должной настройки командных кнопок, используя свойства label, icon, section и tooltip:
<div id="appbar" class="win-appbar"
data-win-control="WinJS.UI.AppBar">
<button data-win-control="WinJS.UI.AppBarCommand"
data-win-options="{
id:'addFriend',
label:'Add Friend',
icon:'addfriend',
section:'global',
tooltip:'Add a friend'}"
type="button">
</button>
</div>
Вы можете придать AppBar совершенно другой вид, отличный от простой полоски по умолчанию внизу экрана, модифицируя стили следующих селекторов классов (class selectors):
- .win-appbar — стили AppBar в целом;
- .win-command — стили индивидуальных кнопок AppBar;
- .win-commandimage — стили изображения командной кнопки;
- .win-commandring — стили кольца вокруг кнопки AppBar;
- .win-commandimage:hover и .win-commandring:hover — стили изображения командной кнопки и кольца при наведении курсора мыши на кнопку.
Flyout Эти элементы являются интерактивными всплывающими окнами. В приложениях Windows Store вы обычно реализуете элементы Flyout для получения пользовательского ввода — нередко при нажатии чудо-кнопки Settings приложения. Эти элементы — отличный способ реализации настроек или хранения каки-то данных, к которым часто обращается пользователь. Например, их можно использовать для вывода заявления о конфиденциальности личных данных, обязательного для принятия приложения в Windows Store. Для стилизации Flyout достаточно перезаписать селектор .win-flyout. Системный CSS содержит параметры для .max-width и .max-height, поэтому, если нужно получить полную форму данных, вам может понадобиться их регулировка.
Flyout — это элемент <div>, который остается скрытым, пока пользователь не вызовет его чудо-кнопкой или командой в AppBar; после вызова этот элемент всплывает на экране. Хотя в Flyout находятся другие элементы управления, их стилизация не изменяется, так как они являются HTML-элементами.
ListView Это, по-видимому, самый сложный элемент управления WinJS. Он позволяет отображать множество элементов данных в сетке или списке. ListView также реагирует на события касания и мыши, инициируемые пользователем, что дает возможность выбирать элемент или вызывать какую-либо операцию. В Windows 8.1 элемент управления ListView также позволяет перетаскивать элементы и переупорядочивать их.
Прежде чем использовать элемент управления ListView, вы должны знать, как он работает. ListView состоит из четырех основных «деталей»: самого ListView, области вывода (viewport), рабочей области (surface area) и элементов. Элементы находятся в рабочей области, которая является прокручиваемой частью ListView. Рабочая область существует и перемещается в пределах области вывода, поэтому понятно, почему полосы прокрутки расположены в области вывода (рис. 3).
Рис. 3. Область вывода в сочетании с рабочей областью образуют элемент управления ListView
Совместно область вывода и рабочая область с элементами образуют элемент управления ListView. Поскольку ListView содержит такие по-разному функционирующие части, его стилизация выполняется по множеству правил, обрисованных в Windows Dev Center (bit.ly/HopfUg). Пока что я рассмотрю самое важное, что вам нужно знать о применении стилей к ListView:
- .win-listview — стили для всего ListView;
- .win-viewport — стили для области вывода ListView;
- .win-surface — стили для прокручиваемой области ListView.
Эти детали позволяют делать такие вещи, как применять фоновое изображение, которое прокручивается вместе с элементами. Когда рабочая область больше области вывода, в последней появляются полосы прокрутки (вертикальная и/или горизонтальная).
Применять стили к элементам ListView несложно. Вы должны использовать классы .win-item и .win-container. Каждый элемент в ListView находится в контейнере, который хранит изображение и текстовые поля элемента. Этот контейнер на самом деле является просто HTML-шаблоном, определяющим элементы, сочетание которых образует элемент в ListView. В коде на рис. 4 показано, как определить этот шаблон и соответствующий ему ListView. Данный код создает элемент управления WinJS.Binding.Template, используемый ListView для отображения данных.
Рис. 4. Код, определяющий шаблон и соответствующий ему ListView
<div id='listviewtemplate' class="itemtemplate"
data-win-control="WinJS.Binding.Template">
<div class="item">
<img class="item-image" src="#"
data-win-bind="src: backgroundImage; alt: title" />
<div class="item-overlay">
<h4 class="item-title" data-win-bind="textContent: title"></h4>
<h6 class="item-subtitle win-type-ellipsis"
data-win-bind="textContent: subtitle"></h6>
</div>
</div>
</div>
<div class="groupeditemslist win-selectionstylefilled"
aria-label="List of groups"
data-win-control="WinJS.UI.ListView"
data-win-options="{ selectionMode: 'none' }">
</div>
На рис. 4 показаны элементы <div>, образующие шаблон элемента в ListView, встроенный в шаблоны проектов Grid и Split. В период выполнения механизм исполнения приложения вводит в эти элементы классы .win-container и .win-item, поэтому вы не увидите эти селекторы в коде при разработке, но можете перезаписать их в CSS-файле, чтобы применять свои стили. В коде ListView шаблона проекта .item, .item-image, .item-title, .item-subtitle и .item-overlay доступны как селекторы, которые можно модифицировать для определения внешнего вида каждого индивидуального элемента в сетке.
Списки или сетки нельзя считать законченными без поддержки сортировки, группирования и других операций, влияющих на их члены. Поэтому, разумеется, есть стили как для сгруппированных элементов, так и для индивидуальных. Стиль применяется к заголовкам группы перезаписью селектора класса .win-groupheader; можно также перезаписывать .win-progress.
Адаптивный CSS для «отзывчивых» UI
Проекты Grid, Split и Navigation в Visual Studio содержат WinJS-селекторы CSS, которые в тандеме с семантическими элементами HTML5 обеспечивают адаптивную и современную разметку. Код на рис. 5 показывает CSS и HTML, необходимые для создания разметки сетки из шаблона Grid. Заметьте, что класс .fragment определяет строки и поля сетки, используя префиксы -ms-grid-columns и -ms-grid-rows. Эти префиксы и другие селекторы потом применяются к элементам <div> на рис. 5. Семантические элементы <header> и <section> четко определяют, какой тип контента в них помещается.
Рис. 5. Фундаментальные HTML и CSS для фрагмента страницы
.fragment {
/* Определяет сетку со строками для баннера и тела */
display: -ms-grid;
-ms-grid-columns: 1fr;
-ms-grid-rows: 128px 1fr;
height: 100%;
width: 100%;
}
.fragment header[role=banner] {
/* Определяет сетку с полями для кнопки Back и заголовка страницы */
display: -ms-grid;-ms-grid-columns: 39px 81px 1fr;
-ms-grid-rows: 1fr;
}
.fragment header[role=banner] .win-backbutton {
-ms-grid-column: 2;
margin-top: 59px;
}
.fragment header[role=banner] .titlearea {
-ms-grid-column: 3;
margin-top: 37px;
}
.fragment header[role=banner] .titlearea .pagetitle {
width: calc(100% - 20px);
}
.fragment section[role=main] {
-ms-grid-row: 2;
height: 100%;
width: 100%;
}
<div class="fragment groupeditemspage">
<header aria-label="Header content" role="banner">
<button class="win-backbutton" aria-label="Back"
disabled type="button"></button>
<h1 class="titlearea win-type-ellipsis">
<span class="pagetitle">CSS in Windows Store apps</span>
</h1>
</header>
<section aria-label="Main content" role="main">
<div class="groupeditemslist win-selectionstylefilled"
aria-label="List of groups"
data-win-control="WinJS.UI.ListView"
data-win-options="{ selectionMode: 'none' }">
</div>
</section>
</div>
Поскольку этот CSS является частью шаблонов проектов Grid и Split, вам не придется возиться со скучной задачей создания адаптивной сетки, изменяемой на основе изменений в данных или состоянии приложения, — все, что нужно, уже встроено.
Шаблоны приложений Windows Store на JavaScript используют блочную модель CSS (CSS box model) (см. мою статью в блоге «A guide to element display and positioning with the CSS Box Model» по ссылке bit.ly/xxATgL) для разметки страницы и разметку CSS-сетки для создания «отзывчивого» UI (детали см. на сайте W3C по ссылке bit.ly/14yzx2h). Заметьте, что сетка превращается в вертикальный список и наоборот при переключении между режимом прикрепления или полноэкранным режимом.
В большинстве исходных шаблонов проектов в приложениях Windows Store используются преимущества media-запросов CSS, чтобы предоставить изощренный UI, реагирующий на изменения ориентации и разрешения экрана устройства, а также размеров браузера. Если вы хотите узнать больше о media-запросах, см. мою статью в блоге «Create mobile site layouts with CSS Media Queries» по ссылке bit.ly/1c39mDx.
Другая причина, по которой приложения Windows Store используют media-запросы, связана с тем, что Windows 8 поддерживает четыре состояния приложений: полноэкранное (full), прикрепленное (snap), заполненное (filled) и портретное (portrait). Когда пользователи переводят приложение в режим прикрепления или заполнения, с концептуальной точки зрения это равнозначно обращению к приложению с другого устройства, поскольку размеры и ориентация окна браузера меняются весьма радикально.
Изучая встроенный CSS, вы обнаружите много правил @media для этих четырех состояний приложения, а также для режимов просмотра с высоким контрастом и поддержкой специальных возможностей. Вот media-запросы, которые распознают режим прикрепления и состояние fullscreen-portrait:
@media screen and (-ms-view-state: snapped) {}
@media screen and (-ms-view-state: fullscreen-portrait) {}
Обычно CSS, работающий для полноэкранного режима, работает и в заполненном режиме (три чтеверти экрана). Предыдущие запросы представляют две важнейшие медийные возможности в мире приложений Windows Store, но таких возможностей гораздо больше (см. сайт W3C по ссылке bit.ly/gnza0F).
Приложения Windows Store используют эффективный и организованный CSS
Посмотрите на селекторы CSS, встроенного в шаблоны Visual Studio, и вы заметите, что они очень четкие и точные. Читаемость CSS (как, впрочем, и любого другого кода) позволяет в итоге создавать легкие в сопровождении и эффективнее работающие приложения. Когда вы видите в коде «.fragment header[role=banner]», вы точно знаете, к каким элементам это применяется: в данном случае к элементу <header>, у которого есть атрибут role со значением «banner» внутри элемента, классифицируемого как fragment. Учтите, что браузеры разбирают CSS справа налево, самый специфичный селектор должен находиться в правой части, чтобы браузер быстрее находил подходящий DOM-элемент.
Вместо использования скрипта для переключения визуальных индикаторов применение некоторых CSS-средств вроде псевдоселекторов для hover, active, disabled, enabled и других визуальных состояний упрощает дальнейшее сопровождение кода. WinJS определяет псевдо-селекторы для многих элементов управления. Например, TextBox и CheckBox могут переключаться между состояниями disabled и enabled, а привязки (anchors) — между состояниями hover и active. Еще больше CSS-анимаций в Windows 8.1 (bit.ly/KDVSPU), поэтому проверьте их, прежде чем браться за написание кода на JavaScript для выполнения тех же анимаций.
Под эффективностью подразумевается не только должная организация файла, но и эффективный код. Файл default.css находится в папке \css, и все встроенные HTML-страницы содержат ссылки на него. В этом файле содержится CSS, который вы видели на рис. 5, наряду с правилами регулярных стилей и media-запросами. Вы можете модифицировать или удалить default.css в отличие от файлов ui-dark.css и ui-light.css.
Шаблоны проектов Visual Studio организуют файлы в папки, содержащие связанные элементы, например groupedItems.html, groupedItems.js и groupedItems.css в папке \pages\groupedItems наряду с другими похожими структурами. Вы можете придерживаться той же организации файлов в папки или переупорядочить эти файлы так, как вам нужно. Возможно, такая реорганизация структуры проекта понадобится, если вы захотите использовать шаблон Model-View-ViewModel (MVVM). В этом случае CSS-файлы могли бы помещаться в другую папку. Так или иначе, это не имеет значения — главное, чтобы ваша организация файлов имела смысл для проекта и была проста в сопровождении.
Ради читаемости разбейте CSS на отдельные файлы и упорядочите их по функциональности или средствам. Скажем, у вас мог бы быть CSS для одного элемента управления, используемого во многих страницах, такого как Flyout. Этот файл можно поместить в папку для общего CSS-кода или в ту же папку, что и Flyout. Нет ничего хуже, когда приходится с трудом продираться через CSS-файл, заполненный кодом, не имеющим ничего общего со страницами, которые на него ссылаются. Например, CSS, отвечающий следующим критериям, стоит выделять в свой файл:
- CSS для специфического элемента управления Flyout или страницы настроек;
- CSS, содержащий только цвета и прочие элементы эстетического оформления (позволяющий создавать темы). В этом случае вы сможете подменять CSS-файлы для переключения цветового оформления так, как вам нужно;
- CSS в media-запросах для специфического сценария, такого как режимы прикрепления или заполнения. Этот CSS можно выделить в свой файл в том же каталоге, где находится страница, которая ссылается на него.
Тем самым вы можете задействовать каждую функциональную единицу CSS так, как вам нужно, а не загружать весь CSS для каждой страницы независимо от того, использует она этот CSS или нет. Помните, что универсальных правил нет, каждый проект уникален и может предъявлять разные требования.
Проекты приложений Windows Store выполняют код, локальный для устройства, а не скачивают сразу же CSS или скрипт, поэтому нет нужды сводить к минимуму CSS и скрипты и заталкивать их в один пакет, как это делается в веб-проектах. Конечно, перед выполнением приложение должно загружать код в память, поэтому все равно следует избегать раздутого кода из соображений его производительности и читаемости.
Заключение
Применять стили ко многим встроенным элементам управления WinJS проще простого, так как инфраструктура предоставляет передовые средства CSS3 и HTML5. Базовый CSS в WinJS создает современный, адаптивный и гибкий UI, который реагирует на изменения в состоянии приложения, когда пользователь переключается между полноэкранным режимом и режимом прикрепления. Тот факт, что базовый WinJS CSS доступен в готовом виде, означает, что вы можете сосредоточиться на создании приложения, а не на разработке структурированного CSS, чтобы сформировать UI в современном стиле.
Рэчел Аппель (Rachel Appel) — консультант, автор, преподаватель и бывший сотрудник Microsoft более чем с 20-летним опытом работы в IT-индустрии. Она выступает на важнейших отраслевых конференциях, в частности Visual Studio Live!, DevConnections, MIX и др. Эксперт в области разработки приложений для бизнеса на основе стека технологий Microsoft и открытых стандартов Web. Если вы хотите узнать о ней больше, посетите ее сайт rachelappel.com.
Выражаю благодарность за рецензирование статьи эксперту Microsoft Эрику Шмидту (Eric Schmidt).