Контент, прилипающий к верху области просмотра после прокрутки

Читатель прислал мне в GIF-изображение, которое демонстрирует классный эффект, который он увидел в Google со своего мобильного телефона. (По-видимому, домашняя страница, которую вы видите, когда запускаете Google Chrome на Android?) Посередине страницы расположено окно поиска, которое при прокрутке страницы вниз фиксируется в верхней части экрана.

Это крутой эффект, особенно если он используется для улучшения пользовательского интерфейса, а не для добавления навязчивой рекламы. Ниже приводится GIF-изображение, из которого понятна сама идея. Немного грубо, но идея ясна:

Контент, прилипающий к верху области просмотра после прокрутки

Два состояния

Как и большинство хороших приемов, этот не так уж и сложен. Все что мы делаем, это продумываем о (и реализуем) два возможных состояния:

  • Панель поиска, с возможностью прокрутки;
  • Панель поиска в фиксированном положении заголовка.

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

Состояние один:

Два состояния

(Я собираюсь использовать SCSS, потому что с помощью вложенных элементов удобно управлять состояниями):

SCSS
.top-header {
  position: fixed;
  top: 0;
  left: 0;
  width: 320px;
  height: 60px;
}

.search { /* Контейнер, который используется только если мы хотим сделать что-то большее, чем просто ввести запрос в панель поиска */
  position: absolute;
  top: 155px;
  left: 20px;
  right: 20px;
  input {
    width: 265px;
    transition: width 0.2s;
    -webkit-appearance: none; /* Автоматическое добавление префиксов здесь не работает */
  }
}

.top {
  height: 250px; /* Пространство для поискового запроса */
  padding-top: 40px;
  position: relative;
}

Состояние два:

Состояние два

Предполагает, что мы ввели для родительского элемента класс «fix-search«.

SCSS

.top-header {
  ...
  .fix-search & {
    background: #eee;
  }
}

.search { /* Контейнер, который используется только если мы хотим сделать что-то большее, чем просто ввести запрос в панель поиска */
  ...
  .fix-search & {
    position: fixed;
    top: 10px;
    input {
      width: 250px;
    }
  }
}

Переключение между состояниями

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

Стиль JQuery:

JQuery

var wrap = $("#wrap");

wrap.on("scroll", function(e) {

  if (this.scrollTop > 147) {
    wrap.addClass("fix-search");
  } else {
    wrap.removeClass("fix-search");
  }

});

Это все, что нужно для переключения между двумя состояниями, которые мы установили. Если страница прокручивается вниз на 147 пикселей или более, то будет применяться этот класс.

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

Демо

Debouncing

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

CSS

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

Возможно, когда-нибудь мы сможем создавать медиа-запросы прокрутки?

Поддержка для фиксированного позиционирования

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

Это всего лишь один пример (который, возможно, вам не удастся применить на практике).

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

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

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

Перевод статьи «Scroll-Then-Fix Content» был подготовлен дружной командой проекта Сайтостроение от А до Я.