Открытие блока при нажатии css

Создаем блоки раскрывающегося текста на HTML, CSS и JavaScript

В этой статье описывается, как без использования сторонних библиотек с помощью HTML, CSS и JavaScript создать раскрывающийся текст. Вот как этот элемент интерфейса выглядит в действии.

Подходы

Для создания подобных панелей расширения используется несколько подходов:

  1. На основе анимации и переходов, примененных к свойствам height или max-height контента.
  2. Использование transform: translateY для перемещения элементов на новую позицию, создания эффекта закрытия панели и повторной визуализации DOM.
  3. Применение сторонней библиотеки.

Какой из подходов лучше?

С точки зрения производительности использование transform более эффективно, чем анимация height и max-height. При применении CSS-свойства transform элементы растризуются и перемещаются графическим процессором. Это низко затратная и простая операция для графического процессора.

Для реализации данного подхода нужно выполнить следующие действия:

  1. Получить высоту контента, который будет располагаться на панели.
  2. Переместить контент выше на высоту содержимого, которое будет свернуто с помощью transform: translateY(Xpx). С помощью перехода реализовать эффект открытия и закрытия панели.
  3. С помощью JavaScript перехватить событие transitionend. После его наступления задаем display: none для контента и удаляем преобразование.

Но у данного метода есть множество недостатков. Например, при использовании transform: translateY необходимо учитывать z-index элемента.

Читайте также:  Add javascript link to head

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

Применение переходов к max-height работает не так хорошо, как свойство transform. Так как браузер изменяет высоту сворачивающегося элемента на протяжении всего перехода. Эта операция потребляет много ресурсов памяти и графического процессора. Но зато данный подход проще в реализации.

Подход на основе элементов details и summary

В HTML существуют элементы details и summary, которые позволяют создать панель расширения:

 
Click to open/close Here is the content that is revealed when clicking the summary.

Кроме этого элемент details поддерживает JavaScript-событие toggle. Поэтому можно изменять HTML в зависимости от того, скрыто или отображается содержимое панели.

details.addEventListener("toggle", () => < details.open ? thisCoolThing() : thisOtherThing(); >)

Но элементы details и summary не анимируются и к ним нельзя применять переходы. Поэтому используем другие средства.

Шаблон разметки

Основная разметка будет выглядеть следующим образом:

 
All the content here

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

Базовая логика

  1. После загрузки веб-страницы измеряем высоту содержимого.
  2. Устанавливаем высоту содержимого в контейнере в качестве значения пользовательского свойства CSS.
  3. Скрываем содержимое, добавив к нему атрибут aria-hidden: «true».
  4. Устанавливаем max-height в качестве значения пользовательского свойства.
  5. Нажатие кнопки изменяет значение свойства aria-hidden с true на false. А также max-height содержимого с 0 на высоту, заданную в пользовательском свойстве. Затем с помощью переходов реализуем визуальный эффект.

JavaScript-код

// Получаем контейнер const container = document.querySelector(".container"); // Получаем контент: const content = document.querySelector(".content"); // 1. Получаем высоту контента, который мы хотим показать/скрыть const heightOfContent = content.getBoundingClientRect().height; // Получаем кнопку const btn = document.querySelector(".trigger"); // 2. Задаем пользовательские свойства CSS с высотой контента container.style.setProperty("--containerHeight", `$px`); // Когда высота задана setTimeout(e => < document.documentElement.classList.add("height-is-set"); 3. content.setAttribute("aria-hidden", "true"); >, 0); btn.addEventListener("click", function(e) < container.setAttribute("data-drawer-showing", container.getAttribute("data-drawer-showing") === "true" ? "false" : "true"); // 5. Переключаем значение aria-hidden content.setAttribute("aria-hidden", content.getAttribute("aria-hidden") === "true" ? "false" : "true"); >)

CSS

.content < transition: max-height 0.2s; overflow: hidden; >.content[aria-hidden=»true»] < max-height: 0; >// 4. Задаем для высоты значение пользовательского свойства .content[aria-hidden=»false»]

Как насчет нескольких блоков?

Если на странице есть несколько раскрывающихся блоков, то нужно будет перебрать их все. Но только в том случае, если они разного размера. Для этого используйте querySelectorAll, чтобы получить все контейнеры и повторно задать пользовательские переменные через forEach.

setTimeout

Метод setTimeout с продолжительностью 0 до вывода контейнера используется для первоначального вывода веб-страницы. Это позволяет получить высоту контента.

Когда страница готова

Кроме этого можно обернуть код блока в функцию, которая инициализируется при загрузке страницы. Например:

window.addEventListener("load", initDrawers);

Мы добавим ее в ближайшее время.

Дополнительные атрибуты data для контейнера

Мы добавляем атрибут data тогда, нужно что-то нужно изменить, когда панель открывается / закрывается. Например, цвет какого-то элемента.

Значение по умолчанию для пользовательского свойства

