DevGang
Авторизоваться

Использование CSS-подсеток для создания расширенных макетов

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

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

Проблемы с сеткой CSS до появления подсеток

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

Рассмотрим пример макета ниже:

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

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

Чтобы гарантировать правильное выравнивание содержимого вложенных сеток, необходимо, чтобы они использовали общую дорожку сетки. Осознав это ограничение традиционной вложенной сетки, CSS grid Level 2 ввел функцию подсеток для решения этой проблемы.

Использование CSS-подсетки

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

Прежде чем перейти к демонстрации более продвинутой системы верстки, давайте ознакомимся с поддержкой подсеток CSS в браузере, синтаксисом и вариантами использования.

Основной синтаксис и использование

subgrid - это значение, которое мы указываем для grid-template-columns и/или grid-template-rows вместо того, чтобы создавать список путей сетки:

.grid {
  display: grid;
  grid-template-columns: 1fr 1fr 1fr;
  grid-template-rows: 100px 200px;
}

.subgrid {
  display: grid;
  grid-template-columns: subgrid;
  grid-template-rows: subgrid;
}

Когда мы применяем значение subgrid во вложенной сетке, мы, по сути, говорим: "Я хочу быть своей собственной сеткой, но хочу перенять пути сетки из родительской сетки".

Помня об этой идее, давайте рассмотрим простой пример. Рассмотрим следующую структуру HTML:

<div class="grid">
  <div class="item">Item 1</div>
  <div class="item">Item 2</div>
  <div class="item">Item 3</div>
  <div class="item">Item 4</div>
  <div class="subgrid">
    <div class="item">Item 5_1</div>
    <div class="item">Item 5_2</div>
  </div>
</div>

Наша цель - выровнять элементы .subgrid по элементам родительской сетки. Вот что мы ожидаем:

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

.grid {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 1rem;
  padding: 1rem;
  background-color: #aba7a7;
}

.subgrid {
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  grid-column: span 2;
  gap: 1rem;
}

Проверьте это на CodePen!

При использовании функции subgrid мы используем grid-template-columns: subgrid, чтобы указать, что вместо создания нового списка дорожек подсеточка должна использовать дорожки столбцов, определенные в родительской сетке:

.grid {
  /* same as before */
}

.subgrid {
  display: grid;
  grid-template-columns: subgrid;
  grid-column: span 2;
}

Обратите внимание, что мы не указываем размер промежутка (gap). Подсетка автоматически наследует имена промежутков и линий родительской сетки (если они есть). При необходимости мы также можем переопределить их внутри подсеток.

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

Внедрение CSS subgrid в реальные проекты

Теперь, когда мы разобрались с основами CSS subgrid, давайте рассмотрим, как применить ее в реальных проектах. Мы рассмотрим два примера: отзывчивый макет на основе карточек и отзывчивый макет списка постов.

Отзывчивый макет на основе карт

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

<section>
  <div class="card">
    <div class="flex">
      <h2>Find out how much</h2>
      <img />
    </div>
    <div class="content">some text</div>
    <div class="action">try it out</div>
  </div>
  <div class="card"><!-- ... --></div>
  <div class="card"><!-- ... --></div>
  <div class="card"><!-- ... --></div>
</section>

Вот CSS:

section {
  display: grid;
  grid-template-columns: repeat(
    auto-fit,
    minmax(min(350px, 100%), 1fr)
  );
  gap: 1rem;
  /* ... */
}

.card {
  display: grid;
  border: 1px solid #cacaca;
  border-radius: 6px;
  padding: 16px;
}

/* Some other styles */

У нас есть следующий макет:

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

С помощью subgrid мы можем создать чистый и организованный макет. В приведенном ниже коде мы используем grid-template-rows: subgrid; для класса карточки, что означает, что она будет наследовать размеры строк от своей родительской сетки, которой в данном случае является элемент section:

section {
  /* ... */
  grid-template-rows: auto 1fr auto;
}

.card {
  display: grid;
  /* ... */
  grid-template-rows: subgrid;
  grid-row: span 3;
}

Поскольку мы указали для класса карточки grid-row: span 3;, он будет занимать три строки в родительской сетке, обеспечивая правильное выравнивание первого, второго и третьего рядов:

Как уже говорилось, пробелы наследуются в подсеточном пространстве. Обратите внимание на пробел между заголовком и описанием. У нас есть возможность заменить пробел на другой в подсетке:

.card {
  /* ... */
  gap: 5px;
}

Отзывчивый макет для объявлений в блогах

Теперь давайте построим пример макета, о котором говорилось в начале этого урока:

Ниже приведена структура HTML для макета:

