コーディングを一部でも仕事に取り入れているひとであれば経験があるかもしれませんが、主要ブラウザではどんどん新しいCSSプロパティが標準化されていくので、気づかないうちに次々と「新種」が増えてキャッチアップできなくなってしまうことがあります。

もちろん、こうしたプロパティはあらゆる職種のWebデベロッパーの方にとってはよいことです。
便利なプロパティが増えれば、今までJavaScriptなどで実装していたこともCSSで短く記述できるようになり、手間も省け、生産性が向上するからです。

今回は、比較的最近登場したCSSプロパティの中でも、あまり知られていないけれど便利なCSSプロパティをご紹介します。
知らないCSSプロパティを学んでいくのに、ブラウザサポートを心配されている方もいるかもしれません。
その場合は、ぜひCan I use?などのプロパティサポート一覧を一緒にご覧ください。

あまり知られていないけれど便利なCSSプロパティ

image.jpg
Source: pexels.com

1. font-display

fontdisplay.png
Source: pablo

font-displayは、Webフォントをはじめとするダウンロード可能なフォントが完全に読み込まれる前にどのように処理すべきかや、読み込みが失敗してしまったときにどのような挙動にするかを指定するCSSプロパティです。

実際のところ、カスタムフォントが読み込まれるまで、ユーザーは長時間真っ白な画面を見続けるのを余儀なくされることがあります。
当然のことながら、ページの読み込み速度が劇的に遅ければ、ユーザーはページから離れてしまいます。

見えないテキストが表示される時間はブラウザにもよりますが、おおよそ3秒程度です。
3秒は短く感じるかもしれませんが、Webを閲覧しているユーザーにとっては極めて長く感じてしまうものです。

もともとこの問題に対処するために、Webデベロッパーたちの中にはFont Face ObserverFont Loading Module APIのようなJava Scriptを使った解決策を使うひともいました。
しかしながら、font-displayプロパティのおかげで、外部ファイルを設定してブラウザに読み込むような必要もなくなりました。

font-displayプロパティは「@font-face」の宣言内で記述するのを想定されています。
このプロパティには、次の5つの値が用意されています。

auto

規定値です。
autoは基本的にこのプロパティを全く使わないのと同じ挙動をし、結果的にブラウザのテキストが読み込み時間中は隠れてしまいます。
Webフォントなどが全て読み込まれたあとに、テキストを表示します。

block

blockを使うことで、カスタムフォントをダウンロードする間にブラウザがテキストを隠してしまう時間が、およそ1秒程度短くなります。
しかし、回線が遅いなどの理由でブラウザはカスタムフォントが読み込まれるのをずっと待っている場合は、フォントが閲覧できるまで結局待たされることになります。

swap

swapでは、カスタムフォントが読み込まれる間代替フォント(フォールバック)が表示されます。
カスタムフォントの表示の準備が完了すれば、フォールバックに代わってカスタムフォントが表示される仕組です。
まさにこれこそが多くのWebデベロッパーが待ち望んでいたものではないでしょうか。

fallback

fallbackを設定すると、カスタムフォントが見えなくなっている間のテキストがスタイリングされているわずかな間(およそ100ミリ秒)に表示する代替フォントを設定できます。
カスタムフォントの読み込みが準備されるまで、フォールバックを使ったテキストなどのスタイリングされていないテキストが表示されます。
ただし、もしページの読み込みが極端に長くなってしまえば、フォールバックが永遠に表示されるようになってしまいます。

optional

これはfallbackに似ている値です。
カスタムテキストが見えなくなっている間(100ミリ秒程度)で、カスタムフォントの準備ができていない間だけフォールバックが表示されます。
ただし、この値はブラウザ自体がフォントをダウンロードして使うべきかどうかを判断することになります。

ブラウザがカスタムフォントをダウンロードしないと決定する場合は、例えば回線速度が遅くてページの表示に支障をきたす場合です。
optionalを使うのは、ページのデザインやブランディングにフォントのタイプフェイスが決定的な役割を担っているわけではない時が好ましいでしょう。

さて、具体的には以下のように利用していきます。

