スクロールする度に、固定されているボタンがふわっと表示されたり、最初は出ていて、スクロールすると消えるヘッダーがある位置に来たら上部に固定するなどはJavaScript scroolYというプロパティを使います。たとえば「上へ戻る」ボタンがスクロール後に表示されたり、スクロール方向によってヘッダーが隠れたりするような動きは、window.scrollY を使ってページのスクロール位置を取得することで実現できます。
1.「上へ戻る」ボタンを表示/非表示
画面右下に固定した「上へ戻る」ためのボタン(アイコン)が、最初から表示するのではなく、画面を 600px 以上スクロールすると、右下に固定された「上へ戻る」ボタンがふわっと表示され、クリックすることでページの先頭へ戻ることができます。
HTML
<div id="backToTop">
<a href="#top">
▲
</a>
</div>
CSS
#backToTop a {
display: block;
position: fixed;
right: 10px;
bottom: 100px;
background-color: var(--main-color);
padding: .75rem 1rem;
color: var(--white);
text-decoration: none;
border-radius: 5px;
z-index: 200;
opacity: 0;
visibility: hidden;
transition: opacity 0.4s ease, visibility 0.4s ease;
}
#backToTop.show a {
opacity: 1;
visibility: visible;
}
JavaScript
const backToTop = document.getElementById('backToTop');
window.addEventListener('scroll', () => {
const scrollY = window.scrollY; // 現在のスクロール量を取得
if (scrollY > 600) {
backToTop.classList.add('show');
} else {
backToTop.classList.remove('show');
}
});
window.scrollYとは?
window.scrollY は、ページが どれだけ縦にスクロールされたか(px単位) を取得するプロパティです。
たとえば、scrollY > 600 と書けば、「600px以上スクロールされたかどうか」を判定できます。
毎回 window.scrollY と書くのは少し長いので、下記のように const scrollY = window.scrollY; のように変数に入れておくと、コードが読みやすくなります。
2.スクロール方向でヘッダーを隠す/戻す
ページの上部に表示されているヘッダーは、最初は表示されていますが、ユーザーが下にスクロールすると非表示になり、再び上にスクロールし始めると表示されるようになります。
このような動きは window.scrollY を使い、「今のスクロール位置」と「ひとつ前のスクロール位置」を比較することでスクロールの方向を判定して実現します。
HTML
<header class="header">
<h1>サイトのタイトル</h1>
<nav class="header-list">
<ul>
<li><a href="#">About</a></li>
<li><a href="#">Service</a></li>
<li><a href="#">Contuct</a></li>
</ul>
</nav>
</header>
<main style="padding: 2rem;">
<p style="line-height: 2;">下にスクロールします。</p>
<p style="line-height: 2;">下にスクロールします。</p>
<p style="line-height: 2;">下にスクロールします。</p>
<p style="line-height: 2;">下にスクロールします。</p>
<p style="line-height: 2;">下にスクロールします。</p>
<p style="line-height: 2;">下にスクロールします。</p>
<p style="line-height: 2;">下にスクロールします。</p>
<p style="line-height: 2;">下にスクロールします。</p>
<p style="line-height: 2;">下にスクロールします。</p>
<p style="line-height: 2;">下にスクロールします。</p>
<p style="line-height: 2;">下にスクロールします。</p>
<div style="height: 800px;"></div>
</main>
CSS
body {
margin: 0;
overflow-x: hidden;
}
.header {
position: fixed;
top: 0;
width: 100%;
background: #9e9e9ed6;
padding: 1rem 2rem;
box-sizing: border-box;
box-shadow: 0 2px 5px rgba(0, 0, 0, 0.1);
transition: transform 0.3s ease;
z-index: 500;
display: flex;
align-items: center;
justify-content: space-between;
}
/* 非表示時:上に押し上げて隠す */
.header.hide {
transform: translateY(-100%);
transition: transform 0.3s ease;
}
.header-list ul {
list-style: none;
display: flex;
gap: 30px
}
.header-list ul a {
color: #000;
text-decoration: none;
}
JavaScript
const header = document.querySelector('.header');
const main = document.querySelector('main');
let lastScrollY = window.scrollY;
// ヘッダーの高さを main に反映(初期設定)
window.addEventListener('DOMContentLoaded', () => {
const headerHeight = header.offsetHeight;
main.style.paddingTop = `${headerHeight}px`;
});
window.addEventListener('scroll', () => {
const currentScrollY = window.scrollY;
if (currentScrollY > lastScrollY && currentScrollY > 300) {
header.classList.add('hide');
} else {
header.classList.remove('hide');
}
lastScrollY = currentScrollY;
});
.header 要素と <main> 要素を取得。
lastScrollY は「ひとつ前のスクロール位置」を記録しておくための変数です(初期値は現在のスクロール位置)。
main の padding-top をヘッダーの高さにする
window.addEventListener('DOMContentLoaded', () => {
const headerHeight = header.offsetHeight;
main.style.paddingTop = `${headerHeight}px`;
});
- ページのHTMLが読み込まれたら(画像などの読み込み前でもOK)実行されます。
header.offsetHeightは、ヘッダーの高さ(ピクセル)を取得。main.style.paddingTop = ...によって、<main>にヘッダーの高さ分の余白を上に追加し、内容が隠れないように調整します。
スクロールイベントでヘッダーを出し入れ
window.addEventListener('scroll', () => {
const currentScrollY = window.scrollY;
- スクロールのたびに現在のスクロール位置(縦方向)を取得
下にスクロールしたか?を判定
if (currentScrollY > lastScrollY && currentScrollY > 300) {
header.classList.add('hide');
} else {
header.classList.remove('hide');
}
currentScrollY > lastScrollY→ 前回より下にスクロールした場合currentScrollY > 300→ ページ上部(300px未満)ではヘッダーを常に表示したいので、その範囲は対象外- 両方満たすと、
.hideクラスを付けてヘッダーを非表示にします。 - 逆に、上にスクロールした場合や、300pxより上の位置なら、
.hideを外して再表示します。
スクロール位置を更新
lastScrollY = currentScrollY; });
- 最後に、今回のスクロール位置を記録して、次回の判定に使います。
3.スクロールで要素をフェードイン/下から上 左から右 右から左
画面を下にスクロールしていくと、各セクションや画像がふわっと表示される演出はgetBoundingClientRect() を使って、要素が画面内に入ってきたタイミングを検出します。
HTML
<section class="fadein">下から</section>
<hr>
<section class="fadein-left">左から</section>
<section class="fadein-left">左から</section>
<hr>
<section class="fadein-right">右から</section>
<section class="fadein-right">右から</section>
<hr>
<section class="fadein-left">左から</section>
<section class="fadein-right">右から</section>
CSS
.fadein,
.fadein-left,
.fadein-right {
opacity: 0;
transition: all 1s ease;
}
/* 下から上 */
.fadein {
transform: translateY(100px);
}
.fadein.show {
opacity: 1;
transform: translateY(0);
}
/* 左から右 */
.fadein-left {
transform: translateX(-200px);
}
.fadein-left.show {
opacity: 1;
transform: translateX(0);
}
/* 右から左 */
.fadein-right {
transform: translateX(200px);
}
.fadein-right.show {
opacity: 1;
transform: translateX(0);
}
section {
border: 1px solid #999;
max-width: 500px;
height: 200px;
background-color: #eee;
display: flex;
justify-content: center;
align-items: center;
color: #000;
margin: 30px auto;
}
JavaScript
.fadein,.fadein-left,.fadein-rightというクラスがついた要素をすべて対象にして、- 画面内に入ってきたタイミングで
.showクラスを追加 - その結果、CSSで指定されたアニメーション(フェードイン・スライドイン)が実行される
const items = document.querySelectorAll('.fadein, .fadein-left, .fadein-right');
const checkFade = () => {
for (const item of items) {
const rect = item.getBoundingClientRect();
if (rect.top < window.innerHeight * 0.8) {
item.classList.add('show');
}
}
};
window.addEventListener('scroll', checkFade);
window.addEventListener('DOMContentLoaded', checkFade);
const items = document.querySelectorAll('.fadein, .fadein-left, .fadein-right');
.fadein系の3種類すべてをまとめて取得itemsはNodeList(配列のようなリスト)になります- これがループ処理の対象になります
const checkFade = () => {
- アロー関数の定義です
checkFadeはスクロールごとに実行される関数で、「表示チェック」を行います
for (const item of items) {
for...of文を使って、リスト内の各要素に順番にアクセスします- 1つずつ
itemという変数に取り出して処理します
const rect = item.getBoundingClientRect();
getBoundingClientRect()は、要素の「画面上での位置とサイズ」を取得するメソッドrect.top:その要素の上端が、画面の上から何pxの位置にあるかを表します
if (rect.top < window.innerHeight * 0.8) {
- 要素の上端が、ウィンドウの高さ × 0.8 より上に来たら(つまり画面の8割より上に来たら)…
- 表示開始の条件を満たしたと判断します
item.classList.add('show');
- 条件を満たしたら
.showクラスを追加 - CSSで
.fadein.showなどにアニメーション指定されているので、ここで動きが実行される
window.addEventListener('scroll', checkFade);
- スクロールするたびに
checkFade関数が実行されます - 表示される位置に来た要素をチェックします
window.addEventListener('DOMContentLoaded', checkFade);
- ページが読み込まれた時点(HTML構造ができた時)でも、
checkFadeを実行 - 初期状態からすでに画面内にある要素にも
.showをつけるためです
