Создаем расписание конференции с помощью 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-минутных увеличения */
}

Но размещение элементов в сетке с большим количеством строк очень сложное и запутанное. Здесь на помощь приходят строки сетки с названиями! Вместо того чтобы полагаться на номера строк сетки, можно дать каждой строке название в соответствии со временем суток.

Добавляем макет сетки - 2

Становится гораздо проще размещать сессии, если использовать строки сетки с названиями.

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 все строки получают одинаковую высоту. Эта высота определяется содержанием самой высокой строки в расписании.

Небольшое примечание: использование единиц измерения fr и автоматического значения высоты строк

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

Это создает макет расписания, в котором высота пропорциональна времени. Но это также может сделать макет очень высоким.

Небольшое примечание: использование единиц измерения fr и автоматического значения высоты строк - 2

Использование 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 вписываются идеально.

Дайте знать, что вы думаете по этой теме материала в комментариях. Мы крайне благодарны вам за ваши комментарии, отклики, лайки, подписки, дизлайки!

Пожалуйста, опубликуйте свои отзывы по текущей теме материала. Мы очень благодарим вас за ваши комментарии, лайки, подписки, дизлайки, отклики!

Ангелина Писанюкавтор-переводчик статьи «Building a Conference Schedule with CSS Grid»