Макет
Использование CSS-сетки
Начиная с "Быстрый старт" , мы уже использовали CSS-сетку для многих целей. В особенности модель сетки нравится мне потому, что она позволяет вам без особых усилий задавать относительное расположение элементов и легко масштабируется под различные размеры экранов.
Так как этот курс направлен на особенности разработки для Windows 8, я оставляю задачу разъяснения всех подробностей о сетке спецификациям W3C: http://dev.w3.org/csswg/css3-grid-layout/ и http://www.w3.org/TR/css3-grid-layout/. Эти материалы представляют собой общие руководства, которые помогут в понмании того, как настраиваются размеры строк и столбцов, особенно когда некоторые из них объявлены с фиксированными размерами, кого размер некоторых зависит от содержимого, а другие заданы так, чтобы они заполняли оставшееся пространство. Здесь много тонкостей!
Так как эти спецификации, когда я пишу это, всё еще находятся в разработке, полезно точно знать, какие части спецификация реально поддерживаются подсистемой HTML/CSS, которой пользуются приложения для Магазина Windows.
Для элемента, содержащего сетку, поддерживаемые стили весьма просты. Во-первых, используйте модели отображения -ms-grid и -ms-inline-grid (стиль display:). Позже мы вернемся к -ms-inline-grid.
Во вторых, в элементах сетки используйте -ms-grid-columns и -ms-grid-rows для задания их расположения. Если оставить эти параметры незаданными, значение по умолчанию - это один столбец и одна строка. Поддерживается и синтаксис для задания повторяющихся конструкций, такой, как -ms-grid-columns: (1fr)[3];, что особенно удобно, когда у вас имеется повторяющиеся серии строк или столбцов, которые появляются внутри строк описаний. Как пример, следующие команды эквивалентны:
-ms-grid-rows:10px 10px 10px 20px 10px 20px 10px; -ms-grid-rows:(10px)[3] (20px 10px)[2]; -ms-grid-rows:(10px)[3] (20px 10px) 20px 10px; -ms-grid-rows:(10px)[2] (10px 20px)[2] 10px;
То, как вы задаёте строки и столбцы - вопрос достаточно интересный, так как вы можете сделать некоторые из них фиксированными, некоторые - гибко меняющими размеры, а некоторые - ориентированными на размер содержимого. Этих целей можно достичь, используя следующие значения. Опять же, посмотрите документацию по особенностями использования спецификаторов max-content, min-content, minmax, auto, и fit-content, вместе со значениями, которые задаются в таких единицах измерения, как px, em, %, и fr. Приложения для Магазина Windows, так же, поддерживают, в качестве единиц измерения, такие показатели, как vh (высота окна просмотра) и vw (ширина окна просмотра).
Внутри сетки, дочерние элементы располагаются в заданных строках и столбцах с заданными характеристиками выравнивания, объединения, расположения по слоям, используя следующие стили:
- -ms-grid-column - определяет базовый столбец (нумерация начинается с 1) в сетке для дочернего элемента.
- -ms-grid-row - определяет базовую строку (нумерация начинается с 1) в сетке для дочернего элемента.
- -ms-grid-column-align и -ms-grid-row-align задаёт то, как дочерний элемент будет расположен в ячейке сетки. Допустимые значения - start, end, center и stretch (по умолчанию).
- -ms-grid-column-span и -ms-grid-row-span показывает, будет ли дочерний элемент занимать одну строку и один столбец, или же несколько.
- -ms-grid-layer управляет тем, как элементы сетки перекрываются. Это похоже на стиль z-index, используемый для элементов, которые можно позиционировать. Так как дочерние элементы сетки не позиционируются напрямую из CSS, позиционируясь, вместо этого, в соответствии с сеткой, -ms-grid-layer позволяет управлять этим.
Обратите особое внимание на то, что нумерация строк и столбцов начинается с 1, а не с 0. Перепрограммируйте ваш ум, ориентированный на JavaScript для того, чтобы это запомнить, так как вам понадобится небольшая трансляция адресов в том случае, если вы храните дочерние элементы в массиве, нумерация которого начинается с 0.
Кроме того, обращаясь к любому из этих -ms-grid* стилей как к свойствам в JavaScript, опустите тире и переключитесь на написание адресов в "верблюжьем" (camel casing) стиле: msGrid, msGridColumns, msGridRowAlign, msGridLayer.
В итоге, работа с сетками не вызывает затруднений, особенно в Blend, где вы можете сразу же видеть их изменения. Посмотрим теперь на некоторые секреты и советы, которые могут оказаться полезными.
Переполнение ячейки сетки
Одна из замечательных, в зависимости от вашей точки зрения, возможностей сетки заключается в том, что содержимое может переполнять ячейку, не нарушая макета. Контент просто выходит за границы. (Это очень сильно отличается от таблиц). Это значит, что вы можете, если нужно, сдвинуть дочерний элемент в ячейке таким образом, что он перекроет смежную ячейку или ячейки. Кроме того, что это не нарушает макет, это делает возможность анимировать элементы путём перемещения между ячейками сетки, если нужно.
Пример содержимого, которое выступает за пределы содержащей его ячейки можно найти в упражнении GridOverflow в дополнительных материалах к этой лекции. Здесь создана сетка из прямоугольных элементов, 4х4, но нижеприведенный код, размещенный в конце функции doLayout (js/default.js) размещает первый прямоугольник за пределами ячейки:
children[0].style.width = "350px"; children[0].style.marginLeft = "150px"; children[0].style.background = "#fbb";
Это делает первый элемент в сетке шире и смешает его вправо, таким образом, он появляется внутри ячейки второго элемента (фон изменен для того, чтобы это было очевидно). В итоге макет сетки остаётся неизменным.
У меня есть некоторые сомнения, касающиеся того, хорошая ли это возможность, если речь идёт о случаях, когда вы ожидаете иного поведения сетки, желая, чтобы она меняла размер, подстраиваясь под содержимое. Если это - именно то, что вам нужно - попробуйте воспользоваться HTML-таблицей.
Вертикальная центровка содержимого
Где-то, в собственном опыте работы с CSS вы, возможно, сталкивались с неприятным поведением стиля vertical-align в попытке разместить фрагмент текста в центре или в нижней части элемента div. К несчастью, это не работает: этот стиль предназначен для ячеек таблицы и для встроенного содержимого (для того, чтобы задать, как текст и изображения, например, выравниваются относительно друг друга).
В результате, для того, чтобы это реализовать, было разработано множество методов. Например, об этом идет речь здесь: http://blog.themeforest.net/tutorials/vertical-centering-with-css/. К несчастью, практически все эти методы основаны на фиксированной высоте - а это может работать для веб-сайта, но не подходит для адаптивных макетов, в которых нуждаются приложения для Магазина Windows. И единственный метод, который не использует фиксированную высоту, основан на применении встраиваемой таблицы. Эх.
К счастью, и CSS-сетка, и гибкое окно (смотрите раздел "Макет элемента" ниже) позволяют легко решить эту проблему. В случае с сеткой, вы можете просто создать родительский элемент div с сеткой 1х1 и использовать стиль -ms-grid-row-align: center для дочернего элемента div (значение по умолчанию для которого - ячейка 1,1):
<!-- В HTML --> <div id="divMain"> <div id="divChild"> <p>Centered Text</p> </div> </div> /* В CSS */ #divMain { width: 100%; height: 100%; display: -ms-grid; -ms-grid-rows: 1fr; -ms-grid-columns: 1fr; } #divChild { -ms-grid-row-align: center; -ms-grid-column-align: center; /* Горизонтальное выравнивание текста так же работает с */ /* text-align: center; */ }
Решение этой проблемы даже проще с помощью макета на основе flexbox, где flex-align: center задаёт вертикальную центровку, flex-pack: center отвечает за горизонтальную центровку, и дочерний элемент div не нужен. Это тот же подход к стилизации, что применен в шаблоне Приложение с фиксированным макетом для центровки элемента ViewBox:
<!-- В HTML --> <div id="divMain"> <p>Centered Text</p> </div> /* В CSS */ #divMain { width: 100%; height: 100%; display: -ms-flexbox; -ms-flex-align: center; -ms-flex-direction: column; -ms-flex-pack: center; }
Код обоих методов можно найти в упражнении CenteredText к этой лекции. (Упражнение так же используется для демонстрации применения многоточий, в итоге он выглядит не точно так же, как показано выше).
Масштабирование размеров шрифтов
Один из вопросов, обычно вызывающих затруднение при работе с HTML, заключается в принятии решения о том, как масштабировать размер шрифта в адаптивном макете. Я не предлагаю вам делать это с помощью стандартных типографских методов, рекомендованных для дизайна Windows-приложений, как мы увидим ниже в этой лекции. Это больше касается вопроса, когда вам нужно использовать шрифты в каком-то ином аспекте, как, например, в виде больших букв на плитке игры.
При работе с адаптивным макетом, обычно нужно, чтобы размер шрифта был пропорционален размерностям его родительского элемента. (Это не проблема, если родительский элемент имеет фиксированный размер, потому что так вы можете использовать шрифт фиксированного размера). К несчастью, процентные значения, используемые в стиле font-size в CSS, основаны на размере шрифта по умолчанию (1em), а не на размере родительского элемента, как в случае с height и width. Вам, вероятно, понравилось бы использование выражения наподобие font-size: calc(height * .4), но значения других CSS-стилей того же самого элемнта не доступны calc.
Одно исключение из этого правила касается значения vh (которое можно использовать в calc). Если вы знаете, например, что текст, который вы хотите масштабировать, содержится в ячейке сетки, которая всегда занимает 10% от высоты окна вывода, и вы хотели бы, чтобы размер шрифта равнялся половине от этого значения, вы можете воспользоваться выражением font-size: 5vh (5% от высоты окна просмотра).
Другой метод заключается в использовании SVG для вывода текста, где вы можете установить атрибут viewBox и задать font-size относительно этого viewBox. Затем, масштабирование SVG по отношению к ячейке сетки эффективно масштабирует и шрифт:
<svg viewBox="0 0 600 400" preserveAspectRatio="xMaxYMax"> <text x="0" y="150" font-size="200" font-family="Verdana"> Big SVG Text </text> </svg>
Так же вы можете воспользоваться JavaScript для вычисления желаемого размера шрифта, основываясь на свойстве clientHeight родительского элемента. Если данный элемент находится в ячейке сетки, размер шрифта (и высотра строки) могут составить некоторый процент от высоты ячейки, таким образом, позволяя масштабировать шрифт вместе с ячейкой.
Так же вы можете попытаться использовать элемент управления WinJS.UI.ViewBox. Если вам нужно, чтобы текст занял 50% элемента, содержащего его, поместите ViewBox в div, который настроен на размер, равняющийся 50% размера контейнера, и стилизуйте дочерний элемент элемента ViewBox с помощью position: absolute. Попытайтесь, для того, чтобы увидеть это, поместить нижеприведеннй код в default.html нового проекта, созданного на основе шаблона Пустое приложение:
<div style="height:50%;"> <div data-win-control="WinJS.UI.ViewBox"> <p style="position:absolute;">Big text!</p> </div> </div>