Фиксация контента после прокрутки

Фиксация контента после прокрутки

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

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

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

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

Поле поиска при прокрутке страницы

Поле поиска зафиксировано в шапке страницы

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

Первое состояние

(Я собираюсь использовать здесь 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; /* Autoprefixer здесь не срабатывает */
  }
}

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

Второе состояние

При условии, что мы добавили класс .fix-search к родительскому элементу.

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

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

Переключение состояний

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

var wrap = $("#wrap");

wrap.on("scroll", function(e) {
    
  if (this.scrollTop > 147) {
    wrap.addClass("fix-search");
  } else {
    wrap.removeClass("fix-search");
  }
  
});

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

Настройка ограничений

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

CSS

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

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

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

Это только один пример (не подходящий, в частности, для повсеместного использования)

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

Возможно, использование какой-нибудь из версий плагина waypoints (или самой идеи) позволит создать более устойчивое решение.

Автор: Chris Coyier

Источник: http://css-tricks.com/

Редакция: Команда webformyself.

Практика HTML5 и CSS3 с нуля до результата!

Получите бесплатный пошаговый видеокурс по основам адаптивной верстки с полного нуля на HTML5 и CSS3

Получить

Метки: ,

Комментарии Вконтакте:

Комментарии Facebook:

Комментарии (1)

  1. BECEJLbE / Данил

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

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

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

Можно использовать следующие HTML-теги и атрибуты: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>

Я не робот.

Spam Protection by WP-SpamFree