Современные способы переключения контента

На Главную

Раскрывающиеся элементы <details> и <summary> </summary>

Сценарий использования: доступное "резюмирование" контента с возможностью переключения деталей содержимого независимо друг от друга или в виде "аккордеона".

Разметка раскрывающихся элементов

                      
<details>
  <summary>Content summary (всегда видно)
  Content (видимость переключается при нажатии на summary)
</details>
                      
                    
Content summary (всегда видно) Content (видимость переключается при нажатии на summary)

Стилизация раскрывающихся элементов

Будем честны, нам всем хочется избавиться от этого раздражающего маркера. Сделать это можно, установив свойство display для <summary> в любое значение, кроме list-item

                      
summary {
  display: block; /* Или любое другое значение, кроме list-item*/
}
                      
                    
Content summary (всегда видно) Content (видимость переключается при нажатии на summary)

Другим вариантом может быть изменение внешнего вида маркера. В приведенном ниже примере используется ::after

                      
.collapse__style-marker {
  position: relative;
  cursor: pointer;
}
.collapse__style-marker summary {
  display: block;
}
.collapse__style-marker summary::after {
  content: '';
  width: 15px;
  height: 15px;
  display: block;
  position: absolute;
  left: 250px;
  top: 0;
  background: url(down.svg) center / cover no-repeat;
  transition: all 0.3s ease 0s;
}
.collapse__style-marker[open] summary::after {
  content: '';
  width: 15px;
  height: 15px;
  display: block;
  position: absolute;
  left: 250px;
  top: 0;
  background: url(up.svg) center / cover no-repeat;
  transition: all 0.3s ease 0s;
}
                      
                    
Content summary (всегда видно) Content (видимость переключается при нажатии на summary)

Для создания "аккордеона" необходимо присвоить нескольким раскрывающимся элементам атрибут name с одинаковым значение

Prequels
  • Episode I: The Phantom Menace
  • Episode II: Attack of the Clones
  • Episode III: Revenge of the Sith
Originals
  • Episode IV: A New Hope
  • Episode V: The Empire Strikes Back
  • Episode VI: Return of the Jedi
Sequels
  • Episode VII: The Force Awakens
  • Episode VIII: The Last Jedi
  • Episode IX: The Rise of Skywalker
Other name
  • other list 1
  • other list 2
  • other list 3

С помощью FLEX контейнера их можно превратить в горизонтальные вкладки

Prequels
  • Episode I: The Phantom Menace
  • Episode II: Attack of the Clones
  • Episode III: Revenge of the Sith
Originals
  • Episode IV: A New Hope
  • Episode V: The Empire Strikes Back
  • Episode VI: Return of the Jedi
Sequels
  • Episode VII: The Force Awakens
  • Episode VIII: The Last Jedi
  • Episode IX: The Rise of Skywalker

Диалоговые окна (<dialog>)

Теперь, когда у нас есть Popover API для создания немодальных окон (non-modal overlays), диалоговые окна следует считать модальными, хотя метод show() по-прежнему позволяет реализовывать немодальные диалоговые окна. Преимуществом атрибута popover по сравнению с элементом <dialog> является возможность создания немодальных оверлеев без использования JS. Таким образом, немодальные диалоговые окна теряют свою актуальность, так как требуют выполнения кода на JS.

Для ясности: модальное окно — это оверлей, который делает основное содержание страницы неактивным (инертным), тогда как немодальные оверлеи позволяют взаимодействовать с основной страницей.

                    
//HTML

<button data-dialog="dialogA">Open dialogA</button>
<dialog id="dialogA" class="dialog__modal">
  <button class="closeDialog">Close dialogA</button>
</dialog>
                    
                  
                    
//CSS

.dialog__modal {
  position: fixed;
  left: 50%;
  top: 50%;
  transform: translate(-50%, -50%);
}
//Блокировка прокрутки страницы при открытом диалоговом окне
body:has(dialog:modal) {
  overflow: hidden;
}
//Стилизация фона диалогового окна
::backdrop {
  background: hsl(0 0 0 / 90%);
  /* Интересное свойство, предназначенное только для фонов */
  backdrop-filter: blur(3px); 
}
                    
                  
                    
//JAVASCRIPT

// Перебираем все элементы с атрибутом data-dialog
document.querySelectorAll('[data-dialog]')
  .forEach((button) => {
    // Обрабатываем взаимодействие (клик)
    button.addEventListener('click', () => {
      // Выбираем соответствующее диалоговое окно
      const dialog = document.querySelector(`#${button.dataset.dialog}`);
    // Открываем его
    dialog.showModal();
    // Закрываем
    dialog.querySelector(
      '.closeDialog').addEventListener('click', () => dialog.close());
  });
});
                    
                  
Popover API (<element popover>)

По сути, это всплывающие окна. Могут использоваться в качестве таких элементов, как подсказки (tooltips) (или переключаемые подсказки (toggletips) — важно понимать разницу между ними), уведомления, переключаемая навигация и другие немодальные оверлеи, которые позволяют сохранять доступ к основной странице. Хотя эти варианты и отличаются от сценариев использования диалоговых окон, поповеры обладают множеством достоинств. Функционально они аналогичны диалоговым окнам, но не являются модальными и не требуют использования JS.

Разметка поповеров

Для начала поповер должен иметь идентификатор, а также атрибут popover с одним из значений: manual (это означает, что клик вне поповера не закрывает его), auto (клик вне поповера закрывает его) или без значения (что эквивалентно значению auto). Для соблюдения семантики поповер можно оформить в виде элемента <dialog>.

Следующим шагом добавляем атрибут popovertarget к элементу <button> или <input type="button">, который будет управлять видимостью поповера. Значение этого атрибута должно совпадать со значением атрибута popover:

                    
<button popovertarget="tooltipA">Show tooltipA<button>
<dialog id="tooltipA" popover>
  <button popovertarget="tooltipA">Hide tooltipA<button>
</dialog>