А если без JavaScript?
В нашем мире без JavaScript никуда! Куча фреймворков, библиотек и прочей радости! jQuery плотно вошел в нашу жизнь. React с Angular пробивают дорогу к светлому будущему. Да и не за горами поддержка браузерами ES6 без Babel.
Но если тема заходит об обычном сайте со стандартным функционалом, не редки случаи, когда JavaScript начинают “злоупотрелять”. И все, в принципе, нормально… Но порой задаешься вопросом: «А если без JavaScript?».
Поэтому хочу поделиться с Вами вариантами реализации того или иного функционала, используя только html и css. Возможно, какие-то Вы уже видели, или даже используете в своих проектах, но здесь я решил собрать все полезные (и не очень) наработки, которые могут заменить js.
Все примеры адаптивные и легко расширяемые. Логика работы построена на checkbox и radiobutton, с которыми связаны label по id. Id можно генерировать на стороне сервера.
Но сразу хочу заметить, что данный код служит лишь примером реализации, и я не добавлял к свойствам вендорных префиксов.
Пойдем от простых решений к более интересным.
1. Табы / вкладки
label — вкладка;
p — контейнер для текста (можно заменить на div, к примеру).
Чтобы добавить новую вкладку, надо добавить в html теги input+label+p.
2. Аккордеон
Работает по такому же принципу, как и 1 пример.
3. Модальное окно
Модальное окно открыто, когда input:checked.
Теперь в любом месте в документе можно разместить кнопку label[for=zayavka], нажатие на которую будет открывать модальное окно. «zayavka» — это id модального окна, а точнее id input’а, который его «открывает». Т.е. что бы добавить еще 1 модальное окно, надо скопировать input+div.modal и заменить id input’а и for у label, которые с ним связаны.
4. Навигация / меню
Это вариант реализации мобильного меню с подпунктами. Можно, естественно, адаптировать через медиа-запросы до десктопной версии.
5. Слайдер с превью изображений
Размер слайдера и количество изображений в нем можно сделать любое. Чтобы добавить новое изображение, нужно скопировать конструкцию input+(.item>img)+label>img (опять же, это можно генерировать автоматически на стороне сервера). Первый img — это основное изображение, второй img — превью. При желании, flex можно заменить на inline-block или float.
6. Карусель с «ленивой» загрузкой изображений
Размер карусели и количество изображений в ней можно сделать любое. Также можно доработать css и сделать отображение нескольких изображений в ряд. «Ленивая» загрузка здесь достигается путем того, что изображения прописываются в background-image для div, а в css есть строка, которая перебивает это свойство для div, которые не отображены на экране. В итоге, изображения загрузятся только тогда, когда пользователь начнет листать карусель.
Div с background-image можно заменить на обычный , но тогда ленивая загрузка работать не будет. Чтобы добавить новое изображение, надо добавить в html теги input+div>label+.item. Причем, for у label должен вести на input перед предыдущим изображением (пример см. в коде выше).
Итог
Все примеры не привязаны к id элементов и их количеству! Т.е. не надо лезть в css при добавлении слайда в карусель, или новой вкладки таба. Id элементов можно задавать любые — все будет работать!
Так же хочу добавить, что, например, «прилипание» меню к верхней части экрана при скроллинге можно сделать, установив свойство position: sticky для меню. Но это свойство поддерживается не всеми браузерами.
Надеюсь, данная статья оказалась полезна для Вас! Таким образом можно реализовать еще много различных элементов на сайте без JavaScript. Один из плюс таких реализаций — это работа в браузерах с выключенным JavaScript (если в наше время кто-то таким пользуется).
Как сделать адаптивные табы (вкладки) на css без использования скриптов
Добрый вечер! Сегодня я вам расскажу, каким образом можно сделать табы (вкладки) на чистом css3 без какого-либо использования jquery или других скриптов. Как вы уже знаете, чем меньше вы будете использовать скриптов, тем лучше для вашего сайта, и тем быстрее он будет работать. А скорость сайта сегодня один из самых важных показателей его ранжирования в поисковых системах.
Адаптивные вкладки (табы) на чистом css и без скриптов
Сегодня табы есть практически на любом сайте. Они необходимы для того, чтобы отображать несколько областей контента без перехода пользователя на другие страницы. Например, на одном из моих проектов по разработке интернет-магазина на Joomla было добавление двух табов, которые будут отображать по 3 товара двух типов: “хиты продаж” и “последние”. Принято решение делать их на чистом css без перезагрузки сайта ненужными скриптами.
HTML код для табов с использованием css3 по пунктам
1. В первую очередь нам необходимо создать div с классом “tabs”.
2. Добавляем непосредственно кнопки-переключали с именем “tabs”, при нажатии на которые они будут включать содержимое наших табов.
3. Добавляем их название через label
4. Под кнопками, которые мы с Вами сделали в пунктах 1-3, мы добавляем уже непосредственно контент, который нам нужно выводить. В моем случае это три последних товара и три лучших товара.
Каждый блок у нас имеет класс tab-content и идентификаторы tab-content-1 и tab-content-2.
Итоговый HTML наших будущих табов
Хиты продаж
Последнее
На этом мы закончили с написанием нашего html. Согласитесь, ничего сложного тут не было. Итак, идем дальше.
CSS стили для табов с использованием css3 по пунктам
Теперь самое интересное и сложное. Нам нужно наши табы сделать табами, которые будут переключаться при клике
Так как у нас будет два таба, то нам нужно назначить им такую ширину, чтобы они помещались на экране и не вылазили за его черту. Для этого мы прописываем ширину 50%. Если у вас будет другое число табов, то и ширину рассчитывайте отталкиваясь от их числа.
Также, обратите внимание, что по умолчанию, мы делаем наши кнопки-переключатели невидимыми
.tabs < max-width: 90%; float: none; list-style: none; padding: 0; margin: 75px auto; border-bottom: 4px solid #ccc; >.tabs:after < content: ''; display: table; clear: both; >.tabs input[type=radio] < display:none; >.tabs label p < padding: 5px; margin-right: 0; >.tabs label < display: block; float: left; width: 50%; color: #ccc; font-size: 30px; font-weight: normal; text-decoration: none; text-align: center; line-height: 2; cursor: pointer; box-shadow: inset 0 4px #ccc; border-bottom: 4px solid #ccc; -webkit-transition: all 0.5s; /* Safari 3.1 to 6.0 */ transition: all 0.5s; >.tabs label span < display: none; >.tabs label:hover < color: #3498db; box-shadow: inset 0 4px #3498db; border-bottom: 4px solid #3498db; >.tab-content
Как заставить это работать
А тут все просто.
Добавляем следующий css код
.tabs [id^=»tab»]:checked + label < background: #FFF; box-shadow: inset 0 4px #3498db; border-bottom: 4px solid #3498db; color: #3498db; >#tab-first:checked ~ #tab-content-1, #tab-second:checked ~ #tab-content-2
Строками выше мы добавляем особы стиль для активного таба используя :checked + label
Далее мы уже проверяем, какой наш переключатель имеет статус checked и отображаем содержимое, которое у нас прикреплено за ним, используя его id.
#tab-first:checked ~ #tab-content-1 – данная строка говорит о том, что нам нужно отобразить контент, который имеет id=”tab-content-1″, если tab-first имеет статус checked.
Делаем наши табы адаптивными
@media (min-width: 768px) < .tabs p < padding: 5px; margin-right: 10px; >.tabs < max-width: 750px; margin: 50px auto; >>
Ну вот по сути и все. Наши табы готовы :). Вы их можете менять как угодно, добавлять-удалять. Спасибо за внимание
автор: Роман Довгаль
С 2010 года я занимаюсь интернет маркетингом. Сюда входит и SEO, и SMM, и SMO, и, собственно маркетинговое продвижение не только сайтов, а проектов в комплексе 🙂
Для меня каждый проект – это отдельная жизнь. Своя целевая аудитория, свои методы продвижения, свои показатели результативности 🙂
Делаем адаптивные табы без javascript и грязных хаков

