CSS if(): よりスマートなスタイル設定のためのインライン条件

  • if() は、style()、media()、supports() を使用した CSS 値に対する条件付きロジックを許可します。
  • 条件を順番に評価します。最初の true がその値を返し、そうでない場合は残りをカバーします。
  • @media/@supports を開かずにプロパティを変更するのに最適です。互換性のためにフォールバックを使用します。
  • より自律的なコンポーネントを実現するために、カスタム プロパティとデータ属性を組み合わせます。

CSSの属性セレクターとは何ですか

長年、CSS は「考える」ことができないと想定されていました。それでも、回避策はありました。 @media、@supports、@container、フォールバック変数 以前はコンテキストに応じてスタイルを変更できました。しかし、新しい機能によってそのレベルが上がり、デザインにおける私たちの思考方法により合致するようになりました。それは、プロパティ値に直接 if() 条件関数を組み込むことです。

それは煙ではありません。 Chrome 137以降ではif()をテストできる スタイル、メディア、サポートクエリに基づいた条件付きロジックを使用してインラインスタイルを作成できます。ただし、Chromium以外ではサポートがまだ限られているため、慎重に使用することをお勧めします。 フォールバックと組み合わせる それを理解しないブラウザ向けです。

以前からあったもの: CSSで既に使用されていた「条件文」

if() より前に、CSS はすでに、それぞれ独自のスコープを持つ条件付きメカニズムを提供していました。 これらは真の条件ではありませんが、満たされています 彼らの土地で:

  • @media: ウィンドウまたはデバイスが基準 (幅、方向、ポインターなど) を満たしている場合にルールを適用します。
  • @サポート: ブラウザが機能または値を理解する場合、スタイルをアクティブ化します。
  • @容器: コンテナーのサイズやスタイルに反応します。コンポーネントベースのデザインに役立ちます。
  • var() デフォルト値: if ではありませんが、「変数が存在しない場合はこのフォールバックを使用する」ことができます。

これらのアプローチは強力ですが、目的に「固執」しています。 メディア、サポート、またはコンテナif() 関数はこれらのツールを置き換えるのではなく、シームレスに統合します。 インターカレートおよび粒状 不動産価値において。

CSS の if() とは何か、なぜ重要なのか

Webデザイン

関数 もし() プロパティ値内に、条件と値のペアのリストを定義し、それらを順番に評価することができます。最初の条件が真の場合、それに関連付けられた値が「優先」されます。 これはif…elseに似たフローです JS ですが、CSS に埋め込まれています。

現在のバージョンでは、if() は条件内で 3 種類のクエリを理解します。 スタイル() (要素自体のスタイルクエリ) 平均() (メディアからの問い合わせ) サポート() (機能サポートの問い合わせ)。さらに、 そうでない場合: 値 他に何も当てはまらない場合をカバーします。

詳細な構文と評価

一般的な構造は、セミコロンで区切られたタイプのブランチのリストです。 :それぞれの条件は、 (style(), media() またはsupports()) またはキーワード ほかには常に true と評価されます。

/* Estructura básica */
propiedad: if(
  style(--estado: activo): valor-1;
  media(width < 700px): valor-2;
  supports(color: lch(60% 50 40)): valor-3;
  else: valor-por-defecto
);

エンジンはブランチを順番に評価します。 最初に真となるものはその値を返す条件が成立せず、elseも存在しない場合、関数の結果は次のようになる。 無効保証は無効な値のように動作し、 外部フォールバックが機能する (たとえば、カスタム プロパティの既定値やカスケードされた以前の値など)。

重要な詳細:条件またはリスト内の特定の値が無効な場合、 機能全体を無効にするわけではない; パーサーは次のペアに進みます。これにより、if() 単一障害点に対する耐性 枝の中に。

テストタイプ: style()、media()、supports()

style(): スタイルクエリ

クエリのスタイル スタイル() 対象要素が特定のプロパティ値を持っているかどうかを調べることができます(特に カスタムプロパティ)。@containerスタイルのクエリとは異なり、 スタイル() if() では、親に依存することなく、要素自体で直ちに評価されます。

