Современные приложения

Создание современного UI с помощью CSS для WinJS-приложений

Рэчел Аппель

Rachel AppelРабота с 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>

Common HTML and WinJS Controls in Dark Default Style
Common HTML and WinJS Controls in Light Default Style
Рис. 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).

Область вывода в сочетании с рабочей областью образуют элемент управления ListView
Рис. 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).