Spec-Zone.ru › CSS

Реализация распространённых макетов с помощью сетки

Чтобы завершить этот набор руководств по CSS-сетке, мы рассмотрим несколько различных макетов, которые продемонстрируют некоторые из различных техник, которые вы можете использовать при проектировании с помощью сетки. Мы рассмотрим пример, использующий grid-template-areas, типичную гибкую систему из 12 столбцов, а также список продуктов с автоматическим размещением. Как вы можете видеть из этого набора примеров, часто существует более одного способа достижения желаемого результата с помощью сетки. Выберите метод, который вы считаете наиболее полезным для решения проблем и реализации необходимых дизайнов.

Реагирующий макет с 1 до 3 гибких столбцов, использующий grid-template-areas

Многие веб-сайты являются вариантом этого типа макета, с контентом, сайдбарами, заголовком и футером. При адаптивном дизайне вы можете отобразить макет как одностолбцовый, добавив сайдбар на определённой точке перехода и затем использовать трёхстолбцовый макет для более широких экранов.

Image of the three different layouts created by redefining our grid at two breakpoints.

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

Разметка представляет собой контейнер с элементами для заголовка, футера, основного контента, навигации, сайдбара и блока для размещения рекламы.

<div class="wrapper">
  <header class="main-head">The header</header>
  <nav class="main-nav">
    <ul>
      <li><a href="">Nav 1</a></li>
      <li><a href="">Nav 2</a></li>
      <li><a href="">Nav 3</a></li>
    </ul>
  </nav>
  <article class="content">
    <h1>Main article area</h1>
    <p>
      In this layout, we display the areas in source order for any screen less
      that 500 pixels wide. We go to a two column layout, and then to a three
      column layout by redefining the grid, and the placement of items on the
      grid.
    </p>
  </article>
  <aside class="side">Sidebar</aside>
  <div class="ad">Advertising</div>
  <footer class="main-footer">The footer</footer>
</div>

Поскольку мы используем grid-template-areas для создания макета. Вне каких-либо медиа-запросов нам нужно назвать области. Мы называем области, используя свойство grid-area.

.main-head {
  grid-area: header;
}
.content {
  grid-area: content;
}
.main-nav {
  grid-area: nav;
}
.side {
  grid-area: sidebar;
}
.ad {
  grid-area: ad;
}
.main-footer {
  grid-area: footer;
}

Это не создаст макет, однако элементы теперь имеют имена, которые мы можем использовать для этого. Оставаясь вне медиа-запросов, мы теперь настроим макет для мобильной ширины. Здесь мы сохраняем всё в исходном порядке, пытаясь избежать разрыва между исходным кодом и отображением, как описано в руководстве Макет сетки и доступность. Мы не определили какие-либо дорожки столбцов или строк, но этот макет определяет один столбец, и строки будут создаваться по мере необходимости для каждого из элементов в неявной сетке.

.wrapper {
  display: grid;
  gap: 20px;
  grid-template-areas:
    "header"
    "nav"
    "content"
    "sidebar"
    "ad"
    "footer";
}

После того, как наш мобильный макет готов, мы можем приступить к добавлению медиа-запроса, чтобы адаптировать этот макет для больших экранов с достаточным пространством для отображения двух столбцов.

@media (min-width: 500px) {
  .wrapper {
    grid-template-columns: 1fr 3fr;
    grid-template-areas:
      "header  header"
      "nav     nav"
      "sidebar content"
      "ad      footer";
  }
  nav ul {
    display: flex;
    justify-content: space-between;
  }
}

Вы можете увидеть, как макет формируется в значении grid-template-areas. header занимает два столбца, как и nav. В третьей строке дорожки у нас есть sidebar рядом с content. В четвёртой строке дорожки я выбрал размещение моего ad контента — так что он появляется под сайдбаром, затем footer рядом с ним под контентом. Мы используем flexbox для навигации, чтобы отобразить её в строке со сдвигом.

Теперь мы можем добавить последнюю точку перехода, чтобы перейти к трёхстолбцовому макету.

@media (min-width: 700px) {
  .wrapper {
    grid-template-columns: 1fr 4fr 1fr;
    grid-template-areas:
      "header header  header"
      "nav    content sidebar"
      "nav    content ad"
      "footer footer  footer";
  }
  nav ul {
    flex-direction: column;
  }
}

Трёхстолбцовый макет имеет два 1fr сайдбара и средний столбец, размер дорожки которого составляет 4fr. Это означает, что доступное пространство в контейнере разделено на 6 частей и распределено пропорционально нашим трём дорожкам — по одной части каждому сайдбару и 4 части центральному столбцу.

