【Перевод】О решении спецэффекта резиновой ленты

внешний интерфейс Chrome CSS Safari

предисловие

Эта статья переведена сScroll Bouncing On Your Websites, я многому научился после прочтения.В сочетании с собственным пониманием, я перевел статью на китайский язык, с одной стороны, я углубил свое понимание, а с другой стороны, я поделился хорошей статьей.

Управляемое чтение

В этой статье представлены специальные эффекты и реализация пружинной прокрутки (то есть подпрыгивания прокрутки) в разных браузерах, а также обзор нескольких распространенных решений в Интернете, кстати, в ней представлено недавно реализованное свойство CSS overscroll-behavior. Я надеюсь, что после прочтения это будет полезно для создания и оформления страниц с фиксированными элементами.

Scroll bouncing

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

  1. При прокрутке вверх или вниз страницы или HTML-элемента вы ненадолго увидите пустое пространство, прежде чем страница или элемент вернутся вверх/вниз (т. е. до того, как вы отпустите палец или мышь).
  2. Тот же эффект можно получить и при прокрутке CSS между элементами (CSS scroll-snapping) видеть. В этой статье основное внимание уделяется первому случаю, то есть сценарию, когда порт прокрутки достигает своей границы прокрутки.
    Четкое понимание отскока прокрутки может помочь нам решить, как создавать веб-страницы и как прокручивать страницы.

задний план

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

Обзор сцены

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

Хотя для нижнего колонтитула установлено значение Fixed=>bottom, этот эффект резиновой ленты действительно немного застигнут врасплох.
Давайте посмотрим, что означает position:fixed:
Согласно Спецификации CSS 2.1, когда «коробка» (в данном случае темно-синий нижний колонтитул) зафиксирована, она «фиксируется по отношению к области просмотра и не перемещается при прокрутке».
Согласно спецификации CSS 2.1: когда поле (здесь, очевидно, нижний колонтитул) установлено фиксированным, оно будет позиционироваться в соответствии с областью просмотра и не будет перемещаться во время прокрутки.

Очевидно, описанный выше эффект является неожиданным.
Чтобы сделать статью более полной, я попробовал эффекты в мобильном Edge, мобильном Safari и настольном Safari, правда, производительность в firefox и chrome отличается. Очень сложно разработать свайпы с одинаковым эффектом на разных платформах.

решение

Для нас первая идея, безусловно, является простым и быстрым способом, поэтому в этом случае первый выбор, конечно, css, чтобы разобраться с этим отдельно. Поэтому выберите следующие способы попробовать. Тестовые браузеры включают Chrome, Firefox, Safari на Win 10 и Mac, а также Edge и Mobile Safari, Все версии браузеров являются последними версиями в 2018 году. Структура страницы следующая:

<html>
  <body>
    <div class="body-container">
      <div class="color-picker-main-container"> 
      </div>
    </div>
    <footer>
    </footer>
</body>    

Используйте только css и html для решения

1. Абсолютное позиционирование и относительное позиционирование

Используйте absolute для позиционирования нижнего колонтитула, а затем расположите html относительно высоты 100%, чтобы нижний колонтитул всегда был зафиксирован внизу, а высота содержимого была равна 100% минус высота нижнего колонтитула. Конечно, вы также можете установить padding-bottom вместо calc и установить body-containe на 100%, чтобы предотвратить повторение нижнего колонтитула. Язык относительно бледный, а код закончен:

html {
  width: 100%;
  height: 100%;
  overflow: hidden;
  position: relative;
}

body {
  width: 100%;
  margin: 0;
  font-family: sans-serif;
  height: 100%;
  overflow: hidden;
}

.body-container {
  height: calc(100% - 100px);
  overflow: auto;
}

.color-picker-main-container {
  width: 100%;
  font-size: 22px;
  padding-bottom: 10px;
}

footer {
  position: absolute;
  bottom: 0;
  height: 100px;
  width: 100%;
}

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

Кроме того, возникла еще одна нежелательная ситуация: при попытке скользить было обнаружено, что характеристики скольжения в это время были немного плохими.
Поскольку мы устанавливаем высоту скользящего контейнера на 100% от себя, что препятствует прокрутке на основе импульса на ios,
Прокрутка на основе импульса здесь, у меня нет хорошего языка для перевода, для краткости это называется затухающим скольжением.
Проще говоря, это добавленная в мобильное устройство функция для улучшения производительности пролистывания страниц.Очевидным проявлением является то, что при прикосновении пальца к поверхности устройства начинает скользить сама страница, а когда палец перестает скользить, страница будет продолжать скользить. Проведите некоторое время.Для получения дополнительной информации перейдите на. Мне определенно нужен этот эффект, поэтому не устанавливайте высоту элемента ползунка на 100%.

Прежде чем перейти к другим попыткам, давайте замедлимся и подумаем о текущем состоянии. Исходное фиксированное позиционирование имеет проблему с резиновой лентой.Если вышеприведенное преобразовать в абсолютное + относительное, демпфирующее скольжение отсутствует. Если вы хотите уменьшить скольжение, высота раздела содержимого не может быть установлена ​​на 100%. Так можно ли явно не устанавливать высоту на 100%?