В продолжение предыдущего поста про стилизацию элементов выбора, хотел бы рассказать как сделать полностью адаптивные табы без использования 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, или на своих проектах. Буду рад увидеть и другие предложения решений данной проблемы в комментариях.
Понравилась статья? Поделитесь ею:
Интерфейсы с вкладками без JavaScript
Все больше и больше хитрых интерфейсных функций опираются на JavaScript, из-за чего создают проблемы доступности. Даже с учетом того, что на сегодняшний день JS им больше не требуется. CSS3 принес нам, как разработчикам, много интересных возможностей, позволив реализовать модальные диалоги, мобильные меню “гамбургеры” и даже интерфейсы с вкладками без единой строчки JavaScript-кода.
Что плохого в JavaScript?
Ничего само по себе, если это не единственное ваше средство обеспечения удобства или функциональности на странице. JavaScript должен улучшать работающую страницу, а не оказываться единственным, благодаря чему она функционирует.
Если базовая функциональность не работает, когда JS-скрипты заблокированы, отключены или иным образом не задействованы, ваша страница не соответствует требованиям WCAG, и поэтому вы рискуете подвергнуться судебному преследованию или гражданскому разбирательству в соответствии с такими законами, как ADA в США или EQA в Великобритании. Программное обеспечение, которое читает страницу вслух, программы для чтения шрифта Брайля, поисковые системы и другие невизуальные юзер-агенты испытывают трудности, если им прямо не закрыт доступ, со страницами, где для всего применяется JavaScript. Многие пользователи также блокируют JS из-за недоверия или работают в местах, где он намеренно отключен. JavaScript не должен быть постоянной технологией для решения каждой мимолетной проблемы на стороне клиента!
Опять же, я не утверждаю, что надо полностью отказаться от JavaScript, но он должен улучшать пользовательский опыт, а не предоставлять его в одиночку.
Как же реализовать вкладки по-другому?
Это, на самом деле, довольно просто — спасибо CSS3 и таким “новинкам” (если то, чему в 2020 году уже исполнилось десять лет, можно считать новинкой), как :checked , :nth-child и общий комбинатор смежных селекторов. В основном для достижения нашей цели мы “злоупотребляем” .
Настоящая магия здесь в том, что если нажать на , где атрибут for=”” указывает на поле ввода input , то получится то же самое, если бы вы нажали в это поле напрямую! Таким образом, для правильной семантики можно поместить ярлыки в список отдельно, после ввода.
Все будет размещаться в , так что находить нужные цели, не разбрасывая классы по всей разметке, будет легко.
Разметка
Во-первых, входные данные:
type="radio"
name="tabset_1"
hidden
aria-hidden="true"
checked
>
type="radio"
name="tabset_1"
hidden
aria-hidden="true"
>
type="radio"
name="tabset_1"
hidden
aria-hidden="true"
>
type="radio"
name="tabset_1"
hidden
aria-hidden="true"
>
Все они получают одно и то же имя и функционально аналогичны сочетанию радио-кнопок с уникальными идентификаторами для каждой. Мне нравится использовать имя в качестве префикса к идентификатору.
Они “скрыты” ( hidden ), так что когда наш экранный медиа-запрос CSS неприменим/не имеет смысла для UA, они игнорируются. Более того, я установил aria-hidden=”true” , так что если CSS медиа-запрос будет применен к озвучиванию/распознаванию текста (так не должно быть, но некоторые UserAgent’ы способны на всякое), то все равно будет проигнорирован. Помните: такие вещи, как вкладки, предназначены только для восприятия на экране.
Вот список меток, которые станут нашими “вкладками”:
Они тоже “скрыты” как с помощью атрибута, так и через aria-hidden . Простой список вариантов с правильной семантикой (если вы опустите ul / li , некоторые UA могут показать вывод, что это просто бессмысленный набор символов). Опять же, магия в том, что клик по этим меткам — то же самое, что клик по полю ввода, для которого они предназначены.
Затем содержимое нашей вкладки можно рассматривать как внутри :
Description
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Donec id elementum neque, ac pharetra tortor. Vivamus ac vehicula augue. Curabitur pretium commodo nisi id pellentesque.
Statistics
Sed ut leo in turpis efficitur convallis at bibendum erat. Curabitur in egestas ex. Etiam efficitur sagittis molestie. Praesent condimentum elementum ipsum sit amet euismod. Sed vestibulum, leo ac iaculis fringilla, felis nulla placerat turpis, eu aliquam elit risus vel tellus.
Reviews
Donec non nunc ac augue ornare aliquam. Aenean sed volutpat arcu. Sed molestie lacus placerat nisl gravida condimentum.
Contact
Nullam nec condimentum lacus. Integer dapibus velit nec ipsum varius, a pharetra arcu imperdiet. Donec pretium libero a tincidunt vulputate. Mauris feugiat tempor lectus, quis placerat mi congue sit amet.
Каждый из них получает тэг , содержащий описание раздела для невизуальных UA. При желании эти заголовки в таблице стилей экранных медиа можно скрыть.
Стили
Весь этот код также предполагает, что используется некоторая форма “сброса”. Во-первых, нам нужно нацелить поле ввода так, чтобы ввод больше не был “скрыт” атрибутом, чтобы сохранить возможность навигации с помощью клавиатуры, при этом оставив его невидимым. Заодно это исправляет ошибку, при которой IE не может изменять состояние поля ввода, имеющего атрибут hidden , если не установить его видимым через команду display :
.tabset > input display:block; /* "включает" скрытые элементы в IE/Edge */
position:absolute; /* а потом скрывает их за пределом экрана */
left:-100%;
>
Далее идет наш неупорядоченный список:
.tabset > ul position:relative;
z-index:999;
list-style:none;
display:flex;
margin-bottom:-1px;
>
position:relative; и z-index:999; — это трюк, которым можно воспользоваться, чтобы нижние границы вкладок перекрывались с рамкой вкладки. Для помещения всех меток в одну строку мы могли бы применить inline-block или float , но в наши дни есть флекс-верстка, и она намного проще!
Поскольку все наши и рамка вокруг вкладок содержимого имеют одну и ту же границу, нетрудно сразу же объявить их вместе:
.tabset > ul label,
.tabset > div border:1px solid hsl(220, 100%, 60%);
>
С помощью HSL проще переключить всю цветовую схему, ведь можно просто найти/заменить “hsl(220” как вам будет угодно… или использовать переменные CSS для его назначения.
.tabset > ul label display:inline-block;
padding:0.25em 1em;
background:hsl(220, 100%, 90%);
border-right-width:0;
>
Они настроены как inline-block , поэтому подчиняются отступам top/bottom . Взамен можно установить display:block , но так как они находятся на одной линии, inline-block представляется мне удобнее. Обратите внимание, что граница по правому краю таким образом будет удалена. Мы скоро к этому вернемся.
.tabset > ul li:first-child label border-radius:0.5em 0 0 0;
>
Закруглим угол первого:
.tabset > ul li:last-child label border-right-width:1px;
border-radius:0 0.5em 0 0;
>
Закруглим верхний правый угол последнего, а затем повторно применим правую границу. И глядите: никакой двойной границы между элементами, а первые и последние получают некоторое легкое закругление:
.tabset > div position:relative;
background:hsl(220, 100%, 98%);
border-radius:0 0.5em 0.5em 0.5em;
>
, обертывающий наши теги , получает более светлый фон и закругление везде, кроме верхнего левого угла, где он находится вровень с нашими вкладками.
Теперь начинается “сложная” часть. Во-первых, нам нужен стиль, применяемый к метке, когда используется навигация с клавиатуры. Простое подчеркивание на :focus может сработать. Это покажется сложным, но на самом деле все очень просто:
.tabset > input:nth-child(1):focus ~ ul li:nth-child(1) label,
.tabset > input:nth-child(2):focus ~ ul li:nth-child(2) label,
.tabset > input:nth-child(3):focus ~ ul li:nth-child(3) label,
.tabset > input:nth-child(4):focus ~ ul li:nth-child(4) label,
.tabset > input:nth-child(5):focus ~ ul li:nth-child(5) label,
.tabset > input:nth-child(6):focus ~ ul li:nth-child(6) label,
.tabset > input:nth-child(7):focus ~ ul li:nth-child(7) label,
.tabset > input:nth-child(8):focus ~ ul li:nth-child(8) label,
.tabset > input:nth-child(9):focus ~ ul li:nth-child(9) label text-decoration:underline;
>
Конечно, это ограничивает нас в количестве вкладок, но, честно говоря, если у вас более девяти вкладок, возможно, пора подумать о другом стиле интерфейса и разбить его на несколько страниц. На веб-сайте вы редко увидите более пяти вкладок, и на то есть причины.
Логика на самом деле проще, чем кажется. Рассмотрим только один селектор:
.tabset > input:nth-child(1):focus ~ ul li:nth-child(1) label,
Внутри .tabset , когда первое поле ввода в фокусе, метка внутри первого li любого соседнего неупорядоченного списка получит наш стиль. И это буквально всё. Это означает, что когда вы устанавливаете фокус на поле ввода (с помощью клавиатуры или кликнув по нему), связанная метка становится подчеркнутой. И то же самое для любого количества вкладок, которые нам нужно поддерживать, вплоть до максимума.
Затем этот же шаблон можно повторить для проверки входных данных:
.tabset > input:nth-child(1):checked ~ ul li:nth-child(1) label,
.tabset > input:nth-child(2):checked ~ ul li:nth-child(2) label,
.tabset > input:nth-child(3):checked ~ ul li:nth-child(3) label,
.tabset > input:nth-child(4):checked ~ ul li:nth-child(4) label,
.tabset > input:nth-child(5):checked ~ ul li:nth-child(5) label,
.tabset > input:nth-child(6):checked ~ ul li:nth-child(6) label,
.tabset > input:nth-child(7):checked ~ ul li:nth-child(7) label,
.tabset > input:nth-child(8):checked ~ ul li:nth-child(8) label,
.tabset > input:nth-child(9):checked ~ ul li:nth-child(9) label background:hsl(220, 100%, 98%);
border-bottom-color:hsl(220, 100%, 98%);
>
Если сделать их того же цвета и нижней границы, что и содержимое , то получится, что вкладка будет сверху. Вот тут-то и вступает в игру наш нижний отступ -1px .
А что же насчет отображения/скрытия содержимого ? Сначала спрячем секции:
.tabset > div > section,
.tabset > div > section h2 position:absolute;
top:-999em;
left:-999em;
>
Тот же код я использую, чтобы скрыть h2 за пределами экрана. Большая проблема с программами для чтения с экрана и некоторыми другими UA для незрячих состоит в том, что зачастую они не будут читать контент, если вы настроите их на display:none; или visibility:hidden; . В частности поисковые системы часто будут подчиняться поведению экранных медиа-запросов, когда этого не стоило бы делать при поиске недобросовестных SEO-мошенников, пытающихся использовать маскировку контента. Сдвинув этот тэг с экрана, мы в лучшем случае полностью избегаем описанной выше проблемы, в худшем — получаем отметку для проверки вручную, во время которой любой компетентный человек в Google скажет, что все в порядке.
При любой возможности старайтесь не использовать display:none в основных разделах, будь он заскриптован или осуществлен через CSS! Вы рискуете тем, что контент останется незамеченным поиском и другими невизуальными юзер-агентами.
Затем я установил отступы для везде, кроме нижней части. Я предпочитаю внутренние отступы ( padding ) вместо внешних ( margin ), чтобы избежать проблем со “слипанием”. Если вы ставите отступ на нижнюю часть элементов контента, то ставьте и на все направления элемента-родителя, с этим просто легче иметь дело:
.tabset > div > section padding:1em 1em 0;
>
Следом мы используем ту же логику селектора, что и с ul , чтобы переключиться с на display:static; :
.tabset > input:nth-child(1):checked ~ div > section:nth-child(1),
.tabset > input:nth-child(2):checked ~ div > section:nth-child(2),
.tabset > input:nth-child(3):checked ~ div > section:nth-child(3),
.tabset > input:nth-child(4):checked ~ div > section:nth-child(4),
.tabset > input:nth-child(5):checked ~ div > section:nth-child(5),
.tabset > input:nth-child(6):checked ~ div > section:nth-child(6),
.tabset > input:nth-child(7):checked ~ div > section:nth-child(7),
.tabset > input:nth-child(8):checked ~ div > section:nth-child(8),
.tabset > input:nth-child(9):checked ~ div > section:nth-child(9) position:Static;
>
О display:static; нужно помнить то, что он по сути игнорирует все правила позиционирования, а значит текущий выбранный раздел появится в поле зрения без необходимости изменять какие-либо другие свойства.
И это подходит для быстрой и не слишком тщательной реализации. Можно пойти путем посложнее, например, воспользоваться display:flex; на и position:relative , чтобы сдвинуть их все на место, открывая дорогу для изощренных анимаций и тому подобного.
Наконец, поскольку всё это управляется метками и вы нажимаете на метки, возникает проблема: быстрый клик или случайное перетаскивание во время клика могут неправильно выделить текст. Кроме того, если кто-то соберется копировать/вставлять что-нибудь со страницы, вы можете не захотеть, чтобы в копии содержались метки, поскольку они избыточны для h2 , который и будут копировать. Следовательно:
.tabset > ul label -webkit-touch-callout:none;
-webkit-user-select:none;
-khtml-user-select:none;
-moz-user-select:none;
-ms-user-select:none;
user-select:none;
>
Так мы запрещаем выделять метки. Может показаться, что применение всех версий префиксов браузера бессмысленно, но если вы проверите “Can I use”, то увидите — таблица совместимости говорит, что все версии IE нуждаются в -ms- , все версии Safari по-прежнему нуждаются в -webkit- , версия -moz- была удалена только недавно и вместе с этим была удалена поддержка новой сборки для некоторых старых ОС, о которой нам все еще нужно беспокоиться, и т. д.
Но на самом деле кроме этого, больше ничего и не надо.
Наглядная демонстрация
Каталог файлов:
https://cutcodedown.com/for_others/medium_articles/tabsWithoutJS/
Он открыт для легкого доступа к разным частям. Я поместил туда файл разметки .txt для тех, кто стесняется “view-source”, и там есть также файл tabs.rar, содержащий полный код для легкой загрузки.
Обратите внимание на функциональность для клавиатуры. Нажимайте [tab], пока не увидите подчеркивание на одной из вкладок, или нажмите на одну, чтобы установить на ней фокус, а затем попробуйте нажимать клавиши со стрелками. Когда на какой-либо из радио-кнопок устанавливается фокус, вы можете переключаться между ними с помощью стрелок.
За и против
Недостатки
- Вы полагаетесь на более современные браузеры, чтобы всё работало. Предложенный метод должен хорошо функционировать во всех браузерах новее IE 10. Сейчас я привык просто блокировать CSS в устаревших браузерах и позволять страницам спокойно деградировать до семантической разметки.
- Для каждой дополнительной вкладки приходится добавить по три строки CSS, чтобы она поддерживалась в трех разных окружениях. Это может быть громоздко, но если вам на самом деле нужно больше девяти вкладок, то, вероятно, именно такой способ вам не подходит.
- Эта реализация не создает в разметке бесконечные классы просто так. Это может расстроить некоторых разработчиков, которые не могут справиться с селекторами и верят в наглую ложь вроде того, что бесконечные бессмысленные классы, которые увеличивают необходимую разметку в два раза, а то и в двенадцать, каким-то волшебным образом делают рендеринг “быстрее”. Подождите, разве это недостаток? К сожалению, для многих это так.
Преимущества
- Основная структура раздела — правильная семантическая разметка контента, что означает большее удобство использования для невизуальных UA и альтернативной навигации.
- Функциональность не основывается целиком на JavaScript, поэтому, в отличие от других методов, этот не нарушает WCAG.
- В любом современном браузере с выключенным CSS все наши элементы управления на UI исчезают, оставляя правильную доступную структуру.
- Поскольку эта структура на 100% управляется CSS, вы можете расширить ее с помощью CSS-переходов, анимации или любых других эффектов, которые только придут в голову.
- Разметка не захламляется выдуманными сказочными несемантическими тегами, бесконечными бессмысленными классами и другими глупостями разработчиков.
- Применение атрибута hidden HTML 5 и aria-hidden=”true” приводит к тому, что программы для чтения с экрана, программы для чтения шрифта Брайля, пользователи, просматривающие без CSS, и так далее, игнорируют всю избыточную разметку, используемую для создания вкладок, и просматривают страницу, как если бы это были просто обычные разделы с заголовками.
- Так получается гораздо меньше кода, чем если бы вы применили любой из памятников невежеству, некомпетентности и неумелости разработчиков, которые называются интерфейсными фреймворками.
Вывод
“Злоупотребление” с помощью CSS-свойства :checked и общего комбинатора смежных селекторов поможет вам избежать многих заскриптованных глупостей и большинства проблем доступности. Решения проблем с помощью одного только JavaScript следует избегать, и у нас наконец-то есть для этого инструменты!
Я надеюсь, что это вам пригодилось, и серьезно, ребята: уделите больше внимания доступности ваших сайтов, особенно в том, что происходит, когда нет JavaScript. Можно было бы подумать, что Бейонсе и Domino’s, которых таскают по судам как раз по таким вопросам, послужат тревожным звонком для разработчиков, работающих на реальный бизнес, но нет. Слишком многие разработчики прячут головы в песок, отрицая ошибки, и продолжают действовать, руководствуясь лишь апатией, невежеством и принятием желаемого за действительное.
Не позволяйте подходу “но миллионы людей именно так и поступают” или “но это прекрасно работало долгие годы” — он же “ошибка выжившего” — обмануть вас и не позволить принять лучшую стратегию действий или помешать создавать веб-сайты, которые действительно способны делать то, что имеет значение, а именно — поставлять контент как можно большему числу пользователей, независимо от ограничений устройства или его недостатков.
- Темная сторона Javascript: избегайте данных трех функций
- JavaScript: 5 нововведений 2021 года
- 10 хитрых приемов в JavaScript, о которых должен знать каждый разработчик
