x
 
Саша Васильева
14 июня 2018
Советы почтой каждую неделю
Пожалуйста, получите наше письмо, чтобы подтвердить свой адрес:
Вы подписаны на «Советы за неделю»:

Как сверстать прокручивающееся меню для мобильных, как у вас на новом сайте?


С помощью стандартной прокрутки и пары улучшений.

Для начала сверстаем горизонтальное меню:

<!-- index.html -->
<menu class="menu">
  <li class="menu-item">
    <a href="#">Новости</a>
  </li>
  <li class="menu-item">
    <a href="#">Проекты</a>
  </li>
  <li class="menu-item">
    <a href="#">Книги</a>
  </li>
  <!-- ... -->
</menu>
/* style.css */
.menu {
  display: flex;
  font: 24px/32px Bureausans, Arial, sans-serif;
}

.menu-item {
  margin-right: 15px;
}

.menu-item:last-child {
  margin-right: 0;
}

Теперь поместим меню в блок с ограниченной шириной и горизонтальной прокруткой:

<!-- index.html -->
<div class="menuLimiter">
  <menu class="menu">
    <li class="menu-item">
      <a href="#">Новости</a>
    </li>
    <li class="menu-item">
      <a href="#">Проекты</a>
    </li>
    <li class="menu-item">
      <a href="#">Книги</a>
    </li>
    <!-- ... -->
  </menu>
</div>
/* style.css */
.menuLimiter {
  width: 350px;
  padding: 0 10px;

  /* Зададим возможность горизонтальной прокрутки */
  overflow-x: scroll;

  /* Для Сафари дополнительно зададим инерцию при прокрутке.
  С инерцией меню будет «оттягиваться» при попытке прокрутить
  его за его пределы. */
  -webkit-overflow-scrolling: touch;
}

/* ... */

Для прокрутки потащите меню мышью

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

<!-- index.html -->
<div class="menuWrapper">
  <div class="menuLimiter">
    <menu class="menu">
      <li class="menu-item">
        <a href="#">Новости</a>
      </li>
      <li class="menu-item">
        <a href="#">Проекты</a>
      </li>
      <li class="menu-item">
        <a href="#">Книги</a>
      </li>
      <!-- ... -->
    </menu>
  </div>
</div>
/* style.css */

.menuLimiter {
  /* ... */

  /* Добавим дополнительный нижнее поле
  элементу, в котором прокручивается меню */
  padding-bottom: 20px;

  /* С помощью отрицательного отступа
  компенсируем «нарощенное» поле  */
  margin-bottom: -20px;
}

.menuWrapper {
  /* Спрячем всё, что выходит за границы родителя */
  overflow: hidden;
}

Добавим немного косметики в виде «забеления» по краям с помощью маски:

/* style.css */

.menuLimiter {
  /* ... */
  mask-image: linear-gradient(
      90deg,
      transparent 0, rgba(0, 0, 0, .25) 9px,
      #000 18px,
      #000 calc(100% - 18px),
      rgba(0, 0, 0, .25) calc(100% - 9px),
      transparent
    );
}

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

Чтобы поправить это, можно написать небольшой скрипт, который будет анализировать ширину элементов и расставлять их так, чтобы один из элементов всегда обрезался. Но так как наше меню довольно статичное, просто опишем подходящие отступы для разной ширины экрана:

/* style.css */

@media only screen and (max-width: 400px) {
  .menu-item { margin-right: 25px; }
}

@media only screen and (max-width: 426px) {
  .menu-item { margin-right: 13px; }
}

@media only screen and (max-width: 450px) {
  .menu-item { margin-right: 20px; }
}

@media only screen and (max-width: 470px) {
  .menu-item { margin-right: 25px; }
}

@media only screen and (max-width: 510px) {
  .menu-item { margin-right: 15px; }
}
P. S. Это был совет о веб-разработке. Хотите знать всё о коде, тестах, фронтенд-разработке, цеэсэсе, яваскрипте, рельсах и джейде? Присылайте вопросы.
Вёрстка и прототипирование — дисциплина Школы дизайнеров. Набор закрыт. Опоздавшим: оставьте нам почту, и мы напишем вам, пока есть свободные места.
 

Поделиться
Отправить

Комментарии

Евгений Закурдаев
15 июня 2018

Вместо:
.menu-item { margin-right: 15px; }
.menu-item:last-child { margin-right: 0; }

Можно написать:
.menu-item:not(:last-child) { margin-right: 15px; }

Строчек вдвое меньше, нет переопределения.

Андрей Пулин
15 июня 2018

Руст, почему у вас menu → li ? Разве это допустимо, чтобы лист-айтем был где-то кроме листа?


18 июня 2018

Андрей, menu ведёт себя как неупорядоченный список (ul), когда внутри него содержится хотя бы один элемент li:
https://html.spec.whatwg.org/…/grouping-content.html#the-menu-element
https://developer.mozilla.org/en-US/docs/Web/HTML/Element/menu

В остальных случая это обычный контейнер.

Андрей Ситник
18 июня 2018

У PostCSS есть плагин для автоматического включения -webkit-overflow-scrolling: touch

https://github.com/yunusga/postcss-momentum-scrolling


Цель рубрики — обсуждение вопросов дизайна всех видов, текста в дизайне и взаимоотношений дизайнеров с клиентами.

Мы публикуем комментарии, которые добавляют к уже сказанному новые мысли и хорошие примеры. Мы ожидаем, что такие комментарии составят около 20% от общего числа.

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

Вот такой веб 2.0.

Как бороться с багами? Часть восьмая: порефлексировать 6 Как бороться с багами? Часть седьмая: исправить




Недавно всплыло

Пожалуйста, подскажите, как можно написать лучше? Как избавиться от сухости? 1 Как объяснить человеку, не обидев его, что это мой проект, и я не хочу выходить за рамки концепции? 2 2 2