/* Estado embebido en una custom property */
.card {
  --status: attr(data-status type(<custom-ident>));
  border-color: if(
    style(--status: pending): royalblue;
    style(--status: complete): seagreen;
    else: gray
  );
  background-color: if(
    style(--status: pending): #eff7fa;
    style(--status: complete): #f6fff6;
    else: #f7f7f7
  );
}

以内 スタイル() 論理演算子を使用できる および, or y 、括弧でグループ化できるので、 複雑な組み合わせ 州の。スタイルのクエリは @容器 現在、通常のプロパティはサポートされておらず(カスタムプロパティのみ)、 if() 内の style() 要素自体の単一のプロパティの値を決定するために使用されます。

media(): インターリーブされたメディアクエリ

とともに 平均() スタイルを別の@mediaブロックに分割することなく、特定のメディアクエリでプロパティの値を指定できます。これは次のような場合に最適です。 プロパティを変更したいだけの場合 環境によって異なります。

/* Ejemplo para puntero fino vs grueso */
button {
  aspect-ratio: 1;
  width: if(
    media(any-pointer: fine): 30px;
    else: 44px
  );
}

このブロックは、基本ルールと @media 所有権を再定義するが、 論理を集中させる 1か所にまとめられます。また、 メディアタイプ (例:印刷)または メディア機能 論理的に および/または/.

/* Media type */
.elemento {
  background: if(
    media(print): white;
    else: #eee
  );
}

/* Media feature con rango */
.caja {
  margin: if(
    media(width < 700px): 0 auto;
    else: 20px auto
  );
}

必要な場合 多くのセレクターや複数のプロパティを変更する 一方で、従来の@mediaブロックの方が優れています。単一の文の具体的なバリエーションについては、 if() の方が表現力が豊かです.

supports(): サポートクエリ

とともに サポート() ブラウザが特定の機能 (プロパティ、値、セレクターなど) を理解しているかどうかを確認し、それに応じて値を選択します。 プログレッシブエンハンスメントに最適 @supports ブロックを重複せずに。

/* Color de amplia gama si está soportado */
body {
  background-color: if(
    supports(color: oklch(0.7 0.185 232)): oklch(0.7 0.185 232);
    else: #00adf3
  );
}

/* Consulta de soporte de selector */
video {
  outline-width: if(
    supports(selector(:buffering)): 1em;
    else: initial
  );
}

覚えておいてください、ブランチには サポート() if()関数内では、ブラウザ自体が if() をサポートする. したがって、定義することの重要性は 確実なフォールバック 関数の外側。

elseの頻度と位置

あなたが使用することができます 1つ以上のその他 関数内で好きな場所に配置できます。しかし、最も一般的な方法は、単一の ほかに デフォルト値として最後に加えます。 elseを先頭に置くとは常に勝ち、その後の条件 評価されません.

/* Útil para depurar: colocamos un else intermedio */
.elemento {
  background-image: if(
    style(--flag: on): url("ok.png");
    else: url("debug.png"); /* si la primera no encaja, mostramos pista */
    supports(background: paint(foo)): paint(foo)
  );
}

さらに、関数 もし() のみで構成されている そうでない場合: 値、または空であっても、構文的には有効ですが、あまり役に立ちません。 値を直接割り当てる方が良い 論理がなければ。

完全な値、部分的な値、ネスト

この関数は、プロパティの値全体、またはプロパティ内の一部の値のみを取得できます。 速記これにより、同じ表現から逸脱することなく、非常に表現力豊かな作曲が可能になります。 繰り返しが少ない コードの。

/* Decidimos solo el color dentro de un shorthand */
.box {
  border: 2px solid if(
    supports(color: lch(60% 50 40)): lch(60% 50 40 / 0.7);
    else: rgb(100 120 200 / 0.7)
  );
}

機能 もし() 他のものの中に入れ子にすることができる もし()、また以下のような役でも活躍しています calc()これにより、セレクターを複製したり新しいブロックを開いたりすることなく、よりきめ細かな意思決定モデリングが可能になります。

