husky + lint-staged で品質を保つ

リントツールをインストールしても使わなければ意味がない。

というわけで人的なリント忘れを未然に防ぐためにも、huskey と lint-staged と 各種リントツールを組み合わせてコミット前に自動的にリントが行われる環境を作りましょう。リントエラー時にコミットを弾くことによって git 上のコードの品質を保つことができます。

続きを読む

object-fit で画像を自由にサイジング

object-fit プロパティは <img> や <video> などによく使用されるプロパティです。width や height などを使って指定したボックス領域に、どんな感じで画像やビデオを表示するか、というのを object-fit で指定します。

どんな感じで、と言うのは具体的にはサイズ感やリサイズ方法、表示範囲を指します。object-fit プロパティの値には fillcontaincovernonescale-down のうちのいずれかを指定でき、もちろんそれぞれ意味が異なるので意図にあったものを選ぶ必要があります。

例えば、アスペクト比を無視してボックス領域全体に画像を拡大表示したいという場合であれば fill が最適です。以下に各値がどのように作用するかについてまとめました。

fill アスペクト比を無視して、領域全体を埋めるように拡大表示する。(デフォルト値)
contain アスペクト比を保ったまま、領域に収まる最大サイズで表示する。
cover アスペクト比を保ったまま、領域全体を埋める最小サイズで表示する。
none 一切リサイズせず、ボックス領域でトリミングされる。
scale-down nonecontainのうち、サイズが小さい方で表示する。

ポリフィル

ただ、残念ながらIE11では object-fit をサポートしていません。Edgeにおいても<img>以外への使用はサポートしていないようです。

そのためそれらのブラウザ上で object-fit を使用するにはポリフィルが必要となります。オススメは object-fit-images です。<img>タグのみの対応ですが、ポリフィル導入時の変更が他のものと比べかなり少なく済むのが特徴です。

<video> などに object-fit を使用したい場合は object-fit-polyfill がいいかもしれません。こちらは試していないのでなんとも言えませんが、<img><video><picture>に対応しているようです。

object-fit-images の使用方法

参考程度に object-fit-images の使用方法も記しておきます。このポリフィルの面白いところは何と言っても font-family を使って文字列を保存している点ですね。

object-fit-images を使用する場合はHTMLとCSSの修正が必要です。

まずはHTML側でスクリプトの読み込みと呼び出しを行います。

<script src="./ofi.min.js" async></script>
<script>
  window.addEventListener('load', function() {
    objectFitImages();
  });
</script>

次にCSS側で、object-fit プロパティを指定している場所に追加で font-family で object-fit を指定します。

.cover-polyfill {
  object-fit: cover;
  font-family: "object-fit: cover";
}

これで完了です。不明な点などあれば以下のデモページも参考にしてみてください。

デモ

デモページ

object-fit のデモページです。object-fit-images をポリフィルとして使用したパターンも掲載しています。

font-familyプロパティにクォーテーションは必要?

CSSでフォントを指定する際に使うfont-familyプロパティ。CSSを使う人なら必ず一度は書いたことがあるであろうプロパティの一つですが、以前から僕には一つ疑問がありました。それは何かと言うと、タイトルにもありますが、値を指定する際にクォーテーションが必要かどうか? ということです。

ちなみに以下のCSSはいずれも正常に動作します。

font-family: メイリオ, Verdana;
font-family: 'メイリオ', 'Verdana';
font-family: "メイリオ", "Verdana";

ネットで軽く検索をかけてみると、「スペースを含むフォント名にはクォーテーションが必須」や「日本語を含むフォント名にはクォーテーションが必須」といった意見が見つかりますが、試しに実際に動かしてみると、どうも正常に動くようです。果たしてこれはブラウザの忖度なのか? あるいはネット上の意見が間違っているのか? というわけで少し深掘りしてみることにしました。

結論から言うと、おそらく、日本語を含む場合もスペースを含む場合もクォーテーションは必要ありません。(※ スペースが2つ以上連続で続く場合を除く)

調べてみる

こういう時はやはり規格の仕様をみるのが手っ取り早いです。CSSはW3Cが仕様を制定していて、フォントに関する仕様は CSS Fonts Modules Level 3 でまとめられているみたいです。現時点ではまだ勧告候補で最終決定盤ではないみたいですが、まあいいでしょう(適当)。

CSS Fonts Modules Level 3 の font-family の項には以下のように書かれています。

Font family names other than generic families must either be given quoted as strings, or unquoted as a sequence of one or more identifiers.

汎用ファミリー以外のフォントファミリー名は、stringsとしてクォーテーションで囲うか、あるいはひとつ以上の identifies の並びである必要があります。

!! これは重要な情報です。フォントファミリー名の指定が identifies の並びであればクォーテーションは必要ないのです。ここでいう identifies は以下のように定義されています。

In CSS, identifiers (including element names, classes, and IDs in selectors) can contain only the characters [a-zA-Z0-9] and ISO 10646 characters U+00A0 and higher, plus the hyphen (-) and the underscore (_); they cannot start with a digit, two hyphens, or a hyphen followed by a digit. Identifiers can also contain escaped characters and any ISO 10646 character as a numeric code (see next item). For instance, the identifier “B&W?” may be written as “B\&W\?” or “B\26 W\3F”.

要は identifies は[a-zA-Z0-9]、ISO 10646のU+00A0以上、ハイフン(-)、アンダースコア(_)のみを含み、かつ、数字、2つのハイフン、1つのハイフンと数字では始まらないもののことを指します(わかりづら)。ここで重要なのは、日本語はU+00A0以上なので identifies に含むことができるということです。

つまり…

これまでのことを総合するとこうです。

  • identifies の並びであればクォーテーションは必要ない。
  • 日本語もidentifies に含まれる。

つまり、フォントファミリー名に日本語が含まれようと、スペースが含まれようと、全て identifies の並びとして解釈され、クォーテーションは必要ないようです。

ひとつ気がかりなのが identifies の『並び』と言う部分です。僕は並びと言うのをスペース区切りと解釈しました(英語の文章も単語をスペースで区切って並べるし…)が、それがあってるのか正直微妙です。ですがいろんな記事に目を通したところおそらく! 僕の解釈であっていると思われます。

仕様の続き

To avoid mistakes in escaping, it is recommended to quote font family names that contain white space, digits, or punctuation characters other than hyphens:

エスケープ時の間違いを防ぐために、スペース、数字、ハイフン以外の区切り文字を含む場合、クォーテーションで囲うことをオススメします。

しかし強制ではないものの、仕様ではスペースを含む場合はクォーテーションで囲うことをオススメしているので、特に理由のない限り結局はクォーテーションを使ったほうがいいのかもれません。

注意点

ちなみに絶対クォーテーションが必要なケースが2つあって、1つはフォントファミリー名が inherit や serif などのCSSで使用するキーワードと同じ場合。

もう1つは、フォントファミリー名の中で2つ以上のスペースが連続で続く場合です。と言うのも、identifies の並びで記述された値は全てのidentifies をスペースで結合した文字列に変換されるため、2つ以上のスペースは1つのスペースに変換されてしまいます。まあそんなフォント名があるかどうかわかりませんが、そういったフォントを扱う場合は指定に気をつける必要がありそうです。

参考リンク