Создаем расписание конференции с помощью CSS Grid
Я заново оценил возможности CSS Grid, когда создавал адаптивный шаблон для расписания конференции. В результате появилось несколько интересных способов использования CSS Grid. К тому же я разобрался с некоторыми особенностями грида, с которыми сталкиваешься не каждый день.
Определяем требования к макету
Я решил создать этот макет благодаря WordCamp. В рамках проекта проводятся сотни конференций, посвященных WordPress. Конференции бывают разных масштабов и форматов, но все они используют один инструмент для создания расписания.

В результате получился этот макет.
Я знал недостатки существующего макета HTML-таблицы. Чтобы усовершенствовать его, я составил список требований к новому шаблону:
- Дизайн легко настроить с помощью CSS
Сайты WordCamp позволяют задавать стили только с помощью CSS.
- Макет может быть сгенерирован автоматически из контента CMS
Приступаем к работе: надежный HTML
<div> верхнего уровня будет иметь класс .schedule, а также он будет родительским элементом для Grid. У каждого времени начала конференции есть свой заголовок. За ним следует перечисление мероприятий (сессий), которые начинаются в это время.
HTML
<h2>Conference Schedule</h2>
<div class="schedule">
<h3 class="time-slot">8:00am</h3>
<div class="session session-1 track-1">
<h4 class="session-title"><a href="#">Session Title</a></h4>
<span class="session-time">8:00am - 9:00am</span>
<span class="session-track">Track 1</span>
<span class="session-presenter">Presenter Name</span>
</div>
<!-- Cессии 2, 3, 4 -->
<h3 class="time-slot">9:00am</h3>
<div class="session session-5 track-1">
<h4 class="session-title"><a href="#">Session Title</a></h4>
<span class="session-time">9:00am - 10:00am</span>
<span class="session-track">Track 1</span>
<span class="session-presenter">Presenter Name</span>
</div>
<!-- Сессии 6, 7, 8 -->
<!—и так далее... -->
</div> <!-- конец .schedule -->
Макет для мобильных устройств и резервный вариант сетки
Макет для мобильных устройств и резервный вариант для браузеров, которые не поддерживают CSS Grid, готовы.
Вот как выглядит мой макет в цвете:

Добавляем макет сетки
Переходим к практической части реализации CSS Grid. Одна строка grid – это 1% от высоты диаграммы. Поэтому столбец занимает столько же строк, сколько и процент, который он представляет.
CSS
.chart {
display: grid;
grid-template-rows: repeat(100, 1fr); /* 1 строка = 1%! */
}
.fifty-percent-bar {
grid-row: 51 / 101; /* 101 - 51 = 50 => 50% */
}
Благодаря этому я понял, что grid идеально подходит для любого макета, предназначенного для отображения часто изменяющихся величин. Например, времени. В данном случае мы будем использовать приращение в 30 минут. Только избегайте ошибки в Chrome, которая ограничивает макеты сетки 1000 строк.
В первом варианте макета для размещения списка сессий я использовал такой же синтаксис, что и в гистограмме Робина. А также немного простой математики.
Мы используем восемь рядов, потому что есть восемь 30-минутных увеличений периодов между 8:00 и 12:00. Помните, что номера строк неявного грида начинаются с единицы (а не с 0). Поэтому строки нумеруются с 1 по 9.

Элементарная версия расписания с одним столбцом и пронумерованными строками сетки.
CSS
.schedule {
display: grid;
grid-template-rows: repeat(8, 1fr);
}
.session-1 {
grid-row: 1 / 3; /* 8:00 – 9:00, 3 - 1 = 2 30-минутных увеличения */
}
.session-2 {
grid-row: 3 / 6; /* 9:00 - 10:30, 6-3 = 3 30-минутных увеличения */
}
Но размещение элементов в сетке с большим количеством строк очень сложное и запутанное. Здесь на помощь приходят строки сетки с названиями! Вместо того чтобы полагаться на номера строк сетки, можно дать каждой строке название в соответствии со временем суток.