По умолчанию для пользовательского свойства установлено значение 1000px. Оно указывается после запятой внутри значения: var(—containerHeight, 1000px). Вы можете установить другое значение.

Почему бы не использовать значение по умолчанию 10000000px?

Проблема заключается в том, что переход всегда будет выполняться от этой высоты. Если длительность перехода установлена ​​в 1 сек., переход будет выполняться со скоростью 10000000 пикселей в секунду. Если контент имеет высоту всего 50px, то вы получите довольно быстрый эффект открытия / закрытия.

Тернарный оператор для переключателей

Тернарный оператор является укороченной формой if / else. В нем сначала указывается условие, которое нужно проверить. Затем ? отделяет код для выполнения, если true. После : идет код, который будет выполняться, если проверка ложна.

isThisTrue ? doYesCode() : doNoCode();

Что происходит при изменении размера окна браузера?

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

Повышаем доступность (Accessibility)

Чтобы повысить доступность создаваемой панели, используйте атрибуты aria-expanded, aria-controls и aria-labelledby. Это даст вспомогательным технологиям лучшее представление о том, когда панели будут открыты / раскрыты. Мы добавляем aria-expanded=»false» к кнопке и aria-controls=»IDofcontent», где IDofcontent — это идентификатора контейнера с контентом.

Затем мы используем другой тернарный оператор для переключения в JavaScript атрибута aria-expanded по клику.

Все вместе

Полная версия JavaScript-кода примера:

var containers; function initDrawers() < // Получаем контейнер с контентом containers = document.querySelectorAll(".container"); setHeights(); wireUpTriggers(); window.addEventListener("resize", setHeights); >window.addEventListener("load", initDrawers); function setHeights() < containers.forEach(container =>< // Получаем контент let content = container.querySelector(".content"); content.removeAttribute("aria-hidden"); // Высота контента, который нужно скрыть/показать let heightOfContent = content.getBoundingClientRect().height; // Задаем пользовательские свойства CSS с высотой контента container.style.setProperty("--containerHeight", `$px`); // Когда высота считана и задана setTimeout(e => < container.classList.add("height-is-set"); content.setAttribute("aria-hidden", "true"); >, 0); >); > function wireUpTriggers() < containers.forEach(container => < // Получаем все элементы-триггеры let btn = container.querySelector(".trigger"); // Получаем контент let content = container.querySelector(".content"); btn.addEventListener("click", () =>< btn.setAttribute("aria-expanded", btn.getAttribute("aria-expanded") === "false" ? "true" : "false"); container.setAttribute( "data-drawer-showing", container.getAttribute("data-drawer-showing") === "true" ? "false" : "true" ); content.setAttribute( "aria-hidden", content.getAttribute("aria-hidden") === "true" ? "false" : "true" ); >); >); >

Вы также можете поэкспериментировать с кодом, размещенным на CodePen

Заключение

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

Вадим Дворников автор-переводчик статьи « Make Your Own Expanding And Contracting Content Panels »

Пожалуйста, опубликуйте свои отзывы по текущей теме статьи. За комментарии, лайки, отклики, дизлайки, подписки низкий вам поклон!

Источник

Выпадающий блок при нажатии на HTML + CSS

Выпадающий блок при нажатии на HTML + CSS

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

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

Так выглядит при проверке, где изменена палитра, также добавлены некоторые элементы для редактирование.

Чистый CSS-аккордеон с помощью CSS3

Приступаем к установке:

.gaonutosal <
float: left;
width: 37%;
padding: 0 1em;
>

.pesontedan <
position: relative;
margin-bottom: 1px;
width: 100%;
color: #f3f1f1;
overflow: hidden;
>

.pesontedan input <
position: absolute;
opacity: 0;
z-index: -1;
>

.pesontedan label <
position: relative;
display: block;
padding: 0 0 0 1em;
background: #1c3e5d;
line-height: 3;
cursor: pointer;
text-shadow: 0 1px 0 #333131;
font-size: 17px;
>

.pesontedan-content <
max-height: 0;
overflow: hidden;
background: #0d7b8e;
transition: max-height .40s;
font-size: 14px;
color: #fffdfd;
text-shadow: 0 1px 0 #292727;
>

.pesontedan-content <
background: #0f6f80;
>
.pesontedan-content p <
margin: 1em;
>
/* :checked */
.pesontedan input:checked ~ .pesontedan-content <
max-height: 100vh;
>

/* Icon */
.pesontedan label::after <
position: absolute;
right: 0;
top: 0;
display: block;
width: 3em;
height: 3em;
line-height: 3;
text-align: center;
-webkit-transition: all .40s;
-o-transition: all .40s;
transition: all .40s;
>
.pesontedan input[type=checkbox] + label::after <
content: «+»;
>
.pesontedan input[type=radio] + label::after <
content: «\25BC»;
>
.pesontedan input[type=checkbox]:checked + label::after <
transform: rotate(315deg);
>
.pesontedan input[type=radio]:checked + label::after <
transform: rotateX(180deg);
>

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

Источник

Оцените статью