Зарегистрируйтесь, чтобы продолжить обучение

Расположение элементов в сетке CSS: Вёрстка на Grid

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

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

Нумерация Grid-линий

По вертикали в данной сетке 5 Grid-линий. Самая первая имеет 2 порядковых номера: 1 и -5. По горизонтали 4 Grid-линий. Самая нижняя из них имеет порядковые номера 4 и -1.

Данные номера можно использовать для привязки элементов к конкретным Grid-линиям. Обратите внимание, что при использовании Grid мы уже меньше оперируем такими понятиями, как ширина и высота элемента. Теперь эти две характеристики отданы на откуп колонкам и рядам. Именно от них зависит, какого размера будет элемент внутри сетки.

Вернёмся к примеру из прошлого урока. В нём мы реализовали 12-колоночную сетку, внутри которой расположены три элемента.

Теперь, зная порядковые номера всех Grid-линий расположим наши элементы в следующем порядке:

  • Первый элемент будет занимать 12 колонок, начиная с Grid-линии номер 1. По вертикали он займёт 2 ряда.
  • Второй элемент должен быть расположен ниже первого элемента и займёт 4 колонки, начиная с первой.
  • Третий элемент займёт оставшиеся 8 колонок рядом со вторым элементом.

В конечном итоге получится типичная структура 2-колоночного макета. Для расположения элементов по Grid-линиям в CSS Grid Layout существует 4 свойства:

  • grid-column-start — указывает на начальную вертикальную Grid-линию расположения элемента.
  • grid-column-end — указывает на конечную вертикальную Grid-линию расположения элемента. Обратите внимание, что значение указывает до какой колонки располагать элемент. Сама колонка, указанная в этом свойстве не включается. Если вы хотите включить и указанную колонку, то необходимо прибавить единицу. Например для 12-колоночного макета указывается значение 13, если вы хотите включить последнюю колонку.
  • grid-row-start — указывает на начальную горизонтальную Grid-линию расположения элемента.
  • grid-row-end — указывает на конечную горизонтальную Grid-линию расположения элемента. Как и в случае с вертикальной Grid-линией свойство указывает до какого ряда располагать элемент.

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

Обратите внимание, что для шапки указано значение grid-column-start. Это может показаться излишним, ведь блок и так стартует самым первым от первой колонки. Это справедливо для тех случаев, если не указана конечная Grid-линия. Если убрать свойство grid-column-start, то элемент как бы начнёт расширяться не слева направо, а справа налево.

Для удобного использования этих свойств существуют сокращённые версии записи. Они позволяют записать начальные и конечные значения используя всего одно свойство. Для указания начальной и конечной полосы по горизонтали используется свойство grid-column. Для такой же записи, но по вертикали используется свойство grid-row. В качестве значения указывают начальную и конечную полосу, разделённые слэшем /.

Используя сокращённые версии записи пример выше можно записать следующим образом:

.grid-header {
  grid-column: 1 / 13;
  grid-row: 1 / 3;
}

.grid-aside {
  grid-column: 1 / 5;
  grid-row: 3 / 13;
}

.grid-main {
  grid-column: 5 / 13;
  grid-row: 3 / 13
}

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

В качестве примера растянем шапку макета используя отрицательное конечное значение.

Ключевое слово span

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

Для решения этой задачи разработчики стандарта внесли ключевое слово span, указывающее количество ячеек, которые необходимо охватить элементу при расположении внутри сетки. Теперь вместо указания конечного индекса полосы, можно использовать синтаксис: span <количество ячеек>.

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

.grid-header {
  grid-column: 1 / -1;
  grid-row: 1 / span 2; /* Указываем, что элемент занимает 2 строки по вертикали */
}

.grid-aside {
  grid-column: 1 / span 4; /* Указываем, что элемент занимает 4 колонки по горизонтали */
  grid-row: 3 / -1;
}

.grid-main {
  grid-column: 5 / -1;
  grid-row: 3 / -1
}

Интересной особенностью является использование в качестве значения только ключевого слова span. В этом случае браузер разместит элемент с тем количеством строк/колонок, которое вы указали. Например, следующая запись создаст элемент шириной в 2 колонки:

