Spec-Zone.ru › CSS

CSS-функция `if()`

Базовая доступность Ограниченная доступность

Эта функция не относится к Baseline, поскольку не работает в некоторых наиболее широко используемых браузерах.

Экспериментальная: Это экспериментальная технология
Перед использованием в production внимательно изучите таблицу совместимости с браузерами.

Экспериментальная: Это экспериментальная технология
Перед использованием в production внимательно изучите таблицу совместимости с браузерами.

if() CSS функция позволяет задавать для свойства различные значения в зависимости от результата условной проверки. Проверка может основываться на запросе стилей, медиазапросе или запросе поддержки функций.

Синтаксис

/* Single <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> with 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;
)

/* Multiple <if-test>s */
if(
  style(--scheme: ice): linear-gradient(#caf0f8, white, #caf0f8);
  style(--scheme: fire): linear-gradient(#ffc971, white, #ffc971);
  else: none;
)

/* <if-test> within a shorthand */
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>;
<if-condition>
<if-test> или ключевое слово else.
<if-test>
запрос стилей, медиазапрос или запрос поддержки функций.
else
Ключевое слово, обозначающее <if-condition>, результатом которого всегда является true.
<value>
Значение свойства.

Возвращаемое значение

Значение или гарантированно недопустимое значение.

Описание

Функция CSS if() добавляет условную логику к значениям свойств CSS и работает аналогично инструкциям JavaScript if...else.

Функцию if() можно использовать внутри значения любого свойства; она может содержать ноль или более значений <if-condition>, разделённых точкой с запятой. Каждое <if-condition> — это либо пара <if-test> : <value>, либо пара else : <value>. Точка с запятой после последнего <if-condition> необязательна.

Возвращаемое значение вычисляется следующим образом:

  1. Выражения <if-condition> вычисляются в порядке их появления в функции.
  2. Возвращается значение <value>, связанное с первым <if-condition>, результатом которого является true.
  3. Если результатом ни одного <if-condition> не является true, функция возвращает <guaranteed-invalid&gt:. Если функция if() используется в значении, для которого предусмотрено резервное значение, например в пользовательском свойстве или функции anchor(), это значение ведёт себя как недопустимое или false.

Например:

div {
  background-image: if(
    style(--scheme: ice): linear-gradient(#caf0f8, white, #caf0f8);
    style(--scheme: fire): linear-gradient(#ffc971, white, #ffc971);
    else: none;
  );
}

В этом примере для элементов <div> мы задаём различные linear-gradient() в качестве background-image в зависимости от того, установлено ли пользовательское свойство --scheme в значение ice или fire. Если --scheme не существует или ему присвоено любое другое значение, используется значение else, а свойству background-image присваивается значение none.

Примечание: Каждое условие необходимо отделять от соответствующего значения двоеточием, а каждую пару <if-condition> : <value> — точкой с запятой. Для последней пары <if-condition> : <value> точка с запятой необязательна.

Предупреждение: Между if и открывающей скобкой (() не должно быть пробела. В противном случае всё объявление будет недопустимым.

Если одно <if-condition> или <value> недопустимо, это не делает всю функцию if() недопустимой; вместо этого анализатор переходит к следующей паре <if-condition> : <value>. Если недопустимы все <if-condition> и <value>, функция возвращает гарантированно недопустимое значение.

Частота и положение пар else : <value>

В функцию if() можно включить несколько пар else : <value> в любом месте. Однако чаще всего одну пару else : <value> помещают в конец списка, разделённого точками с запятой, чтобы задать значение по умолчанию, которое возвращается, если ни одно из <if-test> не даёт результат true.

Если включить пару else : <value> перед любыми парами <if-test> : <value>, следующие за ней условия не будут проверяться, поскольку else всегда даёт результат true. Поэтому следующий if() всегда возвращает none, а две пары <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>. Последние две пары <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

<if-test> может принимать один из трёх типов запросов. В этом разделе каждый из них рассматривается подробно.

Запросы стилей

Запрос стилей <if-test> позволяет проверить, задано ли для элемента определённое значение свойства, и в зависимости от результата применить значение к другому свойству. Ранее мы рассмотрели несколько примеров запросов стилей; рассмотрим ещё один:

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() можно задавать только отдельные значения свойств, тогда как запросы @container позволяют условно применять целые наборы правил. Эти подходы дополняют друг друга и подходят для разных задач.

Обратите внимание, что в настоящее время запросы стилей контейнера не поддерживают обычные свойства 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;
)

Можно также использовать медиахарактеристики — следующий пример возвращает значение 0 auto, если ширина текущей области просмотра меньше 700px, и 20px auto в противном случае:

margin: if(
  media(width < 700px): 0 auto;
  else: 20px auto;
)

Это очень удобно, когда нужно изменить значение одного свойства в зависимости от результата медиазапроса.

В медиазапросах также можно использовать логику 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
);

Если на основе одного медиазапроса нужно задать несколько объявлений или правил, потребуется обычная конструкция @media. Эти подходы дополняют друг друга и подходят для разных задач.

Запросы поддержки функций

Запрос поддержки функций <if-test> можно использовать для задания значения свойства в зависимости от того, поддерживает ли браузер определённое значение свойства.

Например, следующий код возвращает цвет lch(), если поддерживаются цвета lch(), и цвет rgb() в противном случае:

color: if(
  supports(color: lch(75% 0 0)): lch(75% 0 0);
  else: rgb(185 185 185);
)

Работают и запросы поддержки селекторов. Следующий код возвращает значение 1em, если браузер поддерживает псевдокласс :buffering, и 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(), когда нужно изменить значение одного свойства в зависимости от поддержки определённого значения или отдельного свойства. Если на основе одного запроса поддержки функций нужно задать несколько объявлений или правил, лучше использовать обычную конструкцию @supports. Эти подходы дополняют друг друга и подходят для разных задач.

Задание резервных значений

Инструкция if() не обеспечивает корректную деградацию; для браузеров, которые её не поддерживают, нужно явно задать резервное значение.

Например, в этом случае мы задаём статическое значение padding для браузеров, не поддерживающих if(). Браузеры, поддерживающие if(), заменят первое объявление вторым, которое задаёт разные значения отступов в зависимости от того, задано ли пользовательское свойство --size: "2xl".

padding: 1em;
padding: if(style(--size: "2xl"): 1em; else: 0.25em);

Примечание: Не забудьте включить условие else. В браузерах, не поддерживающих if(), если не указать значение else, а --size не равно "2xl", для отступа будет задано значение initial.

Полные и частичные значения

Функцию if() можно задать в качестве значения любого свойства CSS, но с её помощью также можно определять части значений свойств. Например, следующий код задаёт разный border-color внутри сокращённого свойства border в зависимости от того, поддерживаются ли цвета lch():

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 (если ни одно из условий не выполняется, возвращается значение black из конструкции else).

Однако оба <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 значение функции calc(), которая вычитает 50px из процента ширины родительского элемента. Этот процент задаётся функцией if(), проверяющей, установлено ли пользовательское свойство --scheme: wide. Если да, процент равен 70%, поэтому внешняя функция возвращает calc(70% - 50px). Если нет, процент равен 50%, поэтому внешняя функция возвращает calc(50% - 50px).

width: calc(if(
    style(--scheme: wide): 70%;
    else: 50%;
  ) - 50px);

Формальный синтаксис

Примеры

Основы использования if()

В этом примере мы покажем основные способы использования каждого из трёх типов <if-test>.

HTML

В нашем HTML есть элемент <section> с двумя вложенными элементами <article>, содержащими заголовки <h2>. Для элемента <section> в атрибуте style задано пользовательское свойство — --show-apple:true, которое мы позже используем для условного задания значения свойства.

<section style="--show-apple:true">
  <article><h2>First article</h2></article>
  <article><h2>Second article</h2></article>
</section>

CSS

В CSS сначала выбираем элемент <section>, располагаем его с помощью flexbox и задаём gap между двумя дочерними элементами <article>. Затем с помощью функции if() и медиазапроса orientation <if-test> задаём свойству 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;
  )
}

Затем выбираем псевдоэлемент ::before элемента <h2> и задаём его свойству content эмодзи яблока, но только если задано --show-apple: true (ранее мы сделали это с помощью встроенного элемента <style> в HTML). Для этого мы используем функцию if() с запросом стилей <if-test>:

h2::before {
  content: if(
    style(--show-apple: true): "🍎 ";
  );
}

Наконец, выбираем сам элемент <h2>. С помощью запроса поддержки функций <if-test> проверяем, поддерживает ли браузер цвета lch(), и задаём свойству color цвет lch(), если поддерживает, или эквивалентный цвет в шестнадцатеричном формате, если нет.

h2 {
  color: if(
    supports(color: lch(29.57% 43.25 344.44)): lch(29.57% 43.25 344.44);
    else: #792359;
  )
}

Результат

Обратите внимание на то, как применяются стили. Проверьте условную стилизацию для первых двух запросов if(), изменив демонстрационный пример в инструментах разработчика браузера:

  • Удалите атрибут style у элемента <section> и обратите внимание, что эмодзи яблок больше не отображаются.
  • Измените атрибут height встроенного элемента <iframe> на 1200px. Ориентация изменится с альбомной на портретную. Обратите внимание, как вслед за этим меняется расположение элементов.

Управление цветовой схемой с помощью if()

Эта демонстрация показывает, как можно по-настоящему увлекательно использовать функции CSS if(). Среди прочего, мы используем функции if() для условного задания значений некоторых пользовательских свойств, что позволяет управлять всей цветовой схемой!

HTML

В нашем HTML есть элемент <article> с содержимым: заголовком верхнего уровня, несколькими элементами <p> и элементом <aside>. Также добавлена <form> с раскрывающимся списком <select>, позволяющим выбрать цветовую схему.

<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">Choose color scheme:</label>
  <select id="scheme">
    <option value="">Default</option>
    <option value="ice">Ice</option>
    <option value="fire">Fire</option>
  </select>
</form>

JavaScript

Наш JavaScript добавляет обработчик события change для элемента <select>. При выборе нового значения скрипт присваивает атрибуту class элемента <article> это значение.

const articleElem = document.querySelector("article");
const selectElem = document.querySelector("select");

selectElem.addEventListener("change", () => {
  articleElem.className = selectElem.value;
});

CSS

В CSS мы задаём элементу <body> значение max-width, равное 700px, и центрируем его с помощью значений auto для свойства margin. Однако функцией if() и медиазапросом <if-test> мы задаём компоненту margin-top внутри сокращённого свойства margin значение 0, если ширина области просмотра меньше 700px, и 20px, если она больше. Это означает, что на широких экранах над содержимым есть небольшой отступ, а на узких он убирается, поскольку выглядит не очень уместно.

* {
  box-sizing: border-box;
}

html {
  font-family: "Helvetica", "Arial", 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;
}

Затем мы задаём пользовательскому свойству --scheme значение, совпадающее с названием <article> элемента class. Наш JavaScript задаст класс, когда в элементе <select> будет выбрано новое значение. Значение пользовательского свойства станет важным в следующем блоке CSS.

.ice {
  --scheme: ice;
}

.fire {
  --scheme: fire;
}

Настоящая сила функций CSS if() проявляется при использовании вместе с пользовательскими свойствами. Здесь с помощью функций if() мы задаём пользовательским свойствам --color1 и --color2 разные значения цвета в зависимости от значения пользовательского свойства --scheme. Затем мы используем значения --color1 и --color2 в свойствах color, border и background-image элемента <article>, а также в свойствах color и background-color элемента <aside>.

Мы управляем всей цветовой схемой с помощью пользовательских свойств, значения которых задаются функциями 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() ещё в нескольких местах:

  • Для свойства font-size элемента <h1> задаём значение calc(3rem + 2vw), если ширина области просмотра больше 700px, и 3rem в противном случае. Это позволяет размеру шрифта динамически меняться при изменении ширины области просмотра на широких экранах, оставаясь неизменным на узких.
  • В зависимости от значения пользовательского свойства --scheme задаём подходящий эмодзи для свойства content псевдокласса ::before элемента <h1>.
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: "";
  );
}

Результат

Эта демонстрация выглядит следующим образом:

Попробуйте выбрать разные значения цветовой схемы и оценить, как они влияют на внешний вид.

Спецификации

Спецификация
Модуль значений и единиц CSS, уровень 5
# if-notation

Совместимость с браузерами

Настольные Мобильные
Chrome Edge Firefox Opera Safari Chrome для Android Firefox для Android Opera для Android Safari для iOS Samsung Internet WebView для Android WebView для iOS
if
137
137
Нет
121
Нет
137
Нет
90
Нет
30.0
137
Нет
style
137
137
Нет
121
Нет
137
Нет
90
Нет
30.0
137
Нет

См. также

  • Запросы стилей контейнера
  • Медиазапросы
  • Запросы поддержки функций
  • Модуль значений и единиц CSS

© 2005–2025 MDN contributors.
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.
https://developer.mozilla.org/en-US/docs/Web/CSS/Reference/Values/if

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API