Loadingアイコンメーカーはじめました(2015年9月3日)
CSSだけでloadingを作る方法の6回目です。
過去に矢印・ボールが回転するloading・loadingバー・その他の回転系・その他のバータイプと紹介してきました。
toolの方でまとめる予定でしたが、作業中にテキスト型のloadingがないことに気付きましたので、1から作成してみました。
PCブラウザではIE11・IE10・Chrome・Safari・Firefox、スマホではiOSのSafari・Android標準ブラウザ・Chrome・Firefoxに対応しています。
「loading」や「読み込み中」の後に点々が続く、かなり良く見かけるタイプです。
HTMLは次のようになります。
<span class="loading">Loading<span></span></span>
CSSは以下です。
span.loading {
display: inline-block;
white-space: nowrap;
}
span.loading span {
display: inline-block;
width: 100px;
height: 2px;
vertical-align: middle;
background-position: 0 0;
background-repeat: repeat-x;
background-size: 4px 100%;
background-image:-webkit-gradient(linear, left top, right top, from(transparent), color-stop(0.5, transparent), color-stop(0.5, #000), to(#000) );
background-image:-webkit-linear-gradient(left,transparent 2px,#000 4px);
background-image: linear-gradient(to right,transparent 2px,#000 4px);
-webkit-animation: animation 1.5s linear infinite;
animation: animation 1.5s linear infinite;
}
@-webkit-keyframes animation {
0% {
width: 0;
}
100% {
width: 100%;
}
}
@keyframes animation {
0% {
width: 0;
}
100% {
width: 100%;
}
}
loading要素の中にspanを設置し、このspanでgradientを利用して点線風のラインを描写し、animationでサイズを変化させています。
尚、span要素を設置せずに疑似要素でやれそうですが、一部のwebkit系ブラウザでは疑似要素に設定したanimationが動かないためできません。
また、dottedのborderでやれそうですが、点線がスライドしているように見えてしまうため却下しました。解決策がある可能性はありますが今回はgradientを採用しました。
Loadingが左からタイミングをずらしてバウンドします。Loadingには限らず、良く利用される装飾方法かと思います。
HTMLは全てのテキストを1文字ずつspanで囲みます。
<span class="loading"><span>L</span><span>o</span><span>a</span><span>d</span><span>i</span><span>n</span><span>g</span></span>
CSSは以下です。
span.loading {
display: inline-block;
white-space: nowrap;
}
span.loading span {
display: inline-block;
vertical-align: middle;
}
span.loading span:nth-of-type(1) {
-webkit-animation: animation 2s ease 0s infinite;
animation: animation 2s ease 0s infinite;
}
span.loading span:nth-of-type(2) {
-webkit-animation: animation 2s ease 0.1s infinite;
animation: animation 2s ease 0.1s infinite;
}
span.loading span:nth-of-type(3) {
-webkit-animation: animation 2s ease 0.2s infinite;
animation: animation 2s ease 0.2s infinite;
}
span.loading span:nth-of-type(4) {
-webkit-animation: animation 2s ease 0.3s infinite;
animation: animation 2s ease 0.3s infinite;
}
span.loading span:nth-of-type(5) {
-webkit-animation: animation 2s ease 0.4s infinite;
animation: animation 2s ease 0.4s infinite;
}
span.loading span:nth-of-type(6) {
-webkit-animation: animation 2s ease 0.5s infinite;
animation: animation 2s ease 0.5s infinite;
}
span.loading span:nth-of-type(7) {
-webkit-animation: animation 2s ease 0.6s infinite;
animation: animation 2s ease 0.6s infinite;
}
@-webkit-keyframes animation {
0% {
margin-top: 0;
}
5% {
margin-top: -1em;
}
10% {
margin-top: 0;
}
13% {
margin-top: -0.5em;
}
16% {
margin-top: 0;
}
18% {
margin-top: -0.2em;
}
20% {
margin-top: 0;
}
}
@keyframes animation {
0% {
margin-top: 0;
}
5% {
margin-top: -1em;
}
10% {
margin-top: 0;
}
13% {
margin-top: -0.5em;
}
16% {
margin-top: 0;
}
18% {
margin-top: -0.2em;
}
20% {
margin-top: 0;
}
}
文字数分だけnth-of-type(1)といった具合に各1つ文字を指定して、それぞれにanimationを設定しています。animation-delayプロパティを0.1秒ずつずらして定義することで左側波打つようにanimationが実行されます。
animationの中身では、バウンドを意識してmargin-topを変化させています。厳密な計算でパーセントとmarginの量を変化させれば、よりリアルなバウンドを再現できますが、バウンド対象が複数あり、比較的スピードのあるバウンドのため、減衰を少なめにして「バウンド感」を演出すること優先された方が良いと思われます。
尚、例では「Loading」「読み込み中」の各7・5文字のテキストにしていますが、これ以上の場合はnth-of-typeを増やしてください。
こちらもloadingに限らずよく見る装飾です。ボキャブラリーが足らず「振り子」と名付けました。
HTMLは上のバウンドと同じく1文字ずつspanで囲みます。
<span class="loading"><span>L</span><span>o</span><span>a</span><span>d</span><span>i</span><span>n</span><span>g</span></span>
CSSは以下です。
span.loading {
display: inline-block;
white-space: nowrap;
}
span.loading span {
display: inline-block;
vertical-align: middle;
}
span.loading span:nth-of-type(1) {
-webkit-animation: animation 2s ease 0s infinite;
animation: animation 2s ease 0s infinite;
}
span.loading span:nth-of-type(2) {
-webkit-animation: animation 2s ease 0.1s infinite;
animation: animation 2s ease 0.1s infinite;
}
span.loading span:nth-of-type(3) {
-webkit-animation: animation 2s ease 0.2s infinite;
animation: animation 2s ease 0.2s infinite;
}
span.loading span:nth-of-type(4) {
-webkit-animation: animation4 2s ease 0.3s infinite;
animation: animation 2s ease 0.3s infinite;
}
span.loading span:nth-of-type(5) {
-webkit-animation: animation 2s ease 0.4s infinite;
animation: animation 2s ease 0.4s infinite;
}
span.loading span:nth-of-type(6) {
-webkit-animation: animation 2s ease 0.5s infinite;
animation: animation 2s ease 0.5s infinite;
}
span.loading span:nth-of-type(7) {
-webkit-animation: animation 2s ease 0.6s infinite;
animation: animation 2s ease 0.6s infinite;
}
@-webkit-keyframes animation {
0% {
-webkit-transform: rotate(-45deg);
}
5% {
-webkit-transform: rotate(45deg);
}
10% {
-webkit-transform: rotate(-23deg);
}
13% {
-webkit-transform: rotate(23deg);
}
16% {
-webkit-transform: rotate(-12deg);
}
18% {
-webkit-transform: rotate(12deg);
}
20% {
-webkit-transform: rotate(0);
}
}
@keyframes animation {
0% {
transform: rotate(-45deg);
}
5% {
transform: rotate(45deg);
}
10% {
transform: rotate(-23deg);
}
13% {
transform: rotate(23deg);
}
16% {
transform: rotate(-12deg);
}
18% {
transform: rotate(12deg);
}
20% {
transform: rotate(0);
}
}
基本構造はバウンドタイプと同一なのでそちらをご参照ください。
animation内では、transform:rotateを使って文字を交互に左右に傾けています。傾きを減衰させることで、垂直に戻る力が働いているような錯覚を生んでいます。
今回紹介する8種類の中で唯一、IEでのみ見た目が異なり、左から右へ向けて文字がキラキラと反射しているように見えます。その他では、浜辺に置かれた文字がたゆたっているように見えます。
<span class="loading"><span>L</span><span>o</span><span>a</span><span>d</span><span>i</span><span>n</span><span>g</span></span>
CSSは以下です。
span.loading {
display: inline-block;
white-space: nowrap;
}
span.loading span {
display: inline-block;
vertical-align: middle;
}
span.loading span:nth-of-type(1) {
-webkit-animation: animation 2s ease 0s infinite;
animation: animation 2s ease 0s infinite;
}
span.loading span:nth-of-type(2) {
-webkit-animation: animation 2s ease 0.1s infinite;
animation: animation 2s ease 0.1s infinite;
}
span.loading span:nth-of-type(3) {
-webkit-animation: animation 2s ease 0.2s infinite;
animation: animation 2s ease 0.2s infinite;
}
span.loading span:nth-of-type(4) {
-webkit-animation: animation 2s ease 0.3s infinite;
animation: animation 2s ease 0.3s infinite;
}
span.loading span:nth-of-type(5) {
-webkit-animation: animation 2s ease 0.4s infinite;
animation: animation 2s ease 0.4s infinite;
}
span.loading span:nth-of-type(6) {
-webkit-animation: animation 2s ease 0.5s infinite;
animation: animation 2s ease 0.5s infinite;
}
span.loading span:nth-of-type(7) {
-webkit-animation: animation 2s ease 0.6s infinite;
animation: animation 2s ease 0.6s infinite;
}
@-webkit-keyframes animation {
20% {
-webkit-text-shadow: rgba(0, 0, 0, 1) 5px 0 0;
color: transparent;
}
}
@keyframes animation {
20% {
text-shadow: rgba(0, 0, 0, 1) 5px 0 0;
color: transparent;
}
}
基本構造はバウンドタイプと同一です。
animation内で、文字色を透明化し、かつ左側に5pxずらしたtext-shadowを設定しています。これにより、元の文字が左にゆったりと5pxズレて戻る効果が得られます。
IEではanimation内でtext-shadowが効かないため、文字色の効果のみが表現されます。IEとその他を統一したい場合は、animation内のtext-shadowを消してください。
同一の表現をすべくtext-indentやmargin-leftなどで試してみましたが、color:transparentとtext-shadowの組み合わせが最も波っぽかったので採用しました。
文字列が一時的にぶるぶると動いて目立ちます。ボタンにマウスを重ねた際や、「NEW」アイコンなどを目立たせるためなど、様々に利用される手法です。
「応答していない」のではなく、しっかり「読み込み中」であることを強く伝えることができます。
HTMLはspanのみでシンプルです。
<span class="loading">Loading</span>
CSSは以下です。
span.loading {
position: relative;
left: 0;
top: 0;
display: inline-block;
white-space: nowrap;
-webkit-animation: animation 2s infinite;
animation: animation 2s infinite;
}
@-webkit-keyframes animation {
4% {
top: -12px;
left: -12px;
}
8% {
top: 11px;
left: 11px;
}
12% {
top: -10px;
left: -10px;
}
16% {
top: 9px;
left: 9px;
}
18% {
top: -8px;
left: -8px;
}
20% {
top: 7px;
left: 7px;
}
22% {
top: -6px;
left: -6px;
}
24% {
top: 5px;
left: 5px;
}
25% {
top: -4px;
left: -4px;
}
26% {
top: 3px;
left: 3px;
}
27% {
top: -2px;
left: -2px;
}
28% {
top: 1px;
left: 1px;
}
29% {
top: 0;
left: 0;
}
}
@keyframes animation {
4% {
top: -12px;
left: -12px;
}
8% {
top: 11px;
left: 11px;
}
12% {
top: -10px;
left: -10px;
}
16% {
top: 9px;
left: 9px;
}
18% {
top: -8px;
left: -8px;
}
20% {
top: 7px;
left: 7px;
}
22% {
top: -6px;
left: -6px;
}
24% {
top: 5px;
left: 5px;
}
25% {
top: -4px;
left: -4px;
}
26% {
top: 3px;
left: 3px;
}
27% {
top: -2px;
left: -2px;
}
28% {
top: 1px;
left: 1px;
}
29% {
top: 0;
left: 0;
}
}
position:relativeにし、animation内でtopとleftを変化させることで、文字が揺れている感じを表現しています。
パーセントの間隔を減らすことで減衰を表現していますが、厳密な計算は行っていません。
loadingに限らず他の場面でも利用できると思います。例えば、a:hoverに設定することで、動きのあるボタンを簡単に作れます。
下線を移動させることで、控えめに読込中を表現しています。
HTMLはspan内に空のspanを設置し、これで下線を表現しています。
<span class="loading">Loading<span></span></span>
CSSは以下です。
span.loading {
position: relative;
display: inline-block;
}
span.loading span {
position: absolute;
display: inline-block;
left: 0;
right: 0;
top: 100%;
height: 2px;
background-position: 0 0;
background-repeat: repeat-x;
background-size: 10px 100%;
background-image:-webkit-gradient(linear, left top, right top, from(transparent), color-stop(0.9, transparent), color-stop(0.9, #000), to(#000) );
background-image:-webkit-linear-gradient(left,transparent 5px,#000 5px,#000 10px);
background-image: linear-gradient(to right,transparent 5px,#000 5px,#000 10px);
-webkit-animation: animation 0.5s linear infinite;
animation: animation 0.5s linear infinite;
}
@-webkit-keyframes animation {
0% {
background-position: 0 0;
}
100% {
background-position: 10px 0;
}
}
@keyframes animation {
0% {
background-position: 0 0;
}
100% {
background-position: 10px 0;
}
}
中のspanにgradientでストライプを表現し、animationでbackground-positionを変化させることでストライプを移動させています。過去に紹介したloadingバーに似ています。
はじめに紹介した尻尾タイプと同様、borderのdottedやdashedでは表現できなかったためgradientを採用しています。
尚、background-sizeの10pxと、keyframes内のbackground-positionの10pxがずれると、滑らかな動作になりませんので、点線の間隔などを変更する際はご注意下さい。
上の動く点線タイプと同じ構造です。こちらもかなり控えめに見えます。
HTMLも上と同じく、spanを内部に設置します。
<span class="loading">Loading<span></span></span>
CSSは以下です。
span.loading {
position: relative;
display: inline-block;
}
span.loading span {
position: absolute;
display: inline-block;
left: 0;
top: 100%;
width: 100%;
height: 2px;
background-position: 0 0;
background-image:-webkit-gradient(linear, left top, right top, from(#000), to(transparent) );
background-image:-webkit-linear-gradient(left,#000,transparent);
background-image: linear-gradient(to right,#000,transparent);
-webkit-animation: animation 2s linear infinite;
animation: animation 2s linear infinite;
}
@-webkit-keyframes animation {
0% {
width: 0;
background-color: transparent;
}
40% {
width: 100%;
background-color: transparent;
}
80% {
width: 100%;
background-color: #000;
}
100% {
width: 100%;
background-color: #000;
}
}
@keyframes animation {
0% {
width: 0;
background-color: transparent;
}
40% {
width: 100%;
background-color: transparent;
}
80% {
width: 100%;
background-color: #000;
}
100% {
width: 100%;
background-color: #000;
}
}
中のspanで設置したバーには、gradientで単純なグラデーションを設定しています。これをanimationで、widthを変化させることで、目盛が上昇するようなイメージを表現しています。
width:100%となった時点で、文字列と同じサイズのグラデーションが設置されます。これ以降は、backgroundの色を変化させて、グラデーションを1色で塗りつぶしています。以上により、100%まで目盛が達しているように見せています。
これはオリジナルなアイディアです。文字列を囲む線が上から時計回りに展開されて、最終的にボックスに囲まれます。
paddingを設定して、もう少し大きな文字で使用すると、まずまず使えるかと思います。
HTMLはspanを中に設定します。
<span class="loading">Loading<span></span></span>
CSSは以下です。
span.loading {
position: relative;
display: inline-block;
border-top: 1px solid transparent;
border-right: 1px solid transparent;
border-bottom: 1px solid transparent;
border-left: 1px solid transparent;
-webkit-animation: animation 5s linear infinite;
animation: animation 5s linear infinite;
}
span.loading span {
position: absolute;
display: inline-block;
left: -1px;
top: -1px;
width: 1px;
height: 1px;
background-color: #000;
-webkit-animation: animation2 5s linear infinite;
animation: animation2 5s linear infinite;
}
@-webkit-keyframes animation {
20% {
border-top: 1px solid #000;
border-right: 1px solid transparent;
border-bottom: 1px solid transparent;
border-left: 1px solid transparent;
}
40% {
border-top: 1px solid #000;
border-right: 1px solid #000;
border-bottom: 1px solid transparent;
border-left: 1px solid transparent;
}
60% {
border-top: 1px solid #000;
border-right: 1px solid #000;
border-bottom: 1px solid #000;
border-left: 1px solid transparent;
}
80% {
border-top: 1px solid #000;
border-right: 1px solid #000;
border-bottom: 1px solid #000;
border-left: 1px solid #000;
}
100% {
border-top: 1px solid #000;
border-right: 1px solid #000;
border-bottom: 1px solid #000;
border-left: 1px solid #000;
}
}
@keyframes animation {
20% {
border-top: 1px solid #000;
border-right: 1px solid transparent;
border-bottom: 1px solid transparent;
border-left: 1px solid transparent;
}
40% {
border-top: 1px solid #000;
border-right: 1px solid #000;
border-bottom: 1px solid transparent;
border-left: 1px solid transparent;
}
60% {
border-top: 1px solid #000;
border-right: 1px solid #000;
border-bottom: 1px solid #000;
border-left: 1px solid transparent;
}
80% {
border-top: 1px solid #000;
border-right: 1px solid #000;
border-bottom: 1px solid #000;
border-left: 1px solid #000;
}
100% {
border-top: 1px solid #000;
border-right: 1px solid #000;
border-bottom: 1px solid #000;
border-left: 1px solid #000;
}
}
@-webkit-keyframes animation2 {
0% {
left: -1px;
top: -1px;
}
2% {
left: 100%;
top: -1px;
}
20% {
left: 100%;
top: -1px;
}
22% {
left: 100%;
top: 100%;
}
40% {
left: 100%;
top: 100%;
}
42% {
left: -1px;
top: 100%;
}
60% {
left: -1px;
top: 100%;
}
62% {
left: -1px;
top: -1px;
}
80% {
left: -1px;
top: -1px;
}
}
@keyframes animation2 {
0% {
left: -1px;
top: -1px;
}
2% {
left: 100%;
top: -1px;
}
20% {
left: 100%;
top: -1px;
}
22% {
left: 100%;
top: 100%;
}
40% {
left: 100%;
top: 100%;
}
42% {
left: -1px;
top: 100%;
}
60% {
left: -1px;
top: 100%;
}
62% {
left: -1px;
top: -1px;
}
80% {
left: -1px;
top: -1px;
}
}
animationを2つ使用しています。
1つ目は外側のspanで、時計回りにborder-colorを設定して色付けすることで、文字を囲む線を増やしています。
中のspanでは、1x1pxのドットを、左上から時計回りに移動させています。
外側のspanのみの場合は、枠線が順番に浮かび上がるように見えますが、これと並行して1x1pxのドットを移動させることで、枠線全体が同時に浮かび上がるのではなく、一端から一端へと線を引くように見せています。
font-size、font-familyなどは自由に設定できます。
上の解説をご理解いただける場合は、色やその他の変更も必要に応じてお試しください。
現在、loadingの色などを設定できるページをツールのページにオープン予定です。
今回紹介したloadingの対応ブラウザは初めに書きましたが、主な未対応ブラウザはIE9以下です。
これまで紹介したloadingでは、条件付きコメント(if lte IE 9)で対応しておりましたが、幸い今回のloadingは全てテキスト表記があるため、animationが動作しなくても意味を伝えることが可能です。よって、特に対策はしておりません。