はじめに
Adobeが用意しているWebフォント。
このWebフォントの欠点である、「Webフォントを読み込み、ブラウザに反映させるのに若干ラグがあるために、文字幅の変更が発生することから、サイトが一瞬ちらついて表示されているように見える(Flash Of Unstyled Text 、FOUT)」という症状について、対策方法を記載しました。
https://hirossyi.work/blog/153
ですが、上記のやり方にはいくつかの欠点がありました。それは、
- htmlタグに「visibility: hidden;」cssを付与しているがために、基本的に初期表示が、白色ないしは単色で固定されてしまう
- Loading画面とうまく組み合わせることができない
といった問題になります。
やっぱり、Loading画面をうまく活用したい。 読み込んでいる間は、デザイン性の高い画像を表示したい。そのような要望もあるはずです。
※Loading画面のイメージはこちら
https://photopizza.design/css_loading/
そこで今回は、Loading画面とWebフォントを組み合わせて、どのように表示するかどうかについて、記載します。
達成したいこと
Webフォント案件で、Loading画面を実装するにあたりありがちなのが、以下のような方法です。
- Webフォントの読み込みはいつ終わるかどうか分からないし、ページによって違う
- なので、適当になんとなく、2秒や3秒といった固定時間を設けて、その時間が経過したらLoadingを解除する
ですが、このような実装は最適ではありません。何故なら、Webフォントの読み込みは、実は速攻で終わっているかもしれないからです。
仮にWebフォントが0.2秒で読み込み完了しているのに、Loading画面を3秒出す設定していたら、2.8秒、ユーザーに待たせてしまうことになります。それだと離脱率が上がりかねないですね。
なので、以下のような方針です。
- 初期表示はLoading画面を出す
- Webフォントが読み込み終わり次第、Loadingを解除する
- ただし低速環境を考慮して、一定時間経過したら強制的にLoading画面を解除するようにする(Webフォント読み込み完了かは問わない)
このような方針で実装していきます。
デモサイト
コード
css
※基本的には、Loading画面で使用するcssと変わらないです。
今回は、こちらの回転+虹色アニメーションをベースに、一部カスタマイズしています。
なので、この内容は必須ではないです。
html {
height: 100%;
}
body {
position: relative;
height: 100%;
width: 100%;
margin: 0;
padding: 0;
font-family: shippori-mincho, sans-serif;
font-weight: 400;
font-style: normal;
}
.loading-block{
position: fixed;
background-color: #192B33;
top: 0;
left: 0;
width: 100%;
height: 100%;
}
.loader {
position: absolute;
top: calc(50% - 32px);
left: calc(50% - 32px);
width: 64px;
height: 64px;
}
.loader div {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
border-radius: 50%;
box-sizing: border-box;
opacity: .8;
}
.one {
border-top: 1px solid #8FB259;
animation: rotate-left 1s linear infinite;
}
.two {
border-right: 1px solid #CCCC52;
animation: rotate-right 1s linear infinite;
}
.three {
border-bottom: 1px solid #FFD933;
animation: rotate-right 1s linear infinite;
}
.four {
border-left: 1px solid #FF7F00;
animation: rotate-right 1s linear infinite;
}
@keyframes rotate-left {
0% {
transform: rotate(360deg);
}
100% {
transform: rotate(0deg);
}
}
@keyframes rotate-right {
0% {
transform: rotate(0deg);
}
100% {
transform: rotate(360deg);
}
}
javascript
※めんどくさかったのでjquery使っちゃいましたが、普通にjqueryなしでも行けると思います。
※headタグ閉じの直前に記載すること
<script>
// 一覧最初に記載
function clearLoading(){
$('.loading-block').fadeOut(900);
}
// Adobe Webフォント読み込み。元はAdobe Webフォントサイトから持ってきたもので、active関数を追加
(function(d) {
var config = {
kitId: 'XXXXX',
scriptTimeout: 3000,
async: true,
// ここが重要
active: function(){
clearLoading();
}
},
h=d.documentElement,t=setTimeout(function(){h.className=h.className.replace(/\bwf-loading\b/g,"")+" wf-inactive";},config.scriptTimeout),tk=d.createElement("script"),f=false,s=d.getElementsByTagName("script")[0],a;h.className+=" wf-loading";tk.src='https://use.typekit.net/'+config.kitId+'.js';tk.async=true;tk.onload=tk.onreadystatechange=function(){a=this.readyState;if(f||a&&a!="complete"&&a!="loaded")return;f=true;clearTimeout(t);try{Typekit.load(config)}catch(e){}};s.parentNode.insertBefore(tk,s)
})(document);
// 低速環境を考慮
setTimeout(function () {
clearLoading();
}, 3000);
</script>
</head>
<body>
<!-- loadingロジックはhttps://photopizza.design/css_loading/をベースに一部変更 -->
<div class="loading-block">
<div class="loader">
<div class="one"></div>
<div class="two"></div>
<div class="three"></div>
<div class="four"></div>
</div>
</div>
<!-- page content -->
<main>
以下、コンテンツ
ポイントとなるのが、Adobe Webフォント読み込み部分のactive関数です。
この関数は、Webフォントの読み込みが完了したタイミングで実行されるイベントのようです。
こちらが実行完了時に、clearLoading関数をしています。
そして、その下のsetTimeoutです。こちらは、「低速環境を考慮して、一定時間経過したら強制的にLoading画面を解除するようにする」のものです。
低速環境だと、フォントが読み込まれないために、コンテンツがいつまでも表示されない現象が起きかねないです。
それを解消するために、3秒経ったら、Loadingを強制解除するようにしています。
このような実装で、本当に必要な時間だけLoading画面を出す、ということが達成できます。是非お試しあれ。