.col-2 {
  grid-column: span 2;
}

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

Именование линий

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

Для создания именованных Grid-линий используется следующий синтаксис свойств grid-template-columns и grid-template-rows: [Название линии] ширина полосы после линии. Вы можете подставлять любое количество различных имён, причём непосредственно в уже свёрстанном макете. Такая запись не повредит текущему шаблону.

Добавим в наш двухколоночный макет именованные линии для обозначения начала каждой из областей. Используем их для обозначения стартовых рядов и колонок. Таких именованных линий будет 4:

  1. header-top — Самая верхняя линия, от которой отрисовывается шапка сайта.
  2. content-begin — Линия, откуда начинается основной контент сайта. В данном случае aside и main. Используем её как ограничитель высоты шапки.
  3. sidebar-begin — Левая линия, от которой начинается отрисовываться aside.
  4. main-begin — Линия, от которой начинается main. Воспользуемся ею для ограничения ширины aside.

Подставим имена в уже существующий CSS и посмотрим, как они записываются:

.grid-12 {
  display: grid;
  grid-template-columns: [sidebar-begin] 1fr repeat(3, 1fr) [main-begin] 1fr repeat(7, 1fr);
  grid-template-rows: [header-top] 1fr 1fr [content-begin] 1fr repeat(9, 1fr);

  height: 100vh;
}

Разберём следующую строку: grid-template-columns: [sidebar-begin] 1fr repeat(3, 1fr) [main-begin] 1fr repeat(7, 1fr);. Её можно разделить на 4 части:

  • [sidebar-begin] 1fr. Как и было описано, создаём именованную линию с именем sidebar-begin и полосу шириной в 1 фракцию.
  • repeat(3, 1fr). Уже изученная вами запись, которая создаст 3 полосы с шириной 1 фракция каждая.
  • [main-begin] 1fr. Создаётся именованная линия main-begin. Ширина полосы после линии составит 1 фракцию.
  • repeat(7, 1fr). Создаётся 7 полос с шириной 1 фракция каждая.

Теперь данные имена можно использовать в изученных свойствах grid-column-start, grid-column-end, grid-row-start и grid-row-end.

Важно: создание именованных линий не «отнимает» у них индексы. Вы всё ещё можете обращаться к этим линиям как по индексу (положительному или отрицательному), так и по их именам.

Создание именованных Grid-областей

Помимо именования Grid-линий разработчики дали возможность именовать целые области. Как вы помните, область — это несколько полос, которые объединены едиными Grid-линиями. Как же именование областей может помочь при создании макета? На самом деле этот инструмент является одним из прорывных в создании дизайна в CSS. Это свойство позволяет не просто задать имена каким-то абстрактным областям, но и визуализировать сетку с помощью этих имён. Одним из недостатков такого способа является его громоздкость. Давайте разберёмся с этим на практике.

Для создания именованных областей используется свойство grid-template-areas. В качестве значения оно принимает данные, которые заключаются в двойные кавычки. Внутри этих кавычек описываются области, которые расположатся на сетке. Сколько колонок они занимают, столько раз их и надо повторить внутри значения. Сами по себе значения отделяются пробелом. Создадим сетку из 6 колонок. В ней, как и в прошлых примерах, расположим 2-колоночный макет. Вначале опишем шапку. Она занимает всю ширину экрана, значит ей нужно выделить 6 колонок. Назовём эту область header. Имя области вы можете выбирать произвольное. Так же необходимо указать блок, который будет являться областью header. Для этого используется свойство grid-area, значением которого является имя области. В данном случае header.

.grid-6 {
  display: grid;
  grid-template-areas: "header header header header header header";
}

.grid-header {
  grid-area: header;
}

Обратите внимание, что в контейнере .grid-6 отсутствуют свойства grid-template-columns и grid-template-rows. Сейчас их роль на себя взяло свойство grid-template-areas. Указав в ней определённое количество областей, автоматически создаются колонки с шириной в 1 фракцию. Если вам нужны другие значения, то всегда можно воспользоваться свойствами grid-template-columns и grid-template-rows, установив необходимую ширину полос.