/* Anidación doble: esquema y preferencia de color */
.elemento {
  color: if(
    style(--scheme: ice): if(
      media(prefers-color-scheme: dark): oklch(85% 0.04 220);
      else: oklch(35% 0.04 220)
    );
    style(--scheme: fire): if(
      media(prefers-color-scheme: dark): oklch(90% 0.1 30);
      else: oklch(40% 0.1 30)
    );
    else: black
  );
}

/* calc() con porcentaje condicionado */
.panel {
  width: calc(
    if(style(--scheme: wide): 70%; else: 50%) - 50px
  );
}

if()を使って決定することもできます 不動産のゆるい部分 変更されないものを複製せずに、ショートハンド内の margin-top として、または特定の背景コンポーネントとして。

実践的な例を散りばめた

1) ポインタの種類に応じてアクセスできるボタン

デバイスに 細いポインター (例: マウス) の場合、ボタンは小さくなります。タッチ スクリーンでは、アクセシビリティの推奨事項を満たすために 44 ピクセルに拡大されています。 一つの発言、二つの行動.

button {
  aspect-ratio: 1;
  width: if(
    media(any-pointer: fine): 30px;
    else: 44px
  );
}

上記はベース + @mediaブロックと同等ですが、次のように ロジックを複数のサイトに分散させない エラーの可能性を減らします。

2) フォールバック機能を備えた幅広い色域

ブラウザが理解できる場合 OKLCH、その色を使用し、ついでに情報メッセージを表示します :: afterそれ以外の場合は、安全なヘックスを適用します。 ドラマのない互換性.

body {
  background-color: if(
    supports(color: oklch(0.7 0.185 232)): oklch(0.7 0.185 232);
    else: #00adf3
  );
}

body::after {
  content: if(
    supports(color: oklch(0.7 0.185 232)): "Tu navegador admite OKLCH";
    else: "Tu navegador no admite OKLCH"
  );
}

RGBと現代の空間の視覚的な違いを知りたい場合は、 oklch.comのようなリソースサポートがある場合にこれらのスペースを採用する価値がある理由がわかります。

3) UIステータスによって変化するカード

状態を保存する データステータス、読んでみてください attr() カスタムプロパティに向けて、決定を下す スタイル()エレガントな方法で 自己完結型コンポーネント.

<div class="card" data-status="complete">...</div>

.card {
  --status: attr(data-status type(<custom-ident>));
  border-color: if(
    style(--status: pending): royalblue;
    style(--status: complete): seagreen;
    else: gray
  );
  background-color: if(
    style(--status: pending): #eff7fa;
    style(--status: complete): #f6fff6;
    else: #f7f7f7
  );
}

このパターンでは、 データ属性を変更する HTML では、追加の CSS やクラスを切り替える JS に触れることなく、複数のプロパティを変更します。

Elseと評価順序: if()の考え方

条件が評価される 出現順に最初のtrueが値を返し、評価は終了します。いずれの条件も満たさなかった場合、結果は 無効保証これにより、外部フォールバック(以前の値のカスケードやブラウザのデフォルト値など)が可能になります。

配置することもできます 真ん中の デバッグするには: 最初の条件が機能していないかどうかを確認したい場合は、たとえば「デバッグ」イメージなどを返す else を配置します。 問題を視覚化する 明らかに。

if() のないブラウザのフォールバック

if() は魔法のように自動劣化を引き起こすわけではありません。 予約値が必要です最初にクロスブラウザセーフなステートメントを配置し、次にサポートされている場合はそれをオーバーライドする if() バージョンを配置します。 推奨パターンです.

.box {
  padding: 16px; /* Fallback para navegadores sin if() */
  padding: if(
    style(--size: "2xl"): 24px;
    else: 16px
  );
}

したがって、if() のないブラウザは最初の行を使用し、それをサポートするブラウザは2行目を評価し、 交換します.

互換性と現在の状態

プログラミング

提供された最新の情報によると、 Chrome 137ではif()のテストが可能になった Edgeの同等バージョンはサポートを継承しています。他の情報源によると、Chromium以外では実装が まだ普及していない この提案はW3Cで成熟し続けるため、維持することが推奨されます。 現実的な期待.

