При всём ажиотаже вокруг технологий CSS Grid и Flexbox, часто упускается из виду другой метод разметки. В этой статья я хочу рассмотреть многоколоночный макет — часто называемый просто «Multicol» или «CSS Columns». Вы узнаете, для каких задач он подходит и какие нюансы следует учитывать при его использовании.
Что такое мультиколонки?
Основная идея мультиколонок заключается в том, что вы можете взять фрагмент содержимого и поместить его в несколько колонок, как в газете. Вы делаете это с помощью одного или двух свойств. Свойство column-count
задаёт количество колонок, на которое вам бы хотелось разбить содержимое. Свойство column-width
задаёт идеальную ширину, давая возможность браузеру самому определить, сколько колонок при этом поместится.
Неважно, какие элементы находятся внутри блока, который вы превращаете в многоколоночный контейнер, все элементы остаются в обычном потоке, но разбиваются на колонки. Это делает CSS Columns непохожим на другие методы вёрстки, которые у нас есть в браузерах сегодня. Flexbox и Grid, например, берут дочерние элементы контейнера, а затем эти элементы участвуют в flex или grid макете. В случае с CSS Columns, у вас всё ещё имеется обычный поток, только не внутри самой колонки.
В примере ниже я использую column-width
, чтобы сделать колонки шириной как минимум 14em. CSS Columns определяет, сколько колонок шириной 14em поместятся в контейнере, а затем распределяет между ними оставшееся пространство. Колонки будут иметь ширину не меньше 14em, кроме ситуации, когда помещается только одна колонка, в этом случае она может становиться уже. CSS Columns стал первым случаем, в котором мы столкнулись с подобным поведением в CSS, создавая колонки, которые по умолчанию были отзывчивыми. Нет необходимости добавлять медиа-выражения и изменять количество колонок на разных контрольных точках, вместо этого мы указываем оптимальную ширину и браузер будет работать с ней.
Стилизация колонок
Блоки колонок, созданные с помощью свойств CSS Columns, не могут быть выбраны для стилизации. Вы не можете выбрать их с помощью JavaScript или стилизовать отдельный блок, чтобы задать ему цвет фона или настроить padding или margin. Все блоки колонок будут одинакового размера. Единственное, что вы можете сделать, — это добавить разделительную линию между колонками, используя свойство column-rule
, которое работает как border. Вы также можете настраивать отступ между колонками, используя свойство column-gap
, которое имеет значение по умолчанию 1em, однако вы можете изменить его на любую другую допустимую единицу длины
Это базовый функционал CSS Columns. Вы можете взять часть содержимого и разделить на колонки. Содержимое будет заполнять колонки, создавая их в линейном направлении. Вы можете контролировать промежуток между колонками и добавить разделительную линию, указав те же значения, что и у border. Пока что всё идет хорошо, а всё вышеперечисленное очень хорошо поддерживается в браузерах и уже на протяжении длительного времени, что делает эту спецификацию очень безопасной для использования с точки зрения обратной совместимости.
Существуют особенности функционала CSS Columns и некоторые потенциальные проблемы, которые следует учитывать при использовании колоночного макета в вебе.
Охват колонок
Порой вам может потребоваться разбить некоторый контент на колонки, но затем один элемент разместить поперек, охватив блоки колонок. Достигнуть этого можно, применив свойство column-span
к потомку колоночного контейнера.
В примере ниже, я заставила элемент <blockquote>
охватить колонки. Заметьте, когда вы делаете это, содержимое разбивается на набор полей выше этого элемента, затем начинает новый набор колонок ниже него. Содержимое не перепрыгивает через охватывающий элемент.
На данный момент свойство column-span
по умолчанию работает во всех браузерах, кроме Firefox. В нём оно еще разрабатывается и скрыто за флагом
Имейте в виду, что в текущей спецификации значением свойства column-span
может быть только all
или none
. Вы не можете охватить только некоторые колонки, но можете получить такой результат, комбинируя колоночный макет с другими методами вёрстки. В следующем примере у меня есть Grid-контейнер с двумя столбцами. Левый столбец имеет ширину 2fr, а правый — 1fr. В левом столбце я обернула статью в колоночный контейнер с двумя колонками, также имеющими охватывающий элемент.
Справа остаётся содержимое, которое располагается во втором Grid-столбце. Играя разными доступными нам методами вёрстки, мы можем точно определить, какой из них лучше всего подходит в конкретной ситуации — не бойтесь совмещать их.
Контроль переноса содержимого
Если в колоночном контейнере содержатся заголовки, вы наверняка хотели бы избежать ситуаций, в которых они разрываются и часть заголовка или текст под заголовком переносится в следующую колонку. Если у вас есть изображения с подписями, было бы лучше, чтобы и изображение и подпись оставались одним целым, без разрыва между колонками. Специально для таких ситуаций, в CSS есть свойства для управления переносом содержимого.
Разделяя содержимое на колонки, вы выполняете так называемую фрагментацию. То же самое справедливо, если вы разделяете ваш контент между страницами, например, когда создаёте стили для печати. Следовательно, колонки ближе к Paged Media, чем к другим методам разметки в вебе. Из-за этого, в течение нескольких лет способом контроля переносов в содержимом было использование свойств page-break-
, которые были частью CSS 2.1.
-
page-break-before
-
page-break-after
-
page-break-inside
Позже спецификация CSS Fragmentation определила свойства, которые были разработаны для любого фрагментированного контекста, спецификация включает подробности для Paged Media, CSS Columns, и отложенной спецификации Regions; Regions также фрагментирует непрерывный фрагмент содержимого. Сделав эти свойства общими, их можно применять к любому будущему фрагментированному контексту, точно так же, как свойства выравнивания из Flexbox были перемещены в спецификацию Box Alignment для того, чтобы их можно было использовать в Grid и Block разметке
-
break-before
-
break-after
-
break-inside
Как пример, я использовала свойство bread-inside: avoid
для элемента <figure>
, чтобы предотвратить отделение подписи от самой картинки. Браузер, поддерживающий это свойство, должен сохранить элемент цельным, даже если колонки при этом будут выглядеть неравномерными.
К сожалению, поддержка этих свойств в CSS Columns довольно неоднозначна. Но даже там, где они поддерживаются, их следует рассматривать как предложение из-за того, что необходимо делать так много запросов, чтобы контролировать перенос, что браузер, по сути, не может делать перенос в любом месте. Спецификация определяет приоритеты в этом случае, однако для вас это может быть даже более полезно контролировать только наиболее важные ситуации.
Проблема колонок в вебе
Одна из причин, почему мы не видим массового использования CSS Columns в вебе, заключается в том, что это привело бы к изменению взаимодействия читателя со страницей, вынуждая его прокручивать не вверх-вниз, а в сторону. Согласитесь, это не очень удобно.
Если вы зафиксируете высоту контейнера, например, используя единицу измерения области просмотра vh, а содержимого будет слишком много, тогда переполнение произойдет в строчном направлении и мы получим горизонтальную прокрутку.
Указанная проблема делает использование CSS Columns в вебе тем, с чем мы должны работать очень осторожно с точки зрения количества размещаемого в нём содержимого.
Колонки, переполняющие блок
Для уровня 2 спецификации CSS Columns мы рассматриваем, как включить метод, с помощью которого переполненные колонки, те которые в данный момент приводят к появлению горизонтальной прокрутки, вместо этого увеличивались в блочном направлении.
Это значит, что вы можете иметь колоночный контейнер с фиксированной высотой, и как только содержимое создаст колонки, заполняющие этот контейнер, новый набор колонок будет создан ниже. Это было бы в чем-то похоже на наш пример выше с охватывающим элементом, однако вместо охвата, вызывающего новый блок колонок, это будет переполнение, вызванное контейнером с ограничением в блочном измерении.
Этот функционал сделал бы колонки существенно более полезными в вебе. Хотя мы всё еще далеки от этого, вы всё же можете следить за этой проблемой в репозитории рабочей группы CSS. Если у вас есть дополнительные примеры использования этого функционала, напишите о них, это действительно помогает, когда разрабатывается новый функционал.
Чем мультиколонки полезны сегодня?
С текущей спецификацией не рекомендуется разделять всё содержимое на колонки без учета возможных проблем с прокруткой. Тем не менее, есть некоторые ситуации, когда колонки идеально подходят. Существует достаточно примеров, достойных рассмотрения, когда вы ищете шаблоны проектирования.
Сокращение небольших элементов интерфейса или текста
Мультиколонки могут быть полезны в любом месте, где имеется небольшой список элементов, который должен занимать меньше пространства. Например, простой список чекбоксов или список имен. Часто в подобных ситуациях посетитель не читает до конца одну колонку, после чего возвращается наверх к началу следующей, а ищет в содержимом чекбокс для нажатия или ссылку для перехода. Даже если возникнет ситуация с появлением прокрутки, это не должно быть проблемой.
Вы можете видеть пример подобного использования колонок на сайте DonarMuseum
Заранее известное небольшое количество содержимого
Бывают ситуации, когда при разработке сайта нам заранее известно, что количество определенного содержимого будет небольшим и поместится на большинстве экранов, не вызывая нежелательной прокрутки. Я использовала колонки на страницах презентации на Notist для введения.
Andy Clarke разработал прекрасный пример для сайта Equfund
Чтобы избежать ситуаций возникновения прокрутки на очень маленьких экранах, помните, что можете использовать медиа-выражения для проверки высоты области просмотра так же, как и ширины. Если включите колонки только на тех контрольных точках, которые имеют минимальную высоту min-height
больше достаточной для содержимого, это может спасти пользователей очень маленьких устройств.
Masonry-подобное отображение контента
Другой пример, когда колоночный макет отлично работает — в ситуациях, когда вы хотите отобразить содержимое в стиле Masonry. Колонки в данный момент — это единственный метод разметки, который создаст этот тип разметки с элементами разной высоты. CSS Grid не оставит отступ или растянет элемент, чтобы строго соответствовать двухмерной сетке.
У Veerle Pieters есть отличный пример использования колонок для этих целей на её вдохновляющей странице.
Grid и Flexbox фолбеки
Свойства column-
также могут быть использованы как фолбек для Grid или Flex макета. Если вы укажете одно из колоночных свойств для контейнера, а затем превратите этот контейнер во Flex или Grid макет с помощью display: flex
или display: grid
любое поведение колонок будет отменено. Если у вас есть, например, карточный макет, который использует CSS Grid, и при этом будет удобочитаемым в нескольких колонках, можно использовать колонки как простой запасной вариант. Браузеры, которые не поддерживают CSS Grid, получат колоночное отображение, те которые поддерживают, получат Grid-сетку.
Не забывайте про мультиколонки!
Довольно часто, отвечая на вопросы о выборе между Grid или Flexbox, вместо них я рекомендую мультиколонки. Возможно, вы не будете использовать их на каждом сайте, но когда столкнетесь с подходящей задачей, они могут стать действительно полезными. На MDN присутствуют полезные ресурсы по CSS Columns и связанным с ними fragmentation properties.
Если вы используете колонки в своем проекте, возможно вам стоит оставить упоминание об этом в комментариях, чтобы поделиться другими способами использования этого функционала
Автор: Зварич Рома