В продолжение предыдущего поста про стилизацию элементов выбора, хотел бы рассказать как сделать полностью адаптивные табы без использования javascript, абсолютного позиционирования и хаков с ссылками.
Для начала хотел бы сказать, что я не призываю отказаться от javascript в пользу лишь CSS, ниже будет представлен лишь один из способов реализации табов. Существует множество ситуаций, когда такой подход вам не подойдёт и где без JS не обойтись, но сейчас не об этом.
Давайте поймём что мы хотим видеть в качестве результата работы и какие требования мы выдвигаем к нему:
- Работа без JavaScript,
- Нет привязки к количеству табов (мы можем использовать один виджет на разных страницах с разным контентом внутри),
- Адаптивность,
- Максимальная кроссбраузерность и кроссплатформенность,
- Максимально удобный и понятный UI,
- Нет ограничений к внутреннему содержанию табов, будь то текст, медиа контент или же вёрстка внутри таба.
Визуально должно получиться что-то подобное:
Пример табов
Перед тем как показать свой вариант табов без JS, я хотел бы рассказать о некоторых вариантах реализаций, которые я нашёл в процессе решения этой задачи.
Вариант первый
Человек придумавший этот способ либо явно хотел поиздеваться над пользователями, либо он один из посетителей реддита, который создавал те самые «удобные» регуляторы громкости. У меня подобный подход вызывает нервный тик.
Суть метода заключается в следующем:
В качестве заголовков (самих кнопок) табов используются ссылки, в атрибут href
, которых прописывается id соответствующей вкладки — div’а или любого другого элемента. Выделение активной вкладки происходит при помощи псевдокласса :target
.
Работает это так:
Как вы могли заметить мы имеем кое-какие проблемы с использованием данного метода:
- При нажатии на таб страница начинает скакать, так как браузер отправляет нас туда, куда ведёт данная ссылка. Избежать конечно же этого можно, но без JS уже ни как.
- Активный заголовок таба не выделяется, это можно сделать, но крайне проблематично.
- Изначально активных табов нет (так как мы ещё не нажимали на ссылки) и нам приходится прибегать к хаку и делать активным третий таб, выделить первый таким способом не получится.
- Весьма спорная адаптивность: да, вкладки перестраиваются на новую строку при сужении экрана, а контент таба сужается вместе с ней, однако выглядит это не очень красиво. Эту проблему могут решить медиа запросы, однако учитывая то, что мы ходим не привязываться к количеству табов, на некоторых размерах дисплеев проблема останется.
Делаем оправданный вывод: этот метод нам не подходит так как не удовлетворят большей части требований. Реализации ужасная и я не советовал бы её использовать.
Вариант второй
Этот метод создания табов без JavaScript уже более практичен, хотя так же имеет некоторые проблемы в применении. Суть метода в следующем: для заголовков вкладок используются элементы checkbox
и label
, а при помощи псевдокласса :checked
и ещё одного div
элемента мы можем показать контент только активной вкладки и скрыть все остальные:
|
.tab-wrapper input:checked + label + .tab-item{display: block;} |
Вот как это работает:
Как вы могли заметить, в этом примере мы используем position: absolute;
для того, чтобы разместить заголовки вкладок сверху, а контент вкладки снизу. Это создаёт определённые проблемы:
- Полная не адаптивность. При изменении размеров экрана вкладки падают вниз и контент вкладки закрывает их. Это можно исправить: сделать горизонтальный скролл вкладок, такое решение имеет место быть, но мне не очень нравится.
- Так как для отображения контента вкладок мы используем абсолютное позиционирование нам придётся указывать фиксированную высоту вкладок, иначе они будут перекрывать контент, который находится ниже (видно в примере), а это значит что мы не можем использовать данный подход при заранее неизвестном количестве вкладок.
Конечно, в некоторых случаях этот метод можно применять, на пример, когда вы заранее знаете количество вкладок и объём контента внутри них. Но мы ищем универсальное решение, поэтому данный подход не применим в нашем случае.
Решение
Третий вариант, и он же решение, является модификацией второго метода. Работает он точно так же, однако мы не будем использовать абсолютное позиционирование и свойство float
для заголовков.
В данном методе мы используем нынче модный flexbox для размещения вкладок и их контента. Вся прелесть flexbox тут заключается в том, что мы можем обозначить какие элементы отображать сначала, а какие в конце. Это можно сделать при помощи свойства order: 1;
, которое по умолчанию равно нулю.
Адаптивность вкладок так же достигается за счёт flex свойства flex-grow: 1;
, которое позволяет вкладкам растягиваться на всю ширину контента, за счёт этого мы можем не беспокоиться за отображение разного количества табов. Так же мы можем размещать контент любого и разного объёма внутри каждой вкладки, это не будет влиять на отображение контента после них.
Данный подход работает во всех современных браузерах, включая мобильные. Из, непривычных для многих, свойств используется только Flexbox, а он уже давно имеет широкую поддержку. В браузерах FireFox, Chrome, Safari и Opera мною не было обнаружено каких-либо проблем с работой вкладок.
Я добавил немного стилей, чтобы вкладки выглядели поинтересней.
Вы можете проверить данный подход на jsfiddle, или на своих проектах. Буду рад увидеть и другие предложения решений данной проблемы в комментариях.
comments powered by HyperComments