В этом макете мы отображаем nav в левом столбце рядом с content. В правом столбце у нас есть sidebar и под ним реклама (ad). footer теперь занимает всю нижнюю часть макета. Затем я использую flexbox для отображения навигации в виде столбца.

Это простой пример, но он демонстрирует, как мы можем использовать макет сетки для перестановки нашего макета для разных точек перехода. В частности, мы изменяем расположение блока ad, как это необходимо в моих разных столбцовых раскладках. Я считаю, что этот метод именованных областей очень полезен на этапе прототипирования, так как легко играть с расположением элементов. Вы всегда можете начать использовать сетку таким образом для прототипирования, даже если вы не можете полностью полагаться на неё в производстве из-за браузеров, которые посещают ваш сайт.

Гибкий макет из 12 столбцов

Если вы работали с одним из многочисленных фреймворков или систем сеток, вы, возможно, привыкли выстраивать свой сайт на гибкой сетке из 12 или 16 столбцов. Мы можем создать такую систему, используя CSS-сетку. В качестве простого примера давайте создадим гибкую сетку из 12 столбцов, которая имеет 12 дорожек столбцов с размером 1fr, все они имеют имя начальной линии col-start. Это означает, что у нас будет двенадцать линий сетки с именем col-start.

.wrapper {
  display: grid;
  grid-template-columns: repeat(12, [col-start] 1fr);
  gap: 20px;
}

Чтобы продемонстрировать, как работает эта система сеток, я поместил четыре дочерних элемента внутри моего обертки.

<div class="wrapper">
  <div class="item1">Start column line 1, span 3 column tracks.</div>
  <div class="item2">
    Start column line 6, span 4 column tracks. 2 row tracks.
  </div>
  <div class="item3">Start row 2 column line 2, span 2 column tracks.</div>
  <div class="item4">
    Start at column line 3, span to the end of the grid (-1).
  </div>
</div>

Затем мы можем разместить их в сетке, используя именованные линии и ключевое слово span.

.item1 {
  grid-column: col-start / span 3;
}
.item2 {
  grid-column: col-start 6 / span 4;
  grid-row: 1 / 3;
}
.item3 {
  grid-column: col-start 2 / span 2;
  grid-row: 2;
}
.item4 {
  grid-column: col-start 3 / -1;
  grid-row: 3;
}

Как описано в руководстве по именованным линиям, мы используем именованную линию для размещения нашего элемента. Поскольку у нас есть 12 линий, все с одинаковым именем, мы используем имя и затем индекс линии. Вы также можете использовать сам индекс линии, если хотите, и вообще избегать использования именованных линий.

Вместо задания конечного номера линии я выбрал указание количества дорожек, которое должен занимать этот элемент, используя ключевое слово span. Я предпочитаю этот подход, так как при работе с многостолбцовым макетом мы обычно представляем блоки с точки зрения количества дорожек сетки, которые они занимают, и корректируем это для разных точек перехода. Чтобы увидеть, как блоки выравниваются по дорожкам, используйте инспектор сетки Firefox. Он наглядно демонстрирует, как размещаются наши элементы.

Showing the items placed on the grid with grid tracks highlighted.

Существуют некоторые ключевые различия в том, как работает макет сетки по сравнению с системами сеток, которые вы могли использовать ранее. Как вы можете видеть, нам не нужно добавлять никакой разметки для создания строки; системам сеток нужно это сделать, чтобы предотвратить появление элементов в строке выше. С помощью CSS-сетки мы можем помещать элементы в строки без риска их подъёма в строку выше, если она остаётся пустой. Благодаря этому жесткому размещению столбцов и строк мы также можем легко оставить пробелы в нашем макете. Нам также не нужны специальные классы для перемещения или сдвига элементов, для их вдавливания в сетку. Всё, что нам нужно сделать, это указать начальную и конечную линии для элемента.

Создание макета с использованием системы из 12 столбцов

Чтобы увидеть, как работает этот метод макета на практике, мы можем создать тот же макет, что и с grid-template-areas, но на этот раз с использованием 12-столбцовой системы сеток. Начнём с той же разметки, что и в примере с шаблоном областей сетки.

