
NULLなCSS変数によるCSSグリッドレイアウト
JavaScript や PHP といったプログラミング言語には値がないことを意味する NULL というものがあります。この NULL をCSS変数 (カスタムプロパティ) に設定できることを知っていますか?
今回は、NULL なCSS変数を活用したグリッドレイアウトを紹介します。
NULLなCSS変数とは
未定義のCSS変数を代替値もなくプロパティに設定すると、そのプロパティは無効になります。
/* --background-repeat が未定義なら、background プロパティは無効になる。 */
.example-1 {
background: linear-gradient(red 0% 100%) var(--background-repeat) center / 1rem 1rem;
/* ≈ background: linear-gradient(red 0% 100%) undefined center / 1rem 1rem; */
}
/* --background-repeat が未定義なら、代替値の no-repeat により、要素中央に赤い正方形が表示される。 */
.example-2 {
background: linear-gradient(red 0% 100%) var(--background-repeat, no-repeat) center / 1rem 1rem;
/* = background: linear-gradient(red 0% 100%) no-repeat center / 1rem 1rem; */
}
しかし、var(--x,)
のように NULL な代替値を設定したり、--x:;
のように NULL なCSS変数を設定すると、プロパティを無効にすることなく適用することができます。
/* --background-repeat が未定義なら、NULL な代替値により、初期値の repeat が適用され、背景が赤く塗りつぶされる。 */
.example-1 {
background: linear-gradient(red 0% 100%) var(--background-repeat,) center / 1rem 1rem;
/* = background: linear-gradient(red 0% 100%) center / 1rem 1rem; */
}
/* NULL な --background-repeat により、初期値の repeat が適用され、背景が赤く塗りつぶされる。 */
.example-2 {
--background-repeat:;
background: linear-gradient(red 0% 100%) var(--background-repeat) center / 1rem 1rem;
/* = background: linear-gradient(red 0% 100%) center / 1rem 1rem; */
}
CSSグリッドレイアウトの使いづらさ
CSSグリッドは、配置する要素が決まっている場合は特に不便さを感じません。
/* ヘッダー, メインコンテンツ, ナビゲーション, サイドコンテンツ, フッターの5要素をレイアウトする。 */
.example {
& {
display: grid;
grid:
"header" auto
"main" minmax(auto, 1fr)
"nav" auto
"side" auto
"footer" auto
/ 1fr;
gap: 32px;
}
& > .header {
grid-area: header;
}
& > .main {
grid-area: main;
}
& > .nav {
grid-area: nav;
}
& > .side {
grid-area: side;
}
& > .footer {
grid-area: footer;
}
@media (width > 720px) {
& {
grid:
"header header" auto
"main nav" auto
"main side" minmax(auto, 1fr)
"footer footer" auto
/ 2fr 1fr;
}
}
}
しかし、配置する要素が一定ではない場合、途端に使いづらくなります。上記のCSSコードでは、ナビゲーションやサイドコンテンツが無い場合を想定していません。
それらを想定するのであれば、ナビゲーションがある場合、サイドコンテンツがある場合、両方がある場合、両方がない場合の4パターンのCSSコードが必要です。
.example {
& {
display: grid;
grid:
"header" auto
"main" minmax(auto, 1fr)
"footer" auto
/ 1fr;
gap: 32px;
}
&:where(:has(> .nav)) {
grid:
"header" auto
"main" minmax(auto, 1fr)
"nav" auto
"footer" auto
/ 1fr;
}
&:where(:has(> .side)) {
grid:
"header" auto
"main" minmax(auto, 1fr)
"side" auto
"footer" auto
/ 1fr;
}
&:where(:has(> .nav):has(> .side)) {
grid:
"header" auto
"main" minmax(auto, 1fr)
"nav" auto
"side" auto
"footer" auto
/ 1fr;
}
& > .header {
grid-area: header;
}
& > .main {
grid-area: main;
}
& > .nav {
grid-area: nav;
}
& > .side {
grid-area: side;
}
& > .footer {
grid-area: footer;
}
@media (width > 720px) {
&:where(:has(> .nav)) {
grid:
"header header" auto
"main nav" minmax(auto, 1fr)
"footer footer" auto
/ 2fr 1fr;
}
&:where(:has(> .side)) {
grid:
"header header" auto
"main side" minmax(auto, 1fr)
"footer footer" auto
/ 2fr 1fr;
}
&:where(:has(> .nav):has(> .side)) {
grid:
"header header" auto
"main nav" auto
"main side" minmax(auto, 1fr)
"footer footer" auto
/ 2fr 1fr;
}
}
}
ヘッダーとフッターは、ナビゲーションとサイドコンテンツの有無に関わらず、ほぼ変化がなく、同じ記述の繰り返しがあり冗長です。また、要素を追加する場合の拡張性まで考慮するとCSSコードは更に多くなり、メンテナンス性も低下します。
NULLなCSS変数を使用したCSSグリッドレイアウト
CSSグリッドレイアウトの使いづらさを解消するために NULL なCSS変数を活用すると次のようになります。
.example {
& {
--row-1: "header header" auto;
--row-2: "main main" minmax(auto, 1fr);
--row-3:;
--row-4:;
--row-5: "footer footer" auto;
--column-1: 2fr;
--column-2: 1fr;
display: grid;
grid: var(--row-1) var(--row-2) var(--row-3) var(--row-4) var(--row-5) / var(--column-1) var(--column-2);
gap: 32px;
}
&:where(:has(> .nav)) {
--row-3: "nav nav" auto;
}
&:where(:has(> .side)) {
--row-4: "side side" auto;
}
& > .header {
grid-area: header;
}
& > .main {
grid-area: main;
}
& > .nav {
grid-area: nav;
}
& > .side {
grid-area: side;
}
& > .footer {
grid-area: footer;
}
@media (width > 720px) {
&:where(:has(> .nav)) {
--row-2: "main nav" minmax(auto, 1fr);
--row-3:;
--row-4:;
}
&:where(:has(> .side)) {
--row-2: "main side" minmax(auto, 1fr);
--row-3:;
--row-4:;
}
&:where(:has(> .nav):has(> .side)) {
--row-2: "main nav" auto;
--row-3: "main side" minmax(auto, 1fr);
--row-4:;
}
}
}
想定される行と列の数だけ --row-N:;
と --column-N:;
を用意し、必要に応じて埋めるというやり方です。この方法であれば、行と列を増やし要素を追加するといった拡張性も得られます。
CodePen
〆
CSS変数の NULL は最近知りました。CSSグリッドレイアウトだけでなく、省略可能な値がある他のプロパティにも応用できそうです。