エムケーワイです。
今回はTwenty Twentyでフッターに表示される「上へ↑」(ヘッダーへのリンク)の固定表示にトライします。
お陰様で本サイトの投稿数が10件を超えたのですが、備忘録という事で画面のキャプチャ画像やコードの表示を多用しており、どの記事も結構長めになっています。
記事が長いと、読み進めていってふとページトップに戻りたいと思ったとき延々とスクロールしなければならないですよね。そんなことを読者の方に強いるのは大変申し訳ないので「トップに戻る」ボタンが欲しいと常々思っていたのですが、残念ながらTwenty Twentyの外観カスタマイズの項目にはそれに該当するものが見当たりません。
ただ、記事を読み終え、フッターを更に下にスクロールしていくと(フッターも長くてすみません^_^;)……………フッターの最下部の右隅に「上へ↑」ボタンというかリンクがあることに気づきます(スマホの場合「上↑」です)。
そこで、この「上へ↑」を固定表示できないの?と考えたわけです。
1. 結果
今回も長くなりそうなので、時間がない方のために先に結果を示します。
ここまで読んでいただくと気づかれたと思いますが、「上へ↑」を固定表示することが出来ました!
追加したCSS設定とjQueryコードの最終形は下記になります。
<CSS>
/* 「上へ↑」を固定表示 */
a.to-the-top {
position: fixed;
right: 2rem;
bottom: 30px;
display: none;
z-index: 100;
}
@media ( min-width: 700px ) {
a.to-the-top {
right: 4rem;
bottom: 43px;
}
}
<jQuery>
//
// 「上へ↑」を固定表示
//
jQuery(function() {
var _window = jQuery(window),
_toTop = jQuery('.to-the-top');
_window.on('load scroll', function() {
var scroll = jQuery(this).scrollTop();
if(scroll > 600) {
_toTop.fadeIn('slow');
} else {
_toTop.fadeOut('slow');
}
});
_toTop.click(function() {
_toTop.blur();
jQuery('body, html').animate({scrollTop:0}, 500, 'swing');
return false;
});
});
この後、上記の最終形に至った経過を記します。時間のある方はお読みください。
2. 対応前のHTML/CSS確認
対応前の「上へ↑」がどのようなHTMLコード、CSS設定になっているのかを確認したところ、下記のことが分かりました。
- 「上へ↑」自体はaタグでヘッダーにリンクされている。
- コピーライトとともにclass “section-inner”のdivタグで囲まれている。
- このdivタグの幅はmin-widthが700pxの場合”calc(100% – 8rem)”、それ以外の場合”calc(100% – 4rem)”。
- class “section-inner”に対し”display: flex”、”justify-content: space-between”が設定されている。
- 更にfooterタグで囲まれている(フッターのウィジェット部分はfooterタグの外だという事もわかりました^_^;)。
- footerタグのmargin-bottomはmin-widthが700pxの場合”43px”、それ以外の場合”30px”。
3. とりあえず固定してみる
1.の確認結果を踏まえて、とりあえずPCで確認するために子テーマのstyle.cssに下記の設定を追加しました。
/* 「上へ」を固定表示 */
a.to-the-top {
position: fixed;
right: 4rem;
bottom: 43px;
z-index: 100;
}
- “to-the-top”は「上へ↑」のaタグに設定されているクラスです。”a.to-the-top”に対して下記の設定を行いました。
- “position: fixed”は表示位置固定のために必須ですね。
- “right”は、上記3.よりdivタグのwidthが”calc(100% – 8rem)”なので”8rem”の半分の”4rem”としました。
- “bottom”には、上記6.のmargin-bottomの値を設定しました。
- 他のコンテンツより上に表示されるよう”z-index: 100″としました。
上記CSS設定の追加で「上へ↑」が常時ウィンドウの右下隅に表示されるようになりました。
フッターまでスクロールすると、元々あった位置からのずれもないようです。
4. スクロール量で表示/非表示を切り替える
2.で「上へ↑」を常時固定表示することができました。
次は、スクロール量によって表示/非表示を切り替えるために下記のjQuery関数を作成しました。
jQuery(function() {
var _window = jQuery(window),
_toTop = jQuery('.to-the-top');
_window.on('load scroll', function() {
var scroll = jQuery(this).scrollTop();
if (scroll > 600) {
_toTop.fadeIn('slow');
} else {
_toTop.fadeOut('slow');
}
});
});
(スクロール量 > 600)であれば「上へ↑」を表示し、そうでなければ「上へ↑」を非表示にします。
「上へ↑」はヘッダーへのリンクなので、クリックされた時の動作は記述不要と考えていました、この時点では。
CSSでも、初期状態を非表示にするための下記設定を”a.to-the-top”に追加します。
display: none;
動作確認をすると、スクロール量により「上へ↑」の表示/非表示が切り替わります。しかし、下スクロール後に「上へ↑」をクリックするとページトップに戻るのですが、上スクロール後に「上へ↑」をクリックした場合は何も起こらない…。はて?
原因は、上スクロールするとヘッダーがウィンドウの最上部に表示されているからでした(「スクロール時にヘッダーを固定する」で対応したものです)。
「上へ↑」はヘッダーへのリンクであり、ページトップへのリンクではありません。したがって、ヘッダーが表示されていると何も起こりません。当たり前ですね…
5. jQueryでページトップに異動させる
aタグのリンクでは、ヘッダーが固定表示されているとページトップに戻らない、ならばjQueryだ!ということで、「上へ↑」がクリックされるとページトップに戻るjQuery関数を_window.on()の後ろに追加しました。
_toTop.click(function() {
jQuery('body, html').animate({scrollTop:0}, 500, 'swing');
return false;
});
上記により、表示位置をスクロール量が0になるまで500msかけて移動させます。ページ全体のお話なので、対象要素を’body, html’としています。
“return false”は、aタグのリンクによる移動を無効にするためのものです。
これで下スクロール後にクリックしても、上スクロール後にクリックしてもページトップに戻るようになりました。
ただ、「上へ↑」の表示をよく見ると、一度クリックすると再表示された際アンダーラインが表示されたままになります。
アンダーラインは元々は、
- 通常:非表示
- hover時:表示
で、クリック後も同じ様になると思っていたのですが…
CSSの設定を確認すると、”:hover”、”:focus”でアンダーラインが表示されるようになっており、クリック後focus状態がキープされているようです。
6. focus解除
_toTop.click()に、ページトップへの移動の前に「上へ↑」のfocusを解除する処理を追加しました。
_toTop.blur();
上記により、「上へ↑」をクリック後再表示された際も、アンダーラインが
- 通常:非表示
- hover時:表示
となり、ようやく希望する状態になりました。
後は、CSS設定にスマホ時の設定を追加して完了です。
スマホ向けには”right”に”2rem”を、”bottom”に”30px”を設定します。理由は「2. 対応前のHTML/CSS確認」をご参照ください。
7. CSS設定、jQueryコードの最終形
CSS設定とjQueryコードの最終形を再掲しておきます。
Twenty TwentyのCSS設定はスマホ優先なので、PC用の設定をメディアクエリーで分離しました。
<CSS>
/* 「上へ↑」を固定表示 */
a.to-the-top {
position: fixed;
right: 2rem;
bottom: 30px;
display: none;
z-index: 100;
}
@media ( min-width: 700px ) {
a.to-the-top {
right: 4rem;
bottom: 43px;
}
}
<jQuery>
//
// 「上へ↑」を固定表示
//
jQuery(function() {
var _window = jQuery(window),
_toTop = jQuery('.to-the-top');
_window.on('load scroll', function() {
var scroll = jQuery(this).scrollTop();
if(scroll > 600) {
_toTop.fadeIn('slow');
} else {
_toTop.fadeOut('slow');
}
});
_toTop.click(function() {
_toTop.blur();
jQuery('body, html').animate({scrollTop:0}, 500, 'swing');
return false;
});
});
例によって今回もかなり長くなってしまいました。
最後までお読みいただきありがとうございました。