<div class="wrapper">
  <header class="main-head">The header</header>
  <nav class="main-nav">
    <ul>
      <li><a href="">Nav 1</a></li>
      <li><a href="">Nav 2</a></li>
      <li><a href="">Nav 3</a></li>
    </ul>
  </nav>
  <article class="content">
    <h1>Main article area</h1>
    <p>
      In this layout, we display the areas in source order for any screen less
      that 500 pixels wide. We go to a two column layout, and then to a three
      column layout by redefining the grid, and the placement of items on the
      grid.
    </p>
  </article>
  <aside class="side">Sidebar</aside>
  <div class="ad">Advertising</div>
  <footer class="main-footer">The footer</footer>
</div>

Затем мы можем настроить нашу сетку, как в примере макета с 12 столбцами выше.

.wrapper {
  display: grid;
  grid-template-columns: repeat(12, [col-start] 1fr);
  gap: 20px;
}

Мы снова сделаем это адаптивным макетом, но на этот раз с использованием именованных линий. В каждой точке перехода будет использоваться 12-столбцовая сетка, но количество дорожек, которые будут занимать элементы, меняется в зависимости от размера экрана.

Мы начинаем с мобильной версии, и всё, что мы хотим для самых узких экранов, — это сохранить элементы в исходном порядке и занять всю сетку.

.wrapper > * {
  grid-column: col-start / span 12;
}

В следующей точке перехода мы хотим перейти к двухстолбцовому макету. Наш заголовок и навигация по-прежнему занимают всю сетку, поэтому нам не нужно указывать никакого позиционирования для них. Сайдбар начинается с первой столбцовой линии с именем col-start и занимает 3 линии. Он идёт после строчной линии 3, так как заголовок и навигация находятся в первых двух строчных дорожках.

Блок с рекламой расположен под сайдбаром, поэтому начинается со строчной линии сетки 4. Затем у нас есть контент и футер, начинающийся со столбцовой линии col-start 4 и занимающий 9 дорожек, доходя до конца сетки.

@media (min-width: 500px) {
  .side {
    grid-column: col-start / span 3;
    grid-row: 3;
  }
  .ad {
    grid-column: col-start / span 3;
    grid-row: 4;
  }
  .content,
  .main-footer {
    grid-column: col-start 4 / span 9;
  }
  nav ul {
    display: flex;
    justify-content: space-between;
  }
}

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

@media (min-width: 700px) {
  .main-nav {
    grid-column: col-start / span 2;
    grid-row: 2 / 4;
  }
  .content {
    grid-column: col-start 3 / span 8;
    grid-row: 2 / 4;
  }
  .side {
    grid-column: col-start 11 / span 2;
    grid-row: 2;
  }
  .ad {
    grid-column: col-start 11 / span 2;
    grid-row: 3;
  }
  .main-footer {
    grid-column: col-start / span 12;
  }
  nav ul {
    flex-direction: column;
  }
}

Ещё раз, инспектор сетки полезен, чтобы увидеть, как сформировался наш макет.

Showing the layout with grid tracks highlighted by the grid inspector.

Следует отметить, что при создании этого макета нам не нужно было явно позиционировать каждый элемент в сетке в каждой точке перехода. Мы смогли унаследовать расположение, заданное для предыдущих точек перехода — преимущество работы «сначала с мобильной версией». Мы также можем использовать автоматическое размещение сетки. Соблюдая логический порядок элементов, автоматическое размещение выполняет большую часть работы по размещению элементов в сетке. В заключительном примере этого руководства мы создадим макет, который полностью полагается на автоматическое размещение.

END_OF_DOCUMENT_MARKER

Списки товаров с автоматическим размещением

Многие макеты представляют собой наборы «карт» — списки товаров, галереи изображений и так далее. Сетка может значительно упростить создание таких списков, которые будут адаптивными без необходимости добавлять справочные таблицы стилей для разных устройств. В этом примере я сочетаю макеты CSS сетки и гибкой компоновки, чтобы создать простой макет списка товаров.

Разметка моего списка — это неупорядоченный список элементов. Каждый элемент содержит заголовок, текст различной высоты и ссылку на призыв к действию.

<ul class="listing">
  <li>
    <h2>Item One</h2>
    <div class="body">
      <p>The content of this listing item goes here.</p>
    </div>
    <div class="cta">
      <a href="">Call to action!</a>
    </div>
  </li>
  <li>
    <h2>Item Two</h2>
    <div class="body">
      <p>The content of this listing item goes here.</p>
    </div>
    <div class="cta">
      <a href="">Call to action!</a>
    </div>
  </li>
  <li class="wide">
    <h2>Item Three</h2>
    <div class="body">
      <p>The content of this listing item goes here.</p>
      <p>This one has more text than the other items.</p>
      <p>Quite a lot more</p>
      <p>Perhaps we could do something different with it?</p>
    </div>
    <div class="cta">
      <a href="">Call to action!</a>
    </div>
  </li>
  <li>
    <h2>Item Four</h2>
    <div class="body">
      <p>The content of this listing item goes here.</p>
    </div>
    <div class="cta">
      <a href="">Call to action!</a>
    </div>
  </li>
  <li>
    <h2>Item Five</h2>
    <div class="body">
      <p>The content of this listing item goes here.</p>
    </div>
    <div class="cta">
      <a href="">Call to action!</a>
    </div>
  </li>
