fr は CSS のグリッドレイアウト中で使用可能な値の単位です。これは端的にいうと利用可能な空間を等分して扱う時に使う値の単位です。fr は恐らく fraction(分数)の略です。
グリッドレイアウトの基本概念 – CSS: カスケーディングスタイルシート | MDN#単位 fr
fr の使い方は具体的には次です。
.grid.fr-only { display: grid; /* 1 + 2 + 4 + 8 + 16 = 31 を分母として空間を割り当てる */ /* 1/31 2/31 4/31 8/31 16/31 といった具合 */ grid-template-columns: 1fr 2fr 4fr 8fr 16fr; } .grid.px-combine { display: grid; /* fr 以外の数値が混じると全体から混じった分の長さを引き */ /* 残った空間を各frで振り分ける */ /* (1 / 31) * (100% - 160px) 的な感じ */ grid-template-columns: 1fr 2fr 4fr 160px 8fr; } .grid > div { background: #8ff; border: solid 1px black; }
fr 単位の便利な点として記述が楽という点があります。仮に calc で同じ目的のデザインを作る場合、次の様に記述する必要があります。これはなかなか手間です。
/* calc */ grid-template-columns: calc(1 / 31 * 100%) calc(2 / 31 * 100%) calc(4 / 31 * 100%) calc(8 / 31 * 100%) calc(16 / 31 * 100%); /* fr */ grid-template-columns: 1fr 2fr 4fr 8fr 16fr;
また分数をそのまま渡すことによる有効桁数問題の緩和という利点あります。
gap は行や列の隙間の大きさを定義する CSS プロパティです。グリッド以外にも使えます。
gap (grid-gap) – CSS: カスケーディングスタイルシート | MDN
gap は次の様に使えます。
.grid.fr-only { display: grid; gap: 10px;/* grid の各グリッドセルの隙間を 10px と指定 */ grid-template-columns: 1fr 2fr 4fr 8fr 16fr; } .grid > div { background: #8ff; border: solid 1px black; }
時折、各グリッドセルの大きさに応じて隙間を広くしたり狭くしたりしたい場合があります。この時、便利に使えそうと思い浮かぶのが fr 単位で gap を指定することです。しかしながら gap はグリッド以外にもつかえるためか fr 単位の値を渡すとそれがグリッドに大して作用する gap であっても無効化されます。次のスクリーンショットは Google Chrome バージョン: 101.0.4951.67 ですが、少なくとも FireFox 100.0 で同様のふるまいをみせます。
この場合の対処法として次の二つがあげられます。
一つが % を使うことです。fr 単位ほど厳密に均等に各要素の大きさを定めることはできませんが、隙間を可変にするという要件は達成できます。厳密な計算を行う必要がない場合、この方法がおすすめです。
もう一つがダミーの要素を置いて fr を定義して gap 的にふるまわせる方法です。こちらは要素数が増えることになり、記述が手間になる問題もありますが fr 単位そのものを使った見た目になります。
それぞれの方法のデモが次です。
.grid.css-gap { display: grid; /* %で gap を定義をする場合、必要なセル数をあらかじめ考えておき、あるべき%を導出します */ /* 各グリッドセルの分母 + 隙間の数 = 使うべき分母 */ /* 31 + 4 = 35 */ gap: calc(1 / 35 * 100%); grid-template-columns: 1fr 2fr 4fr 8fr 16fr; } .grid.dummy-gap { display: grid; /* ダミー要素で gap の代わりをする場合、本来の gap を無効にし、ダミー要素に必要なfr単位の値を割り当てます。 */ /* 本来の gap を無効 */ gap: 0; /* gap である 1fr を元々あった各セル定義の間に追加 */ grid-template-columns: 1fr 1fr 2fr 1fr 4fr 1fr 8fr 1fr 16fr; } .grid > div:not(.gap) { background: #8ff; border: solid 1px black; }