web-dev-qa-db-ja.com

Webページの「オーバースクロール」を防ぐ

MacのChromeでは、以下のスクリーンショットに示すように、ページを「オーバースクロール」して(優れたWordがないため)、iPadやiPhoneのような「背後」を確認できます。

Gmailや「新しいタブ」ページなど、一部のページで無効になっていることに気付きました。

「オーバースクロール」を無効にするにはどうすればよいですか? 「オーバースクロール」を制御できる他の方法はありますか?

enter image description here

86
Randomblue

受け入れられた解決策は私にとってはうまくいきませんでした。スクロールできる状態で動作させる唯一の方法は次のとおりです。

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

body {
    height: 100%;
    overflow: auto;
}
143

これを防ぐ1つの方法は、次のCSSを使用することです。

html, body {
    width: 100%;
    height: 100%;
    overflow: hidden;
}

body > div {
    height: 100%;
    overflow: scroll;
    -webkit-overflow-scrolling: touch;
}

このように、本文はオーバーフローすることはなく、ページの上下でスクロールしても「バウンス」しません。コンテナはその中のコンテンツを完全にスクロールします。これはSafariとChromeで機能します。

編集

余分な<div>-要素がラッパーとして有用な理由:
Florian Feldhausのソリューション は、使用するコードがわずかに少なく、正常に動作します。ただし、ビューポートの幅を超えるコンテンツに関しては、ちょっとした癖があります。この場合、ウィンドウの下部にあるスクロールバーはビューポートの途中に移動し、認識/到達が困難になります。適切であれば、body { margin: 0; }を使用してこれを回避できます。このCSSを追加できない状況では、スクロールバーが常に完全に表示されるため、ラッパー要素が役立ちます。

以下のスクリーンショットを見つけます: enter image description here

38

Chrome 63 +、Firefox 59+およびOpera 50+では、CSSでこれを行うことができます。

body {
  overscroll-behavior-y: none;
}

これにより、質問のスクリーンショットに示されているiOSのラバーバンディング効果が無効になります。ただし、プルトゥリフレッシュ、グローエフェクト、およびスクロールチェーンも無効にします。

ただし、オーバースクロール時に独自の効果または機能を実装することを選択できます。たとえば、ページをぼかしてきちんとしたアニメーションを追加する場合:

<style>
  body.refreshing #inbox {
    filter: blur(1px);
    touch-action: none; /* prevent scrolling */
  }
  body.refreshing .refresher {
    transform: translate3d(0,150%,0) scale(1);
    z-index: 1;
  }
  .refresher {
    --refresh-width: 55px;
    pointer-events: none;
    width: var(--refresh-width);
    height: var(--refresh-width);
    border-radius: 50%; 
    position: absolute;
    transition: all 300ms cubic-bezier(0,0,0.2,1);
    will-change: transform, opacity;
    ...
  }
</style>

<div class="refresher">
  <div class="loading-bar"></div>
  <div class="loading-bar"></div>
  <div class="loading-bar"></div>
  <div class="loading-bar"></div>
</div>

<section id="inbox"><!-- msgs --></section>

<script>
  let _startY;
  const inbox = document.querySelector('#inbox');

  inbox.addEventListener('touchstart', e => {
    _startY = e.touches[0].pageY;
  }, {passive: true});

  inbox.addEventListener('touchmove', e => {
    const y = e.touches[0].pageY;
    // Activate custom pull-to-refresh effects when at the top of the container
    // and user is scrolling up.
    if (document.scrollingElement.scrollTop === 0 && y > _startY &&
        !document.body.classList.contains('refreshing')) {
      // refresh inbox.
    }
  }, {passive: true});
</script>

ブラウザのサポート

この記事の執筆時点では、Chrome 63 +、Firefox 59+およびOpera 50+がサポートしています。 Safariは不明ですが、Edgeはこれを公的にサポートしていました。進捗状況の追跡 ここ および MDNドキュメント での現在のブラウザー互換性

詳細情報

34
Koslun

このコードを使用して、touchmove事前定義アクションを削除できます。

document.body.addEventListener('touchmove', function(event) {
  console.log(event.source);
  //if (event.source == document.body)
    event.preventDefault();
}, false);
1
Daniel Prol
html,body {
    width: 100%;
    height: 100%;
}
body {
    position: fixed;
    overflow: hidden;
}
1
Cormorano71

この方法を試してください

body {
    height: 100vh;
    background-size: cover;
    overflow: hidden;
}
1
Moldavianheart

Webページの高さがwindow.innerHeightに等しい場合を除き、バウンス効果を無効にすることはできません。サブ要素をスクロールさせることができます。

html {
    overflow: hidden;
}
0
Yibo

position: absoluteは私のために働きます。 Chrome 50.0.2661.75 (64-bit)およびOSXでテストしました。

body {
  overflow: hidden;
}

// position is important
#element {
  position: absolute;
  top: 0;
  right: 0;
  bottom: 0;
  left: 0;
  overflow: auto;
}
0
Tony Jin