<main>
  <article>
    <img
      src="https://images.unsplash.com/photo-1524758631624-e2822e304c36?crop=entropyq=80&w=400"
      alt=""
    />

    <h2 class="p7">Lorem ipsum dolor sit</h2>
    <div class="read__more">Read more</div>
  </article>
  <article><!-- ... --></article>
  <article><!-- ... --></article>
  <article><!-- ... --></article>
  <article><!-- ... --></article>
</main>

Использование обычной вложенной сетки

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

В этом случае мы можем использовать grid-template-rows или grid-auto-rows для вложенной сетки, как показано ниже:

main {
  display: grid;
  grid-template-columns: repeat(
    auto-fit,
    minmax(min(300px, 100%), 1fr)
  );
  gap: 1rem;
  grid-auto-flow: dense;
}

article {
  display: grid;
  grid-auto-rows: 180px 1fr auto;
  /* ... */
}

img {
  /* ... */
  height: 180px;
}
/* other css rules */

В определении строки первая строка имеет фиксированную высоту, равную высоте изображения. Второй ряд, заданный как 1fr, будет занимать свободное пространство и пропорционально увеличиваться. Третий ряд, заданный как auto, будет регулировать свою высоту в зависимости от содержимого.

Посмотрите на результат ниже:

Хотя может показаться, что вложенные элементы выровнены, на самом деле они независимы друг от друга. Выравнивание обусловлено фиксированной высотой первого ряда, а заголовок занимает свободное пространство и пропорционально увеличивается. Если бы, например, текст в третьем ряду занимал несколько рядов, выравнивание было бы искажено:

Использование подсеток

Вместо того чтобы определять дорожки строк в статье, мы можем делегировать это определение ее родительской сетке, которой является main. Это позволит всем элементам статьи перенять размеры дорожек из родительской сетки с помощью grid-template-rows: subgrid;:

main {
  /* ... */
  grid-auto-rows: 180px 1fr auto;
}

article {
  /* ... */
  display: grid;
  grid-row: span 3;
  grid-template-rows: subgrid;
  row-gap: 0px;
}

Использование grid-row: span 3; позволяет статье расширяться по вертикали, вмещая ее содержимое без перекрытия:

Сетка в обоих вариантах

Пока что в нашем проекте только дорожки строк вложенной сетки используют дорожки, определенные для родительской, благодаря grid-template-rows: subgrid. Дорожки столбцов, однако, по-прежнему ведут себя как обычная вложенная сетка.

Пересмотрев итоговый проект, мы заметили, что некоторые карточки охватывают два столбца и могут содержать описание. Чтобы убедиться, что описание также выровнено с дорожкой столбцов родительской сетки, мы используем grid-template-columns: subgrid.

Давайте изменим разметку карточки, чтобы включить необязательный текст описания:

<main>
  <article data-custom="true">
    <img... />
    <h2 class="p7">...</h2>
    <div class="description">
      Lorem ipsum dolor sit amet elit dolor consectetur elit
      dolor amet ande.
    </div>
    <div class="read__more">Read more</div>
  </article>
  ...
  <article><!-- ... --></article>
</main>

Мы также ввели пользовательский атрибут data-* для всех элементов статьи (article), которые мы хотим стилизовать по-другому. Это позволяет нам нацелить их на article[data-custom='true'] и применить стили соответствующим образом. В качестве альтернативы вы можете использовать для этого атрибут class.

По умолчанию мы можем скрыть описание для небольших экранов:

.description {
  display: none; /* Hide description by default */
  font-size: 13px;
  padding: 0 7px 7px;
}

А для отображения на больших экранах мы можем использовать медиазапрос:

article[data-custom='true'] {
  @media (min-width: 996px) {
    .description {
      display: block;
    }
  }
}

Мы использовали вложенность CSS, чтобы вложить @media и селектор.

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

article[data-custom='true'] {
  @media (min-width: 996px) {
    grid-column: span 2;
    grid-template-columns: subgrid;

    .description {
      display: block;
    }
  }
}

Элементы вложенной сетки теперь обращаются к родительской сетке для их размещения:

Теперь давайте позаботимся о том, чтобы изображение и заголовок занимали всю ширину карточки:

article[data-custom='true'] {
  @media (min-width: 996px) {
    grid-column: span 2;
    grid-template-columns: subgrid;

    > img {
      grid-column: 1 / -1;
    }

    > h2 {
      grid-column: 1 / -1;
      font-size: 30px;
    }

    .description {
      display: block;
    }
  }
}

Мы использовали grid-column: 1 / -1;, чтобы расположить изображение и заголовок от первого до последнего столбца сетки:

Заключение

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

Если вам понравилось читать это руководство, поделитесь им в Интернете. А если у вас есть вопросы или рекомендации, поделитесь своими мыслями в разделе комментариев.

Источник:

#CSS #Design
Комментарии
Чтобы оставить комментарий, необходимо авторизоваться

Присоединяйся в тусовку

В этом месте могла бы быть ваша реклама

Разместить рекламу