Как свернуть текст в html
Перейти к содержимому

Как свернуть текст в html

  • автор:

<details> , <summary>

Нативный раскрывающийся блок с контентом без магии и JavaScript.

Время чтения: меньше 5 мин

  1. Кратко
  2. Пример
  3. Как понять
  4. Как пишется
  5. Подсказки
  6. На практике
    1. Лена Райан советует
    2. Татьяна Фокина советует

    Обновлено 26 октября 2022

    Кратко

    Скопировать ссылку на секцию «Кратко» Скопировано

    Блок с раскрывающимся контентом на чистом HTML.

    Пример

    Скопировать ссылку на секцию «Пример» Скопировано

    Самый простой раскрывающийся блок выглядит вот так:

    Как понять

    Скопировать ссылку на секцию «Как понять» Скопировано

    Иногда нужно скрывать какую-то информацию на странице в специальном блоке. Чтобы в любой момент можно было кликнуть на этот блок и развернуть информацию. И свернуть обратно таким же кликом. Такой блок ещё называют «аккордеоном».

    Как пишется

    Скопировать ссылку на секцию «Как пишется» Скопировано

    Тег <details> — это интерактивный элемент, при нажатии на который открывается блок с информацией — текстом или картинками. Нередко такие элементы можно встретить на страницах с часто задаваемыми вопросами (FAQ), где в заголовке (или легенде) написан вопрос, а ответом является содержимое «аккордеона».

    Тег <summary> — это заголовок «аккордеона», так называемая легенда. Он необязателен — без него в качестве легенды будет написан текст «Подробнее», «Details» или нечто подобное — в зависимости от выбранного языка и браузера.

    Собирается «аккордеон» очень просто: в <details> вкладываем <summary> и теги с информацией, которая будет показываться при нажатии.

    По умолчанию «аккордеон» закрыт, но если мы хотим, чтобы его содержание показывалось сразу при загрузке страницы или открывать его из JavaScript, нужно добавить к нему атрибут open .

    Подсказки

    Скопировать ссылку на секцию «Подсказки» Скопировано

    �� Можно вкладывать <details> в <details> .

    �� <details> — это интерактивный элемент, но вкладывать другие интерактивные элементы в него можно.

    �� В HTML-стандарте написано, что <summary> должен быть первым ребёнком в <details> , но на деле всё прекрасно работает, даже если <summary> находится между тегами содержательной части «аккордеона».

    �� Вёрстка не ломается, если вложить <summary> в <summary> — в таком случае будет только один элемент : : marker (треугольник перед легендой).

    �� Если в «аккордеоне» будет несколько <summary> подряд, браузер будет реагировать только на первый, а остальные даже не отобразятся, хотя будут стоять в разметке.

    �� Если указать просто <summary> без <details> , то он будет вести себя как обычный <div> — блочный элемент без интерактивности.

    На практике

    Скопировать ссылку на секцию «На практике» Скопировано

    Лена Райан советует

    Скопировать ссылку на секцию «Лена Райан советует» Скопировано

    �� Если присутствует тег <summary> , то псевдоэлемент : : marker можно стилизовать — правда, он реагирует не на все свойства, но как минимум вы сможете поменять цвет и размер шрифта. Раньше для его стилизации нужно было использовать : : — webkit — details — marker .

    Татьяна Фокина советует

    Скопировать ссылку на секцию «Татьяна Фокина советует» Скопировано

    �� Можно заменить иконку по умолчанию с помощью <img> . В этом случае оставьте значение атрибута alt пустым, так как это декоративное изображение.

    �� У <summary> есть встроенная роль button . На практике скринридеры определяют роль тега по-разному. NVDA считает его кнопкой, Narrator — раскрывающим треугольником (disclosure triangle), десктопный VoiceOver — саммари (summary), а TalkBack в Firefox и мобильный VoiceOver в Safari вообще не определяют роль <summary> .

    Можно использовать явную роль button для <summary> , но так лучше не делать:

    • Это не та ситуация, где стоит явно задавать ARIA-роль и нарушать одно из правил использования WAI-ARIA.
    • VoiceOver перестанет определять состояние <details> — развёрнут или свёрнут элемент.
    • Не решит проблему с неопределяемой ролью <details> для TalkBack в Firefox и мобильного VoiceOver в Safari.

    �� Если заменить на свою иконку с треугольником по умолчанию у <summary> , это может привести к проблемам с объявлением VoiceOver, NVDA и JAWS состояния, в котором сейчас находится элемент.

    �� В Firefox есть баг, из-за которого VoiceOver читает название иконки по умолчанию и считает его частью имени элемента — краткого названия, которое скринридеры объявляют вместе с ролью.

    �� VoiceOver в Safari и JAWS в Chrome, Edge или Firefox не считают <h1> – <h6> заголовками, если они вложены в <summary> .

    �� Может показаться, что <details> и <summary> подходят для выпадающего меню. Они ведут себя похоже, но это не самое доступное решение. Вот несколько причин:

    Создаем блоки раскрывающегося текста на 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 элемента.

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

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

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

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

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

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

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

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

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

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

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

    JavaScript-код

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

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

    setTimeout

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    Все вместе

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

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

    Заключение

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

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

    Справка:Сворачивание

    Сворачивание позволяет скрыть любой элемент на странице с помощью специальной кнопки «свернуть/развернуть». Это также можно использовать для крупных таблиц и текстов.

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

    Содержание

    Сворачивание таблицы

    Добавьте код « mw-collapsible » как класс, чтобы в таблице появилась ссылка «свернуть/развернуть».

    Цифра Буква
    1 A
    2 Б
    3 В

    Сворачивание текста

    Аналогично можно этот класс использовать для сворачивания текста внутри статьи.

    Этот текст можно свернуть.

    Свёрнутая по умолчанию таблица

    Чтобы таблица изначально была свёрнута, используйте двойной код: « mw-collapsed » и « mw-collapsible ». Пример:

    Заголовок всегда будет виден
    Содержимое всегда
    будет скрыто

    Скрытие спойлеров в тексте

    Скрыть текст внутри статьи можно, используя двойной код: указанный в предыдущем разделе с добавлением кода « mw-collapsible-content ».

    Этот текст предшествует скрытому тексту.

    Настройка текста «свернуть/развернуть»

    Можно добавить свой текст вместо стандартного «свернуть/развернуть». Для этого используйте код « data-expandtext » и « data-collapsetext ».

    Цифра Буква
    1 A
    2 Б

    Кнопка «свернуть/развернуть»

    Как вы заметили, ссылка «свернуть/развернуть» увеличивает ширину колонки таблицы, где она находится. Этого можно избежать, если вынести переключатель за пределы таблицы, что удобно сделать с помощью кнопки.

    Если присвоить переключателю значение » mw-customcollapsible-myTable «, то при использовании кода » mw-customtoggle-myTable » это можно осуществить следующим образом:

    Аккордеон, faq, спойлер и другие раскрывающиеся виджеты

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

    1. Людям с ограниченными возможностями проще будет пользоваться вашим сайтом! Их софт (скринридеры и подобное) прекрасно понимает html5 теги и будет правильно обрабатывать их и правильно информировать людей о содержимом.
    2. Улучшится связанность текста, и поисковики смогут более качественно индексировать сайт, так как будут лучше понимать, как связаны между собой видимый и скрытый текст.
    3. Будет доступно управление элементами с клавиатуры и других устройств.
    4. Уменьшается количество javascript кода, который нужно подгружать, что увеличивает скорость загрузки страницы, скорость обработки и корректность.
    5. Улучшаются показатели в Lighthouse, Google PageSpeed и других подобных инструментах.
    6. Работает при выключенном javascript.
    1. Старые браузеры не знают таких тегов и не будут скрывать информацию.

    С одной стороны выглядит не очень красиво, с другой стороны нейтрально и легко может вписаться во многие дизайны. Кстати, дефолтный вид тега Details очень похож на спойлер от хабра, только нужно чуть перекрасить, сделать подчеркивание и получим семантически правильный, без javascript и дивов, хабровский спойлер.

    К сожалению, у дефолтного маркера есть два недостатка:

    1. Старые браузеры его не видят.
    2. Вебкит баузеры не позволяют менять символ маркера.

    Рассмотрим первый пример Details/Summary с измененным текстовым маркером:

    Дефолтным маркерам делаем display:none и показываем альтернативный при помощи summary:before

    summary:focus — обводка при помощи box-shadow, это нужно для клавиатуры, чтоб видно было активный элемент и можно было перемещаться клавишей таб и открывать и закрывать при помощи пробела.

    Для тега summary я поставил display:inline-block — это чтоб он не растягивался на всю ширину и были кликабельными только слова, а не вся строка.

    Текстовый маркер справа + простейшая анимация текста и маркера:

    В новом примере я использую для маркера summary:after вместо summary:before, для того чтоб он отображался справа.

    Анимация маркера при помощи transform: scale(1,-1);

    Всем элементам, которые находится после summary, ставлю анимацию плавного появления при помощи animation: sweep .5s ease-in-out;

    Svg маркер + анимация поворота:

    Summary:before пришлось серьезно переделать:

    1. Поставить position: absolute; left: .3em; top: .4em; width: 1em; height: 1em;
    2. Текстовому маркеру надо обязательно поставить color: transparent; иначе он будет виден.
    3. Картинку вешаем при помощи background.

    Ну и добавляем transform: rotateZ(90deg) для красивого поворота стрелки.

    Если нам нужна svg иконка справа, то нужно поменять summary:before и вместо left поставить right.

    Для summary поставить padding-right: 1.5em;

    Давайте теперь сделаем один из наиболее распространенных примеров создания аккордиона, где будет иконка слева, фон, тени, эффекты:

    Svg маркер справа + эффект зеркального поворота стрелки:

    Теперь вы можете создавать красивые аккордионы, спойлеры и faq, без JavaScript, на чистом HTML5 и CSS.

    Прежде чем убирать outline, 100 раз подумайте, чем вы можете его заменить, чтоб человек мог видеть фокус и мог перемещаться с клавиатуры или других устройств.

    Если вам нужно, чтоб при открытии одного спойлера, закрывались остальные, то придется применить javascript, ниже привожу пример простого JS кода, который решит эту проблему.

    С уважением, создатель конструктора лэндингов для фрилансеров CMS cPortfolio

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *