[Перевод] Использование CSS-сетки при проектировании пользовательских интерфейсов
CSS-сетка — это отличный инструмент для создания макетов страниц контентно-ориентированных сайтов, включающих в себя большие фрагменты текста и другие материалы. Кроме того, эта технология имеет огромное значение и для великого множества традиционных пользовательских интерфейсов веб-приложений.
В материале, перевод которого мы сегодня публикуем, Джош Мариначчи рассказывает о том, как использовать CSS-сетку для проектирования макетов страниц. Речь пойдёт о страницах, которые способны реагировать на воздействия пользователя и на изменение их содержимого, но при этом всегда ведут себя так, как от них ожидается, в частности — при прокрутке их содержимого.
О технологии CSS Grid Layout
Технология CSS Grid Layout, или просто CSS-сетка, предназначена для построения макетов веб-страниц.
Эта технология позволяет веб-дизайнерам создавать прекрасные динамические макеты, используя совсем немного понятного кода, а не бесконечно экспериментируя со свойством CSS float
, которое мы вынуждены были применять раньше. Мой друг и сослуживец Джен Симмонс говорил о CSS-сетках много лет, неустанно стремясь к тому, чтобы их поддержку реализовали в браузерах, и его усилия увенчались успехом. В конце прошлого кода поддержка технологии CSS Grid Layout появилась в текущих версиях всех основных настольных и мобильных браузеров. Кстати, Джен запустил новый канал на YouTube, Layout Land, который предназначен для всех, кто хочет в совершенстве освоить возможности CSS Grid Layout.
CSS-сетка — по-настоящему мощная технология, с её помощью легко создавать динамические веб-сайты, ориентированные на контент. Однако сетка хорошо подходит не только для того, чтобы размещать на страницах симпатичные блоки с текстами и картинками. Сетка даёт вам полный контроль над двумя измерениями макета страницы. Она, в том числе, не «ломается» при скроллинге страницы. Это означает доступ к возможностям, которые мы воспринимаем как должное в обычных приложениях. Среди них, например, сворачивание боковых панелей и наличие фиксированных панелей инструментов. Всё это теперь, с помощью сетки, очень легко реализовывать и на веб-страницах.
Дизайн без CSS-сетки
Я занимаюсь созданием инструментов для веб-разработки уже многие годы. Вот скриншот редактора, который я создал для разработки моих ретро-игр в стиле RPG. Как только появилась технология Flexbox, я немедленно взял её на вооружение. Я создавал сложные макеты с использованием вложенных горизонтальных и вертикальных блоков, применяя несколько вспомогательных классов для задач вроде скроллинга и изменения размеров элементов.
Инструмент для разработки игр в стиле RPG
Технология Flexbox, без сомнения, позволила мне работать продуктивнее, если сравнивать это с теми временами, когда я пользовался абсолютным позиционированием и боролся с float
. Но и тут не всё было гладко. Взгляните на увеличенный фрагмент предыдущего скриншота, на то место, где панели сходятся. Обратите внимание на проблемы с выравниванием нижних панелей.
Проблемы с выравниванием панелей
Вот ещё один скриншот. Панель инструментов, которая располагается над областью для рисования, по моей задумке, должна всегда присутствовать в верхней части страницы, однако, стоит начать прокрутку этой области, как панель исчезает.
Исчезающая панель инструментов
Каждую из этих проблем можно решить и с помощью свойства float
, углубившись в тонкости позиционирования элементов, но то, что в результате получается, оказывается весьма хрупким. Всякий раз, когда я добавляю новую панель, мне приходится снова и снова перепроверять и дорабатывать весь макет, выискивая, какой конкретно элемент div
отбирает себе слишком много места при изменении размеров элементов. Кроме того, при таком подходе и код разметки выглядит не очень-то приятно. Структуры из вложенных горизонтальных и вертикальных блоков становятся чрезмерно сложными. Например, ниже показан фрагмент кода, в котором имеются всего два уровня вложенности. А ведь два уровня — это далеко не предел. При этом, по мере развития схем взаимодействия со страницей и её функционала, усложняется и процесс работы над ней.
header
button button
spacer label spacer button button
main content
the footer
header
Переход во второе измерение
Фундаментальная проблема модуля Flexbox заключается в том, что применяя его, мы работаем в одном измерении. Это делает Flexbox отличным выбором для одномерных конструкций вроде панелей инструментов или навигационных панелей, но всё уже далеко не так хорошо, если перед дизайнером стоит задача выравнивания содержимого и по горизонтали, и по вертикали. Тут нужны средства для построения двумерных макетов, и именно поэтому нас так интересует технология CSS Grid Layout, которая изначально предназначена для формирования двумерных сеток.
Вот макет, похожий на те, что мы уже рассматривали, но построенный с использованием CSS-сетки.
Макет, построенный с использованием CSS-сетки
Обратите внимание на низ страницы. Все панели идеально выровнены по отношению друг к другу. Кроме того, используя свойство grid-gap для линий, вместо того, чтобы добавлять границы к каждой панели, я могу не беспокоиться о разной ширине линий сетки. Всё, без дополнительных усилий, выглядит так, как должно выглядеть.
Увеличенная часть макета, демонстрирующая идеальное выравнивание панелей
Наиболее значительное преимущество, которое я получаю, используя CSS-сетку, заключается в возможности адаптации макета страницы к изменениям. У моих приложений часто имеются боковые панели. Мне нужно, чтобы всё в макете вело себя так, как ожидается, независимо от того, развёрнута панель или свёрнута, причём, в идеале, требуется, чтобы все эти изменения происходили без необходимости пересчёта параметров макета в JavaScript. Боковые панели состоят из множества компонентов, там имеются шапки и подвалы. Всё это должно быть выровнено, вне зависимости от размеров этих элементов. Используя CSS-сетки, подобного можно добиться, применив замечательную CSS-функцию minmax ().
Если вы уже изучали CSS-сетки, тогда вы знаете, что макеты можно описывать с использованием шаблонов для строк и столбцов сеток. Например, шаблон вроде 200px 1fr 200px
позволит создать боковые панели шириной 200 пикселей с областью для содержимого в середине, занимающую оставшееся пространство. А что произойдёт, если панели должны быть сворачиваемыми? Если не предпринять никаких дополнительных усилий, то столбец, где была панель, так и будет занимать 200 пикселей, даже если его содержимое будет свёрнуто. В подобной ситуации можно использовать функцию minmax()
, при вызове которой, в качестве параметра max
(в нашем случае это второй параметр) используется ключевое слово min-content
.
#grid {
display: grid;
box-sizing: border-box;
width: 100vw;
height: 100vh;
grid-template-columns:
[start] minmax(auto, min-content)
[center]1fr
[end] minmax(auto,min-content);
grid-template-rows:
[header]2em
[content]1fr
[footer]2em;
grid-gap: 1px;
background-color: black;
}
Теперь столбец сетки всегда будет иметь такую ширину, которая достаточна для вывода того, что в него помещено, при этом использоваться будет минимальная необходимая ширина. Таким образом, если одна часть столбца (например, шапка) будет шире, чем другие, ширина столбца увеличится для того, чтобы он мог вместить всё, что нужно.
Если размер элементов становится меньше, или элементы полностью исчезают, тогда и столбец изменится соответствующим образом. В целом, тут мы видим воспроизведение сжатия и растяжения flexbox-блоков, но работает то, что у нас получилось, со всем, что находится в столбце, а не только с одним элементом. Это и есть настоящий двумерный макет.
Вот код оставшейся части демонстрационной страницы, которую мы тут обсуждаем.
.start {
grid-column: start;
}
.center {
grid-column: center;
}
.end {
grid-column: end;
}
header {
grid-row: header;
}
footer {
grid-row: footer;
}
.sidebar {
overflow: auto;
}
Вот ещё один фрагмент кода.
header
...
header
the center content
Для того чтобы кнопки-переключатели воздействовали на боковые панели, я подготовил следующий код. Обратите внимание на то, что используя современное DOM API и стрелочные функции, мы можем, в нескольких строках, воспроизвести то, что раньше делалось средствами JQuery.
const $ = (selector) => document.querySelector(selector)
const $$ = (selector) => document.querySelectorAll(selector)
const on = (elem, type, listener) => elem.addEventListener(type,listener)
on($('#toggle-left'),'click',()=>{
$$(".start").forEach((elem) => elem.classList.toggle('closed'))
})
on($('#toggle-right'),'click',()=>{
$$(".end").forEach((elem) => elem.classList.toggle('closed'))
})
Кроме того, обратите внимание на то, что появление CSS-сетки не означает признания технологии Flexbox устаревшей или отказа от неё. Мы всё ещё пользуемся Flexbox там, где это нужно, в частности — для макетов одномерных конструкций вроде панелей инструментов. Вот стили, которые я использую для панелей инструментов, построенных на основе элементов header
:
filename.txt
header {
background-color: #ccc;
display: flex;
flex-direction: row;
}
.spacer {
flex: 1;
}
Класс spacer
заставляет элементы занимать всё дополнительное пространство. Используя два таких класса между кнопками, я могу сделать так, чтобы панель инструментов меняла при необходимости размер, но делала это так, чтобы имя файла всегда находилось в её центре. Примерно так же ведут себя панели инструментов обычных приложений.
Вы можете поэкспериментировать со всем этим в специально подготовленном проекте на Codepen.
Проект на Codepen
Итоги
CSS-сетка — это потрясающий инструмент для проектирования интерфейсов интерактивных веб-приложений, который позволяет управлять тем, как содержимое страницы располагается по горизонтали и по вертикали. Такие макеты просто и понятно устроены, все элементы в них правильно выровнены, а свойство grid-gap
позволяет автоматически создавать границы между ними. Средства CSS-сетки позволяют модифицировать внешний вид макетов без привлечения JavaScript, они дают полный контроль над размещением содержимого страниц. Тут очень важно отметить, что всё это — стандартные возможности, поддерживаемые браузерами, не требующие применения тяжёлых CSS-фреймворков.
Если вы занимаетесь разработкой веб-приложений или любых интерактивных веб-сайтов, уверен, вам стоит попробовать CSS-сетки.
Уважаемые читатели! Пользуетесь ли вы CSS-сетками при проектировании веб-страниц?