@font-face {
  font-family: FerretFont;
  src: url('/fonts/ferretfont.woff2') format('woff2'), url('/fonts/ferretfont.eot') format('eot');
  font-display: swap;
}

h1 {
  font-family: FerretFont, Arial, sans-serif;
}

ブラウザサポートは2017年7月現在ではまだ未対応も多いですが、すぐに改善される見通しです。

2. contain

contain.png
Source: pablo

WordPressサイトなどをはじめとしたブログサイトなどで、たくさんのウィジェットを使った複雑なWebサイト構築を行う場合があります。
その時に、containプロパティは大いに活躍するはずです。

このプロパティを使うことによって、指定されたDOM要素やコンテンツが、ドキュメントツリーの他の場所と独立していることをブラウザに知らせます。
つまり、containプロパティは、WebコンポーネントやReactコンポーネントをたくさん組み込む時に活躍します。

より実践的に使うのであれば、独立したウィジェット部分にcontainを適用することで、高さや横幅を、他のDOM要素に影響させずに変更したりすることができます。

具体的には、次のような値が用意されています。

none

規定値です。
どのコンテナもcontainの適用を受けません。

size

サイズを保持した要素になります。
これは、子要素や孫要素によってサイズが変わることがないという意味です。

layout

レイアウトの封じ込めを有効にします。
封じ込めている要素の内外のレイアウトが互いに影響しあうことがないようにします。

style

スタイルの封じ込めを有効にします。
これは、子要素や孫要素の他にも影響を及ぼす可能性のあるほかのプロパティの効果が、封じ込めている要素の外に波及しないようにするという意味です。

paint

塗りの封じ込めを有効にします。
これは、子要素や孫要素がコンテナの境界線を超えて表示されないという意味です。
例えば、ある要素がコンテナの中で表示しきれなかった場合に、その部分は非表示で見えなくなってしまうということです。

strict

これはsize・layout・style・paintのすべての要素を有効にする値です。

content

strictに近いですが、sizeを除いた形になります。

まだ対応ブラウザはそれほど多くありませんが、何気ない変更でもページが不意に遅い処理にならないようにすることができる便利なプロパティです。
ウィジェットなどを多用している際には、このプロパティを使ってみましょう。

3. will-change

willchange.png
Source: pablo

Webデベロッパーであれば、ページの読み込み速度にはシビアになっているでしょう。
とりわけ、モバイルデバイスにおいてはページの読み込み速度はたとえ1秒であっても命取りとも言えます。

モバイルデバイスの限られたRAMやGPUメモリーでは、デスクトップでの閲覧に比べて、CSSによる処理が極めて遅くなってしまう場合があります(特に格安スマホなどの低スペックなものの場合には起こりやすいです)。
実際、「ブラウザ自身」は、ページがすべて読み込まれるまで、レスポンシブ処理も含めてどんなことが起こるのかを予測することができません。
逆に言えば、ブラウザがこれらを知ることができれば、ある程度の表示速度の改善になるのではないでしょうか。

そこに目をつけたのが、will-changeプロパティです。
このプロパティを使うことで、ブラウザは実際の処理を行う前に表示の最適化を行うので、メモリーアロケーションもスムーズに行われ、表示速度が少し早くなります。

幸運なことに、このプロパティはすでにChrome 53以上・Opera 43以上・Firefox 52以上・Safari 10・ Androidでサポートされています。

ただし、注意したいのは、あまりにも多くの要素がある場合には、このプロパティは意味をなさない可能性もあります。
場合によっては遅延につながるケースもあるので、必ずブラウザテストを行うようにしましょう。

will-changeプロパティには、以下の値があります。

auto

規定値です。
ブラウザは要素に対して最適化を行うことはありません。

scroll-position

名前が示すように、スクロールで表示されるときに正しく表示できるよう準備をしておきます。

contents

要素の中身が変化する場合に指定します。

例えば、will-changeは以下のように使います。

.will-change {
  transition: transform 0.3s;
}

.will-change:hover {
  will-change: transform;
}

.will-change:active {
  transform: scale(1.5);
}

このようにしておくことで、要素のホバー時に「transform」の準備をしておくので、アクティブ時にscaleによる画像処理がスムーズに行われるようになります。