Описав верхний ряд, настало время описать следующий, в котором расположим aside и main. Для этого продолжим в свойстве grid-template-areas указывать значения. Так как нам нужен новый ряд, то писать внутри значения с header не имеет смысла. Добавим пробел, и в новых двойных кавычках укажем расположения элементов в следующем ряду.

.grid-6 {
  display: grid;
  grid-template-areas: "header header header header header header" "aside aside main main main main";
}

.grid-header {
  grid-area: header;
}

.grid-aside {
  grid-area: aside;
}

.grid-main {
  grid-area: main;
}

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

Если нужно больше рядов, то их можно продолжить добавлять. Это важно, если у вас нестандартные размеры ячеек. В других случаях высота блоков будет определяться контентом внутри них. Это стандартное поведение, знакомое вам по вёрстке макетов. В данном случае создалась сетка из 6 колонок и двух строк.

Для более удобного чтения CSS позволяет переносить строки внутри свойства. Таким образом свойство grid-template-areas становится более наглядным. Также внутри самих значений можно проставлять любое количество пробелов. Колонки в каждой строке можно выставить друг под другом:

.grid-6 {
  display: grid;
  grid-template-areas: "header header header header header header"
                       "aside  aside  main   main   main   main";
}

Бывают ситуации, когда вместо одной из колонок нужна не какая-то существующая область, а пустая ячейка. Так как количество колонок в каждой строке должно быть одинаковым, то просто удалить одну из областей нет возможности. Вместо этого grid-template-areas может принимать специальное значение, которое обозначает пустую область. Этим значением является точка .. В текущей сетке сделаем шапку на одну колонку меньше. Шапка должна занимать 5 колонок вместо 6. В таком случае значение свойства будет выглядеть следующим образом:

.grid-6 {
  display: grid;
  grid-template-areas: "header header header header header ."
                       "aside  aside  main   main   main   main";
}

Самостоятельное задание

Создайте трехколоночный макет, состоящий из:

  • Шапка.
  • Левый сайдбар.
  • Основной контент.
  • Правый сайдбар.
  • Футер.

При создании используйте оба способа. Вначале используйте Grid-линии, потом Grid-области. Количество колонок в сетке выбирайте самостоятельно. В данном случае их не может быть меньше трёх.


Аватары экспертов Хекслета

Остались вопросы? Задайте их в разделе «Обсуждение»

Вам ответят команда поддержки Хекслета или другие студенты

Для полного доступа к курсу нужен базовый план

Базовый план откроет полный доступ ко всем курсам, упражнениям и урокам Хекслета, проектам и пожизненный доступ к теории пройденных уроков. Подписку можно отменить в любой момент.

Получить доступ
1000
упражнений
2000+
часов теории
3200
тестов

Открыть доступ

Курсы программирования для новичков и опытных разработчиков. Начните обучение бесплатно

  • 130 курсов, 2000+ часов теории
  • 1000 практических заданий в браузере
  • 360 000 студентов
Отправляя форму, вы принимаете «Соглашение об обработке персональных данных» и условия «Оферты», а также соглашаетесь с «Условиями использования»

Наши выпускники работают в компаниях:

Логотип компании Альфа Банк
Логотип компании Aviasales
Логотип компании Yandex
Логотип компании Tinkoff
Рекомендуемые программы
профессия
Верстка на HTML5 и CSS3, Программирование на JavaScript в браузере, разработка клиентских приложений используя React
10 месяцев
с нуля
Старт 26 декабря
профессия
Программирование на JavaScript в браузере и на сервере (Node.js), разработка бекендов на Fastify и фронтенда на React
16 месяцев
с нуля
Старт 26 декабря

Используйте Хекслет по-максимуму!

  • Задавайте вопросы по уроку
  • Проверяйте знания в квизах
  • Проходите практику прямо в браузере
  • Отслеживайте свой прогресс

Зарегистрируйтесь или войдите в свой аккаунт

Отправляя форму, вы принимаете «Соглашение об обработке персональных данных» и условия «Оферты», а также соглашаетесь с «Условиями использования»