Становится гораздо проще размещать сессии, если использовать строки сетки с названиями.
CSS
.schedule {
display: grid;
grid-template-rows:
[time-0800] 1fr
[time-0830] 1fr
[time-0900] 1fr
[time-0930] 1fr;
/* и так далее...
*/
}
.session-1 {
grid-row: time-0800 / time-0900;
}
.session-2 {
grid-row: time-0900 / time-1030;
}
Также можно генерировать названия строк сетки и стилей макета с помощью информации, которая есть в WordPress. Установите в сетке время начала и окончания, и готово!
Поскольку в расписании указывается несколько тематик, то нужен столбец для каждого из них. Можно использовать номера тем в каждой строке столбца сетки. Также есть дополнительный первый столбец для заголовков с указанием времени начала сессий конференции.
CSS
.schedule { /* продолжается */
grid-template-columns:
[times] 4em
[track-1-start] 1fr
[track-1-end track-2-start] 1fr
[track-2-end track-3-start] 1fr
[track-3-end track-4-start] 1fr
[track-4-end];
}
Определив строки сетки, основанные на времени и темах, можно размещать любую нужную сессию, просто зная время и место!
CSS
.session-8 {
grid-row: time-1030 / time-1100;
grid-column: track-2-start / track-3-end;
Собрав все это вместе, мы получаем длинный, но вполне читабельный код:
CSS
@media screen and (min-width: 700px) {
.schedule {
display: grid;
grid-gap: 1em;
grid-template-rows:
[tracks] auto /* Предвосхищаем! */
[time-0800] 1fr
[time-0830] 1fr
[time-0900] 1fr
[time-0930] 1fr
[time-1000] 1fr
[time-1030] 1fr
[time-1100] 1fr
[time-1130] 1fr
[time-1200] 1fr;
grid-template-columns:
[times] 4em
[track-1-start] 1fr
[track-1-end track-2-start] 1fr
[track-2-end track-3-start] 1fr
[track-3-end track-4-start] 1fr
[track-4-end];
}
.time-slot {
grid-column: times;
}
}
HTML
<div class="session session-1 track-1" style="grid-column: track-1; grid-row: time-0800 / time-0900;">
<!-- детали -->
</div>
<div class="session session-2 track-2" style="grid-column: track-2; grid-row: time-0800 / time-0900">
<!-- детали -->
</div>
<!—и так далее... -->
Небольшое примечание: использование единиц измерения fr и автоматического значения высоты строк
Стоит отметить одну деталь – применение единиц измерения fr для определения высоты строк. При использовании значения 1fr все строки получают одинаковую высоту. Эта высота определяется содержанием самой высокой строки в расписании.

Чтобы понять это, я был вынужден прочитать спецификацию W3C для fr.
Это создает макет расписания, в котором высота пропорциональна времени. Но это также может сделать макет очень высоким.

Использование 1fr создает строки одинаковой высоты, определяемой самой высокой строкой в сетке.
Например, если в сетке расписания есть 15-минутные увеличения периодов времени с 7:00 до 18:00, это в общей сложности 48 строк сетки. В этом случае вы захотите использовать для высоты строки значение auto. Потому что расписание будет намного компактнее с высотой каждой строки сетки, определяемой ее содержимым.

Использование значения auto приводит к тому, что высота каждой строки равна высоте ее содержимого.
Добавляем удобные названия тем
Пришло время добавить названия тем, которые выглядят как заголовки в верхней части каждого столбца. Я решил скрыть «заголовки» от вспомогательных технологий с помощью aria-hidden = «true».
Названия тем будут располагаться в первой строке сетки с удобным названием «tracks».
HTML
<span class="track-slot" aria-hidden="true" style="grid-column: track-1;">Track 1</span>
<span class="track-slot" aria-hidden="true" style="grid-column: track-2;">Track 2</span>
<span class="track-slot" aria-hidden="true" style="grid-column: track-3;">Track 3</span>
<span class="track-slot" aria-hidden="true" style="grid-column: track-4;">Track 4</span>
CSS
.track-slot {
display: none; /* виден только в Grid layout */
}
@supports( display:grid ) {
@media screen and (min-width:700px) {
.track-slot {
grid-row: tracks;
display: block;
position: sticky;
top: 0;
z-index: 1000;
background-color: rgba(255,255,255,.9);
}
}
}
Результат
Так выглядит проделанная работа
Это только начало
Это расписание, безусловно, самое эффективное использование CSS Grid в моей практике. Мне нравится, что названия строк основаны на фактических данных, а требования к доступности и CMS вписываются идеально.