このページはコミュニティーの尽力で英語から翻訳されました。MDN Web Docsコミュニティーについてもっと知り、仲間になるにはこちらから。
if()
Limited availability
This feature is not Baseline because it does not work in some of the most widely-used browsers.
Experimental:これは実験的な機能です。
本番で使用する前にブラウザー互換性一覧表をチェックしてください。
if() はCSS の関数で、条件付き検査の結果に応じて、プロパティに異なる値を設定することができます。この検査は、スタイルクエリー、メディアクエリー、機能クエリーに基づいて行うことができます。
In this article
構文
/* 単独の <if-test> */if(style(--scheme: dark): #eeeeee;)if(media(print): black;)if(media(width > 700px): 0 auto;)if(supports(color: lch(7.1% 60.23 300.16)): lch(7.1% 60.23 300.16);)/* <if-test> に else をつけたもの */if(style(--size: "2xl"): 1em; else: 0.25em;)if(media(print): white; else: black;)if(media(width < 700px): 0 auto; else: 20px auto)if( supports(color: lch(7.1% 60.23 300.16)): lch(7.1% 60.23 300.16); else: #03045e;)if( supports(color: lch(75% 0 0)): 3px solid lch(75% 0 0); else: 3px solid silver;)/* 複数の <if-test> */if( style(--scheme: ice): linear-gradient(#caf0f8, white, #caf0f8); style(--scheme: fire): linear-gradient(#ffc971, white, #ffc971); else: none;)/* 一括指定内の <if-test> */3px yellow if( style(--color: green): dashed; style(--color: yellow): inset; else: solid;)引数
この引数は、セミコロンで区切られた<if-branch> のリストです。それぞれの<if-branch> は、<if-condition> にコロンと<value> が続く形式です。
<if-branch> = <if-condition> : <value>;
返値
値またはguaranteed-invalid。
解説
CSS のif() 関数は、CSS プロパティの値に条件付き論理を提供し、JavaScript のif...else 文と同様に動作します。
if(!) 関数は、任意のプロパティの値内で使用することができ、セミコロンで区切られた<if-condition> を 0 個以上含めることができます。それぞれの<if-condition> は、<if-test> : <value> のペア、またはelse : <value> のペアのいずれかです。最後の<if-condition> の後のセミコロンはオプションです。
返値は次のように計算されます。
<if-condition>式は、関数に現れる順に評価されます。- 最初の
trueと評価される<if-condition>は、関連付けられた<value>を返します。 <if-condition>がtrueと評価されない場合、関数は<guaranteed-invalid>: を返します。これは、カスタムプロパティ やanchor()関数など、代替値を持つ値文でif()関数が使用されている場合、不正またはfalseとして動作します。
例を示します。
div { background-image: if( style(--scheme: ice): linear-gradient(#caf0f8, white, #caf0f8); style(--scheme: fire): linear-gradient(#ffc971, white, #ffc971); else: none; );}この場合、--schemeカスタムプロパティ がice とfire のどちらに設定されているかによって、<div> 要素のbackground-image として異なるlinear-gradient() を設定しています。--scheme が存在しない場合、または存在しても他の値に設定されている場合は、else の値が適用され、background-image プロパティはnone に設定されます。
メモ:それぞれの条件は、関連付けられた値とコロンで区切り、それぞれの<if-condition> : <value> ペアはセミコロンで区切る必要が あります。最後の<if-condition> : <value> ペアでは、セミコロンはオプションです。
警告:if と開き括弧 (() の間に空白があってはなりません。空白がある場合、宣言全体が不正になります。
単一の<if-condition> または<value> が不正な場合、if() 関数全体が不正になるわけではありません。代わりに、パーサーは次の<if-condition> : <value> ペアに移動します。<if-condition> および<value> のいずれも有効でない場合、関数はguaranteed-invalid を返します。
else : <value> ペアの頻度と位置
if() 関数内には、任意の位置に複数のelse : <value> ペアを含めることができます。ただし、ほとんどの場合、セミコロンで区切られたリストの最後に 1 つのelse : <value> ペアを指定して、<if-test> のいずれも真と評価されなかった場合に常に返される既定値を指定します。
<if-test> : <value> ペアの前にelse : <value> ペアを含めると、else は常にtrue と評価されるため、それに続く条件は評価されません。したがって、次のif() は常にnone を返し、2 つの<if-test> : <value> ペアは決して評価されません。
div { background-image: if( else: none; style(--scheme: ice): linear-gradient(#caf0f8, white, #caf0f8); style(--scheme: fire): linear-gradient(#ffc971, white, #ffc971) );}期待どおりに動作していない値をデバッグする場合、値リストの末尾以外の位置にelse : <value> を配置したい場合があります。次の例では、最初の<if-test> : <value> ペアが正しく動作しているかどうかを調べます。正常に動作していない場合、else : <value> ペアはurl("debug.png") の値を返し、最初の<if-test> : <value> ペアを修正する必要があることを示す画像を表示します。最後の 2 つの<if-test> : <value> ペアは、ここでも評価されません。
div { background-image: if( style(--scheme: ice): linear-gradient(#caf0f8, white, #caf0f8); else: url("debug.png"); style(--scheme: fire): linear-gradient(#ffc971, white, #ffc971); else: none; );}if() 関数は、else : <value> のペアのみ、またはまったく何も含まれていない場合でも、有効であることに注意してください。次のプロパティ値はどちらも有効です。
background-color: if(else: yellow);background-image: if();これらの関数はあまり有用ではありません。妥当性を示すために記載してあります。この場合、background-color の値は常にyellow に設定され、background-image は初期値に設定されます。background-color を直接yellow に、background-image をinitial またはnone に設定したほうがいいでしょう。
if-test の型
<if-test> は 3 つのクエリー型のいずれかを受け入れます。この節では、それぞれの型について詳しく見ていきます。
スタイルクエリー
スタイルクエリー の<if-test> を使用すると、要素に特定のプロパティ値が設定されているかどうかを検査し、その結果に応じて別のプロパティに値を適用することができます。先ほど、いくつかのスタイルクエリーの例を追ってみましたが、もう 1 つ例を見てみましょう。
background-image: if( style(--scheme: ice): linear-gradient(#caf0f8, white, #caf0f8); else: none;);同じ要素で--scheme 独自のプロパティがice の値に設定されている場合、指定されたlinear-gradient() の値が返されます。そうでない場合、none が返されます。
if(() 文内でスタイルクエリーを使用すると、@container クエリーよりも利点があります。コンテナーの親要素に設定されているスタイルをチェックする代わりに、独自のプロパティが設定されているかどうかによって、スタイルが設定されている要素を直接指定できるからです。
スタイルクエリー内では、and、or、not の論理も使用することができます。例を示します。
background-color: if( style((--scheme: dark) or (--scheme: very-dark)): black;);background-color: if( style((--scheme: dark) and (--contrast: hi)): black;);background-color: if( not style(--scheme: light): black;);@container クエリーにはいくつかの利点があります。if() スタイルのクエリーでは、一度に 1 つのプロパティ値しか設定できませんが、@container クエリーを使用すると、一連のルール全体を条件付きで適用することができます。この 2 つの手法は相互に補完的であり、用途も異なります。
コンテナースタイルクエリーは、現在、通常の CSS プロパティは対応していません。CSS のカスタムプロパティのみ対応しています。例えば、以下は機能しません。
if( background-color: if(style(color: white): black;);)メディアクエリー
メディアクエリー の<if-test> を使用すると、メディアクエリー検査の返値が true であるかどうかに応じて、プロパティの値を設定することができます。
メディア種別を使用することができます。例えば、次の<if-test> : <value> ペアは、印刷メディアではwhite の値を返しますが、else 節は、印刷以外のメディアでは#eeeeee を返します。
background-color: if( media(print): white; else: #eeeeee;)メディア特性も使用できます。次のコードは、現在のビューポートの幅が700px 未満の場合は0 auto、それ以外の場合は20px auto という値を返します。
margin: if( media(width < 700px): 0 auto; else: 20px auto;)これは、メディアクエリー結果に基づいて 1 つのプロパティの値を変更する必要がある場合に、実に有益です。
メディアクエリー内では、and、or、not の論理も使用することができます。例を示します。
border-color: if( media((width > 700px) and (width < 1000px)): blue;);border-color: if( media((width < 500px) or (orientation: landscape)): blue;);background-color: if( not media(width < 500px): blue; else: red);1 つのメディアクエリーに基づいて複数の宣言やルールを設定したい場合は、通常の@media 構文を使用する必要があります。この 2 つの手法は相互に補完的であり、それぞれ異なる用途があります。
機能クエリー
機能クエリー の<if-test> を使用すると、ブラウザーが特定のプロパティ値に対応しているかどうかによって、プロパティの値を設定することができます。
例えば、lch() 色に対応している場合はlch() 色を、対応していない場合はrgb() 色を返します。
color: if( supports(color: lch(75% 0 0)): lch(75% 0 0); else: rgb(185 185 185);)セレクター対応クエリーも動作します。ブラウザーが:buffering 擬似クラスに対応している場合、次のクエリーは1em を返します。対応していない場合はinitial を返します。
margin-top: if( supports(selector(:buffering)): 1em; else: initial;)機能クエリー内では、and、or、not 論理も使用できます。例を示します。
margin-top: if( supports((selector(:buffering)) and (color: blue)): 1em;);margin-top: if( supports((selector(:buffering)) or (color: not-a-color)): 1em;);margin-top: if( supports(not selector(:buffering)): 1em;);機能クエリーは、特定の値または別個のプロパティの対応状況に 基づいて単一のプロパティの値を変更する必要がある場合、if() 文内で実に便利です。1 つの機能クエリーに基づいて複数の宣言またはルールを設定する場合は、通常の@supports 構文を使用することをお勧めします。この 2 つの手法は相互に補完的であり、用途も異なります。
代替値の指定
if() 文は、うまく機能しなくなることはありません。対応していないブラウザー用に、明示的な代替手段を指定しておく必要があります。
例えば、この例では、if() に対応していないブラウザー用に、静的なpadding 値を指定しています。if() に対応しているブラウザーでは、最初の宣言は 2 つ目の宣言で上書きされ、--size: "2xl" という独自のプロパティが設定されているかどうかによって、異なるパディング値が設定されます。
padding: 1em;padding: if(style(--size: "2xl"): 1em; else: 0.25em);メモ:else 条件を忘れずに記載してください。if() に対応しているブラウザーでは、else 値が記載されておらず、--size が"2xl" 以外の場合、パディングはinitial に設定されます。
全体および部分的な値
if() 関数は、任意の CSS プロパティの値として設定することができますが、プロパティ値の一部を決定するためにも使用できます。例えば、次の例では、lch() の色指定に対応しているかどうかによって、border 一括指定プロパティ内のborder-color に異なる値を設定しています。
border: if( supports(color: lch(75% 0 0)): 3px solid lch(75% 0 0); else: 3px solid silver;);しかし、if() 関数を使用すると、border-color 要素のみを指定することができます。
border: 3px solid if( supports(color: lch(75% 0 0)): lch(75% 0 0); else: silver; );if() 関数の入れ子
if() 関数は、プロパティ値全体または個々の要素の場所として取ることができるため、if() 関数を他のif() 関数内、およびcalc() などの他の関数内に入れ子にして使用することができます。
例えば、この宣言では、if() を使用して、さまざまな条件に応じてcolor プロパティの値を設定しています。外側のif() 関数は、カスタムプロパティ--scheme がice とfire のどちらに設定されているかによって、具体的な値を返します(どちらの条件も真を返さない場合は、else 値black が返されます)。
ただし、2 つの<value> もif() 関数です。これらの内部if() 関数は、ユーザーが暗い色スキームを推奨している場合(prefers-color-scheme メディアクエリーを使用して決定)、明るい色の値を返し、そうでない場合は暗い色の値を返します。
color: if( style(--scheme: ice): if( media(prefers-color-scheme: dark): #caf0f8; else: #03045e; ); style(--scheme: fire): if( media(prefers-color-scheme: dark): #ffc971; else: #621708; ); else: black);次の例では、width プロパティを、親要素の幅のパーセント値から50px を差し引くcalc() 関数に設定します。パーセント値は、--scheme: wide というカスタムプロパティが設定されているかどうかを検査するif() 関数で表します。設定されている場合、パーセント値は70% なので、外側の関数はcalc(70% - 50px) と評価されます。設定されていない場合、パーセント値は50% なので、外側の関数はcalc(50% - 50px) と評価されます。
width: calc(if( style(--scheme: wide): 70%; else: 50%; ) - 50px);形式文法
Parse error: Unexpected input例
>基本的なif() の使い方
この例では、3 つの種類の<if-test> のそれぞれの基本的な使用法を示します。
HTML
この HTML には、2 つの<article> 要素を含む<section> 要素があり、その中に<h2>見出しが含まれています。<section> には、style 属性内にカスタムプロパティ--show-apple:true が設定されています。このプロパティは、後でプロパティの値を条件付きで設定するために使用します。
<section> <article><h2>最初の記事</h2></article> <article><h2>次の記事</h2></article></section>CSS
CSS では、最初に<section> 要素を対象とし、フレックスボックス でレイアウトし、2 つの子要素<article> 要素の間にgap を設定します。次に、orientation メディアクエリー<if-test> を含むif() 関数を使用して、文書が横向きの場合にflex-direction プロパティの値をrow に、縦向きの場合にcolumn に設定します。これにより、広い画面ではarticle 要素が横に並んだレイアウトになり、狭い画面では上下に並んだレイアウトになります。
html { height: 100%; font-family: sans-serif;}body,section { height: inherit;}h2 { text-align: center;}article { background-color: cyan; border: 3px solid gray; flex: 1;}section { display: flex; gap: 16px; flex-direction: if( media(orientation: landscape): row; else: column; )}次に、<h2> 要素の::before 擬似要素をターゲットとし、そのcontent プロパティをリンゴの絵文字に設定します。ただし、--show-apple: true が設定されている場合のみです(これは、HTML でインライン<style> を使用して、先ほど設定しました)。これは、スタイルクエリー の<if-test> に対応するif() 関数を使用して実現しています。
h2::before { content: if( style(--show-apple: true): "🍎 "; );}最後に、<h2> 要素自体をターゲットにします。機能クエリー<if-test> を使用して、ブラウザーがlch() 色に対応しているかどうかを検査し、対応している場合はcolor プロパティをlch() 色に設定し、対応していない場合は 16 進数で表現した色に設定します。
h2 { color: if( supports(color: lch(29.57% 43.25 344.44)): lch(29.57% 43.25 344.44); else: #792359; )}結果
スタイル設定がどのように適用されているかに注目してください。ブラウザーの開発者ツールを使用して、レンダリングされたデモを変更し、最初の 2 つのif() クエリーに対する条件付きスタイル設定を検査してください。
<section>要素のstyle属性を除去し、リンゴの絵文字が表示されなくなったことを確認してください。- 埋め込み
<iframe>のheight属性を1200pxに変更します。これにより、方向が横向きから縦向きに変更されます。その結果、レイアウトがどのように変化するかを確認してください。
if() による配色の制御
このデモでは、CSS のif() 関数を使って、CSS をより楽しく使う方法をご紹介します。それ以外にも、if() 関数を使って、カスタムプロパティの値を条件に応じて設定し、配色全体を制御することができます。
HTML
HTML には、いくつかのコンテンツを含む<article> 要素が含まれています。最上位の見出し、2 つの<p> 要素、および<aside> です。また、配色を選択できる<select> ドロップダウンを含む<form> も含んでいます。
<article> <h1>Main heading</h1> <p> Lorem ipsum dolor sit amet consectetur adipiscing elit. Quisque faucibus ex sapien vitae pellentesque sem placerat. In id cursus mi pretium tellus duis convallis. </p> <aside> <h2>An aside</h2> <p> Tempus leo eu aenean sed diam urna tempor. Pulvinar vivamus fringilla lacus nec metus bibendum egestas. </p> </aside> <p> Iaculis massa nisl malesuada lacinia integer nunc posuere. Ut hendrerit semper vel class aptent taciti sociosqu. Ad litora torquent per conubia nostra inceptos himenaeos. </p></article><form> <label for="scheme">配色を選択:</label> <select> <option value="">既定</option> <option value="ice">Ice</option> <option value="fire">Fire</option> </select></form>JavaScript
JavaScript は、<select> 要素にchange イベントリスナーを追加します。新しい値が選択されると、スクリプトは<article> 要素のclass 属性をその値に設定します。
const articleElem = document.querySelector("article");const selectElem = document.querySelector("select");selectElem.addEventListener("change", () => { articleElem.className = selectElem.value;});CSS
CSS では、<body> 要素に700px のmax-width を指定し、automargin の値を使用して中央に配置しています。しかし、メディアクエリー<if-test> を含むif() 関数を使用して、ビューポートの幅が700px 未満の場合はmargin 一括指定内のmargin-top 要素を0 に、それより広い場合は20px に設定します。これは、広い画面ではコンテンツの上部に少しマージンが取得されるが、狭い画面ではそれが除去され、少し奇妙に見えることを意味している。
* { box-sizing: border-box;}html { font-family: Arial, Helvetica, sans-serif;}p { line-height: 1.5;}form { padding-left: 20px; margin-top: 20px;}article h2 { margin: 0; font-size: 1.8rem;}body { max-width: 700px; margin: if( media(width < 700px): 0; else: 20px; ) auto 0;}次に、<article> 要素のclass 名と一致するように、--scheme というカスタムプロパティを設定します。このクラスは、<select> 要素で新しい値が選択されると、JavaScript によって設定されます。カスタム要素の値の重要性は、次の CSS ブロックでわかります。
.ice { --scheme: ice;}.fire { --scheme: fire;}CSS のif() 関数の真の実力は、カスタムプロパティと組み合わせたときに発揮されます。ここでは、if() 関数を使用して、カスタムプロパティ--scheme の値に応じて、カスタムプロパティ--color1 と--color2 に異なる色値を設定しています。次に、<article> 要素のcolor、border、background-image プロパティ、および<aside> 要素のcolor およびbackground-color プロパティで、--color1 および--color2 の値を使用しています。
ここでは、独自のプロパティを使用して、if() 関数で設定したさまざまな値によって、配色全体を制御しています。
article { padding: 20px; --color1: if( style(--scheme: ice): #03045e; style(--scheme: fire): #621708; else: black; ); --color2: if( style(--scheme: ice): #caf0f8; style(--scheme: fire): #ffc971; else: white; ); color: var(--color1); border: 3px solid var(--color1); background-image: linear-gradient( to left, var(--color2), white, var(--color2) );}aside { color: var(--color2); background-color: var(--color1); padding: 20px;}最後に、if() 関数をさらに 2 か所で使用します。
- ビューポートの幅が
700pxより広い場合は、<h1>要素のfont-sizeをcalc(3rem + 2vw)に設定し、それ以外の場合は3remに設定します。これは、広い画面ではフォントサイズがビューポートの幅の変化に応じて動的に更新され、狭い画面ではフォントサイズが変更されないことを意味しています。 --schemeカスタムプロパティの値に応じて、<h1>要素の::before擬似クラスのcontentに適切な絵文字を設定します。
h1 { margin: 0; font-size: if( media(width > 700px): calc(3rem + 2vw); else: 3rem; );}h1::before { content: if( style(--scheme: ice): "❄️ "; style(--scheme: fire): "🔥 "; else: ""; );}結果
このデモは次のように表示されます。
さまざまな配色値を選択して、外観や操作感に与える効果を確認してみてください。
仕様書
| Specification |
|---|
| CSS Values and Units Module Level 5> # if-notation> |