いくつかの推定では、 約47%のカバー率 現時点では(最初のリリース時点では)環境を制御できる場合、または 代替戦略 固体の場合は、段階的に層状に塗布するか、制御された環境で塗布します。

@media、@supports、@containerとの関係

if()とatルールは相互に排他的ではなく補完的です。@mediaまたは@supportsは、 完全なルールセットを適用する 複数のプロパティ/セレクターに渡る。if() は、 単一の価値についての正確な決定ロジックをプロパティに関連付けておくことで、メンテナンスが容易になります。

コンポーネント指向設計では、 @容器 (コンテナレイアウトに対応するため) style() を使用した if() (コンポーネント自体の特定のプロパティを変更する)非常に強力なフローを開き、 冗長性が少ない.

@when と @else の提案

if()に加えて、次のような提案もあります。 @when / @else ルールレベルで条件文を課すもので、 複雑な条件をよりよく読み取る @media と @supports が連鎖すると、保守が難しくなります。

@when media(width <= 600px) {
  .container { display: flex; flex-direction: column; }
}
@else {
  .container { display: flex; flex-direction: row; }
}

あなたは組み合わせることができます そして、または、そうではない グループ化には括弧を使用します。単純なケースでは@mediaで十分ですが、より複雑な組み合わせでは @when/@else の読みやすさが向上.

@when media(width <= 600px) and supports(display: grid) {
  /* ... */
}
@else media(width >= 600px) and supports(display: flex) {
  /* ... */
}
@else {
  /* Fallback final */
}

これらのルールはまだ進化しており、実際の導入には時間がかかるかもしれないが、 拡張条件を簡素化する スタイルシートレベルで。

パターン、制限、ヒント

  • 枝をきちんと整える 確率と明瞭性を重視します。最初に正しいものが優先されるため、パフォーマンスと読みやすさを考慮して並べ替えてください。
  • 使用 そうでなければ最終 デフォルト値として設定します。これを進めると、 評価を短縮する 残りの条件について。
  • if() が決定することを覚えておいてください 一度に1つの物件一度に多くのものを変更する必要がある場合は、@media/@supports を使用するか、複数のステートメントに分割することを検討してください。
  • デバッグ間にelse文を追加し、明るい色または警告画像を表示しましょう。どのブランチが失敗しているかがすぐにわかります。
  • と組み合わせる カスタムプロパティ HTML(データ属性)または他のセレクターから状態をエクスポートし、JSなしで値を決定します。
  • 非常に長い条件文の連鎖を乱用するのは避けてください。読みにくくなったら、 ロジックを抽出する 別の場所へ。

「いつもの」との比較

以前: base + @media/@supports の書き換え。現在: if() インターリーブ ロジックを分割することなく、CSSを減らし、宣言のローカルな一貫性を高めます。 メンテナンスに勝つ.

以前: クラスまたは状態を切り替える JS、現在: カスタムプロパティ + スタイル() プロパティを決定する。if() を使うと、 命令型コード シンプルな視覚的バリエーションを実現します。

実装ノートと将来の組み合わせ

if() の登場は、言語の進化の他の流れと一致しています。 スタイルクエリ アラカルト可能 範囲クエリ 未来に統合され、 @関数 カスタム関数のためのものです。これらを組み合わせることで、より 宣言的かつ構成可能.

今のところ、利用可能な3つのテストに焦点を当てます(スタイル(), 平均(), サポート())してフォールバック戦略を強化しましょう。Chrome 137では、 試作と測定 コードベースへの実際の影響。

「CSSの条件文」というアイデアは、単なる希望的観測から、ニュアンスの違いはあるものの、互換性のある環境で使用できる具体的なツールへと変化しました。if()を使うことで、スタイルは インターリーブロジック、繰り返しの削減、カプセル化の向上、カスタム変数、データ属性、メディアクエリと完璧に連携します。まだ広くサポートされていませんが、プログレッシブパターンを採用し、フォールバックに備えることで、インターフェースの設計方法に近いCSSの考え方を今すぐ活用できるようになります。 適切な場所で適切な決定を下す.