UXPUB 🇺🇦 Дизайн-спільнота

Cover image for Навигация с горизонтальным скроллом (CSS+ JavaScript)
Саша Федорова
Саша Федорова

Опубліковано

Навигация с горизонтальным скроллом (CSS+ JavaScript)

Всем привет!

Продолжая экспериментировать с JavaScript, я хотела обновить горизонтальную навигацию, которую ранее создала для GitHubMobile (до текущей адаптивной версии и нативных приложений), и для этого примера панели инструментов Bootstrap.

Цель? Создать отзывчивую горизонтальную навигацию с помощью скролла, которая автоматически прокручивает активную навигационную ссылку в окне просмотра. Адаптивность заключается в том, что навигационные ссылки прокручиваются горизонтально — достаточно легко и масштабируются во всех окнах просмотра. Скроллинг и настройка активной ссылки выполняются на JS и, благодаря работе над предстоящим редизайном Bootstrap, относительно просты.

Вот финальное демо на сайте CodePen.

Посмотрите, что под капотом. Для HTML я использую базовые элементы: <nav>, <ul> и навигационные ссылки. <nav> – это элемент, который прокручивается, а <ul> всегда содержит ссылки на одну строку.

<header>
  <h1>Demo</h1>
  <nav>
    <ul>
      <li><a href="#">Home</a></li>
      <li><a href="#">World</a></li>
      <li><a href="#">Politics</a></li>
      <li><a href="#">Business</a></li>
      <li><a href="#">Opinion</a></li>
      <li><a href="#" class="active">Tech</a></li>
      <li><a href="#">Science</a></li>
      <li><a href="#">Health</a></li>
      <li><a href="#">Sports</a></li>
      <li><a href="#">Arts</a></li>
      <li><a href="#">Books</a></li>
      <li><a href="#">Style</a></li>
      <li><a href="#">Food</a></li>
      <li><a href="#">Travel</a></li>
    </ul>
  </nav>
</header>

Войти в полноэкранный режим Выход из полноэкранного режима

Однако CSS для элементов <nav> и <ul> становится немного умнее. Я установила фиксированное значение height (равное вычисленной высоте ссылки) и overflow-y на <nav>, чтобы «обрезать» ссылки внутри. Но это не избавляет от раздражающих полос прокрутки, появляющихся при скролле и, таким образом, закрывающих ссылки. Таким образом, среди ряда дополнительных базовых стилей у элемента <ul> есть большое значение padding-bottom, позволяющее скрыть любую видимую полосу прокрутки. У такого решения есть свои проблемы юзабилити — полосы прокрутки показывают, что часть интерфейса можно скроллить, есть дополнительный контент и т. д. — но нет элегантного способа решить эту проблему во всех браузерах и на всех устройствах.

nav {
position: relative;
z-index: 2;
height: 2.5rem;
overflow-y: hidden;
scroll-behavior: smooth;
}

ul {
display: flex;
flex-wrap: nowrap;
padding-bottom: 1.5rem;
padding-left: 0;
margin-block: 0;
overflow-x: auto;
list-style: none;
text-align: center;
white-space: nowrap;
}
Войти в полноэкранный режим Выход из полноэкранного режима

На стороне JavaScript мы начинаем с запроса селектора, проверяем, существует ли он на странице, и устанавливаем ряд переменных для навигационных ссылок и активной ссылки.

let nav = document.querySelectorAll('nav')

if (nav) {
  let navLinks = document.querySelectorAll('nav a')
  let activeLink = document.querySelector('.active')

  //
}

Войти в полноэкранный режим Выход из полноэкранного режима

Наша первая строка JSотвечает за немедленную (при загрузке страницы) прокрутку активной ссылки для просмотра содержащего ее элемента. В CodePen я установила ссылку, которая должна быть за пределами экрана, в качестве элемента .active, чтобы вы могли видеть прокрутку при загрузке страницы. Во время работы над документацией Bootstrap я нашел для этого полезный JS-метод — scrollIntoView.

let nav = document.querySelectorAll('nav')

if (nav) {
  let navLinks = document.querySelectorAll('nav a')
  let activeLink = document.querySelector('.active')
  activeLink.scrollIntoView({ behavior: "smooth", inline: "center" })

  //
}

Войти в полноэкранный режим Выход из полноэкранного режима

behavior сообщает браузеру, как анимировать скроллинг, в то время как inline указывает браузеру выровнять скролл по горизонтали. (Для вертикального выравнивания, если необходимо, есть параметр block) Отсюда нам нужно добавить eventlistener к каждой навигационной ссылке, чтобы установить класс .active и прокрутить ссылку, по которой щелкнули в окне просмотра. Этот последний фрагмент кода можно было бы очистить с помощью функции scrollIntoView для дедупликации этой строки, но на данный момент это не кажется целесообразным и добавляет немного больше JS.

let nav = document.querySelectorAll('nav')

if (nav) {
  let navLinks = document.querySelectorAll('nav a')
  let activeLink = document.querySelector('.active')
  activeLink.scrollIntoView({ behavior: "smooth", inline: "center" })

  navLinks.forEach( function(link) {
    link.addEventListener("click", (event) => {
      navLinks.forEach( function(link) {
        link.classList.remove('active')
      })
      link.classList.add('active')
      link.scrollIntoView({ behavior: "smooth", inline: "center" })
    })
  })
}

Войти в полноэкранный режим Выход из полноэкранного режима

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

Топ коментарі (0)