上へ戻るボタンを実装する
コピペでサッと使える上へ戻るボタンです。(2023年2月4日追記)
HTML
<body id="top">
〜〜〜
<a href="#top" id="toTop" class="c-toTop" aria-hidden="true">
<span class="screen-reader-text">上へ戻る</span>
</a>
HTML はこちらだけです。
最初は非表示、スクロールしたら出現するようにしたいので、aria-hidden="true"
を設定しています。
#top は設定しなくても仕様上ページトップへのリンクとなっているので、このまま使います。
上記仕様について、Twitterでご指摘いただきました。[2023年2月4日追記 ここから]
Chrome、Safari、Firefoxしか検証していませんが、適切にフォーカスの移動が行われたのは Chrome のみでしたので、body に id を明示するように変更しました。
えびちゃんさん、ご指摘ありがとうございました。[2023年2月4日追記 ここまで]
SCSS
html {
scroll-behavior: smooth;
}
.c-toTop {
position: fixed;
right: 10px;
bottom: 10px;
display: flex;
justify-content: center;
align-items: center;
width: 50px;
height: 50px;
border: 1px solid #333333;
border-radius: 50%;
background-color: #fff;
opacity: 0;
visibility: hidden;
pointer-events: none;
transition: .3s background-color ease-out;
&[aria-hidden="false"] {
opacity: 1;
visibility: visible;
pointer-events: auto;
animation: .5s toTopFadeIn both;
}
&::before {
content: '';
display: inline-block;
width: 15px;
height: 8px;
background-color: #333333;
clip-path: polygon(0 70%, 50% 0, 100% 70%, 100% 100%, 50% 30%, 0 100%);
transition: .3s transform ease-out;
}
&:hover {
background-color: #f0f0f0;
&::before {
transform: translateY(-3px);
}
}
}
@keyframes toTopFadeIn {
0% {
visibility: hidden;
opacity: 0;
}
1% {
visibility: visible;
opacity: 0;
}
100% {
visibility: visible;
opacity: 1;
}
}
.screen-reader-text {
clip: rect(1px, 1px, 1px, 1px);
position: absolute !important;
height: 1px;
width: 1px;
overflow: hidden;
}
html
に scroll-behavior: smooth
を設定して、スムーススクロールを実装します。
Safariの対応が15.4以上になるので、今のところ(2023年2月現在)は別途JavaScriptでスムーススクロールの実装が必要かなと思います。
大きさや位置は適宜調整してください。
初期状態をopacity: 0
、visibility: hidden
で不可視にしておき、aria-hidden="false"
になったら可視状態にしています。
::before
で上向き矢印を描いています。
screen-reader-text
クラスで読み上げ用のspanタグの見た目を非表示にしています。
JavaScript
(new IntersectionObserver((entries) => {
document.getElementById('toTop')
.setAttribute('aria-hidden', entries[0].isIntersecting);
})).observe(document.querySelector('header'));
IntersectionObserver で要素を監視します。
ここではheader
を監視して、header
が viewport内にあれば#toTop
のaria-hidden="true"
に、viewport外のときはaria-hidden="false"
にしています。
Discussion