html {
  width: 100%;
  position: fixed;
  overflow: hidden;
}

body {
  width: 100%;
  margin: 0;
  font-family: sans-serif;
  position: fixed;
  overflow: hidden;
}

.body-container {
  width: 100vw;
  height: calc(100vh - 100px);
  overflow-y: auto;
  // Use momentum-based scrolling on WebKit-based touch devices
  -webkit-overflow-scrolling: touch;
}

.color-picker-main-container {
  width: 100%;
  font-size: 22px;
  padding-bottom: 10px;
}

footer {
  position: fixed;
  bottom: 0;
  height: 100px;
  width: 100%;
}

Здесь задан html, а тело зафиксировано и overflow: hidden. нижний колонтитул также исправлен.
В области содержимого body-контейнера, которую необходимо прокручивать, установите ее высоту на 100vh-footer,
В то же время добавьте -webkit-overflow-scrolling: touch;, чтобы включить амортизационную поддержку скольжения.
Какой будет эффект. Chrome и Firefox на Mac аналогичны предыдущему методу. Преимущество этого метода в том, что высота 100 % больше не требуется.
Таким образом, прокрутка на основе импульса работает нормально, но в Safari отсутствует нижний колонтитул. . .
В Safari на iOS нижний колонтитул короче и имеет дополнительное пространство внизу. Так же при прокрутке вниз пропадает возможность прокрутить страницу.

В приведенном выше коде -webkit-overflow-scrolling: touch добавляет прокрутку на основе импульса к указанному элементу. Однако этот атрибут не является стандартным в MDN, и необходимо учитывать совместимость, поэтому от него можно только отказаться.

Другое решение выглядит следующим образом:

html {
  position: fixed;
  height: 100%;
  overflow: hidden;
}

body {
  font-family: sans-serif;
  margin: 0;
  width: 100vw; 
  height: 100vh;
  overflow-y: auto;
  overflow-x: hidden;
  -webkit-overflow-scrolling: touch;
}

.color-picker-main-container {
  width: 100%;
  font-size: 22px;
  padding-bottom: 110px;
}

footer {
  position: fixed;
}

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

использовать JavaScript

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

Один из способов избежать скользящих пружин — заблокировать события touchmove или touchstart окна или документа. Идея состоит в том, чтобы предотвратить касание внешнего окна и разрешить касание только части содержимого. код показывает, как показано ниже:

// Prevents window from moving on touch on older browsers.
window.addEventListener('touchmove', function (event) {
  event.preventDefault()
}, false)

// Allows content to move on touch.
document.querySelector('.body-container').addEventListener('touchmove', function (event) {
  event.stopPropagation()
}, false)

Я перепробовал множество способов, чтобы свайп вел себя хорошо, блокировка touchmove виджета ничем не отличается от блокировки документа, также пробовал использовать touchstart и touchmove для управления свайпом,
Но между этими двумя методами нет никакой разницы. Позже было обнаружено, что из соображений производительности не следует использовать event.preventDefault() таким образом, а в качестве пассивной опции следует установить значение false.

// Prevents window from moving on touch on newer browsers.
window.addEventListener('touchmove', function (event) {
  event.preventDefault()
}, {passive: false})

инструмент

Кроме того, вы можете использовать iNoBounce в помощь себе, цель этой библиотеки — решить эффект пружины, когда веб-приложение на ios скользит. Когда мне нужно упомянуть об этом, добавьте -webkit-overflow-scrolling при использовании этой библиотеки для решения вышеуказанных проблем.
Кроме того, краткий метод, который я упомянул в конце, имеет тот же эффект, вы можете сравнить их.

Overscroll Behavior

Перепробовав так много решений, я обнаружил свойство overscroll-behavior в CSS, которое было реализовано в Chrome 63 и Firefox 59 в декабре 2017 и марте 2018 года соответственно.
Согласно определению mdn: Позволяет управлять поведением браузера при переполнении свайпом — поведением, возникающим при достижении края области прокрутки. Это последний вариант.
Все, что вам нужно сделать, это установить overscroll-behavior:none в теле и установить нижний колонтитул на фиксированный.По сравнению с отсутствием фотера, допустимо применять прокрутку на основе импульса ко всей странице. Что более объективно, так это то, что Edge находится в стадии разработки и можно ожидать будущего.

заключительные замечания

Справочная статья

  1. Momentum Scrolling on iOS Overflow Elements
  2. Scroll Bouncing On Your Websites
  3. MOMENTUM SCROLLING USING JQUERY

Еще раз спасибо оригинальному автору, Уильяму Лиму, за предоставление более богатого решения для эффектов скользящей резиновой ленты. У меня мало знаний и знаний.Пожалуйста, поправьте меня, если некоторые переводы не на месте.Детали Асинхронный оригинал