</ul>

Мы создадим сетку с гибким количеством гибких столбцов. Я хочу, чтобы они никогда не становились меньше 200 пикселей, а затем делили оставшееся пространство поровну — так мы всегда получаем столбцы одинаковой ширины. Это достигается функцией minmax() в нашей записи для определения размера дорожек.

.listing {
  list-style: none;
  margin: 2em;
  display: grid;
  gap: 20px;
  grid-template-columns: repeat(auto-fill, minmax(200px, 1fr));
}

Как только мы добавим этот CSS, элементы начнут выстраиваться в сетку. Если мы уменьшим или увеличим окно, количество дорожек столбцов изменится — без необходимости добавлять точки останова с помощью справочных таблиц стилей и переопределять сетку.

Затем мы можем привести внутренние элементы в порядок, используя немного гибкой компоновки. Я установил элемент списка в display: flex и flex-direction в column. Затем мы можем использовать автоматический отступ в .cta для перемещения этой полосы вниз к нижней части блока.

.listing li {
  border: 1px solid #ffe066;
  border-radius: 5px;
  display: flex;
  flex-direction: column;
}
.listing .cta {
  margin-top: auto;
  border-top: 1px solid #ffe066;
  padding: 10px;
  text-align: center;
}
.listing .body {
  padding: 10px;
}

Это одна из основных причин, по которой кто-то может использовать гибкую компоновку вместо сетки, если нужно только выровнять или распределить что-то в одном измерении, это случай использования гибкой компоновки.

Предотвращение пробелов с помощью ключевого слова dense

Всё это выглядит довольно завершенным, однако иногда у нас есть карточки, содержащие гораздо больше контента, чем другие. Возможно, хотелось бы, чтобы они занимали две дорожки, и тогда они не будут такими высокими. У меня есть класс wide для более крупных элементов, и мы добавляем правило grid-column-end со значением span 2. Теперь, когда сетка встречает этот элемент, она назначит ему две дорожки. В некоторых точках останова это означает, что в сетке образуется пробел — там нет места для размещения элемента, занимающего две дорожки.

The layout has gaps as there is not space to lay out a two track item.

Мы можем заполнить эти пробелы, установив grid-auto-flow: dense для контейнера сетки. Однако будьте осторожны, так как это может изменить логический порядок элементов. Вы должны делать это только в том случае, если у ваших элементов нет определенного порядка — и будьте в курсе проблем с порядком табуляции, который следует исходному коду, а не вашему переупорядоченному отображению.

.listing {
  list-style: none;
  margin: 2em;
  display: grid;
  gap: 20px;
  grid-auto-flow: dense;
  grid-template-columns: repeat(auto-fill, minmax(200px, 1fr));
}
.listing .wide {
  grid-column-end: span 2;
}

Этот метод использования автоматического размещения с применением правил к определенным элементам очень полезен и может помочь вам работать с контентом, который, например, выводится CMS, где у вас есть повторяющиеся элементы, и вы можете добавить класс к определенным элементам при их отображении в HTML.

Дополнительные возможности изучения

Лучший способ научиться использовать сетку — продолжать создавать примеры, как мы это делали здесь. Выберите что-то, что вы обычно создаёте с помощью своего фреймворка или с помощью плавающих элементов, и посмотрите, сможете ли вы создать это с помощью сетки. Не забудьте найти примеры, которые невозможно создать существующими методами. Это может означать вдохновение журналами или другими источниками, не связанными с веб-сайтами. Сетка открывает возможности, которых у нас раньше не было; нам не нужно придерживаться одних и тех же старых макетов, чтобы её использовать.

  • CSS сетка
  • CSS Макеты: Сетки
  • Полное руководство по CSS сетке на CSS-Tricks (2023)
  • Примеры использования сеток
  • Примеры макетов веб-сайтов с CSS сеткой на quackit.com

© 2005–2024 MDN contributors.
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.
https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_grid_layout/Realizing_common_layouts_using_grids

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API