СправошнаяПоиск

:is() (:matches(), :any())

Функция псевдокласса CSS принимает в качестве аргумента список селекторов и выбирает любой элемент, который может быть выбран одним из селекторов в этом списке. Это полезно для написания больших селекторов в более компактной форме.:is()

 

/* Выбирает любой абзац внутри элемента header, main или footer, на который наводится курсор. */
:is(header, main, footer) p:hover {
  color: red;
  cursor: pointer;
}
/* Запись вше эквивалентна этой */
header p:hover,
main p:hover,
footer p:hover {
  color: red;
  cursor: pointer;
}

 

Псевдоэлементы недопустимы в списке селекторов для :is().

Обратите внимание, что старые браузеры поддерживают эту функциональность как :matches()или через более старый псевдокласс с префиксом — :any(), включая более старые версии Chrome, Firefox и Safari. :any()работает точно так же, как :matches()/ :is(), за исключением того, что он требует префиксов поставщиков и не поддерживает сложные селекторы.

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

 

/* Версия с обратной совместимостью с :-*-any() и :matches() (невозможно сгруппировать селекторы в одно правило, поскольку наличие недопустимого селектора сделает недействительным все правило.) */
:-webkit-any(header, main, footer) p:hover {
  color: red;
  cursor: pointer;
}
:-moz-any(header, main, footer) p:hover {
  color: red;
  cursor: pointer;
}
:matches(header, main, footer) p:hover {
  color: red;
  cursor: pointer;
}

 

Разница между :is() и :where()

Разница между ними заключается в том, что :is()учитывается специфичность общего селектора (он принимает специфичность своего наиболее конкретного аргумента), тогда как у :where() значение специфичности равно 0. Это продемонстрировано в примере на :where().

Прощающий разбор селектора

Спецификация определяет :is()и :where()как допускающий прощающий список селекторов.

В CSS при использовании списка селекторов, если какой-либо из селекторов недействителен, весь список считается недействительным. При использовании :is() или :where() вместо того, чтобы весь список селекторов считался недействительным, если один из них не может быть проанализирован, неправильный или неподдерживаемый селектор будет проигнорирован, а другие будут использоваться.

 

:is(:valid, :unsupported) {
  ...
}

 

Будет по-прежнему корректно анализироваться и сопоставляться :valid даже в браузерах, которые не поддерживают :unsupported, тогда как:

 

:valid, :unsupported {
  ...
}

 

Будет игнорироваться в браузерах, которые не поддерживают :unsupported, даже если они поддерживают файлы :valid.

Кроссбраузерный пример

 

<header>
  <p>This is my header paragraph</p>
</header>
<main>
  <ul>
    <li><p>This is my first</p><p>list item</p></li>
    <li><p>This is my second</p><p>list item</p></li>
  </ul>
</main>
<footer>
  <p>This is my footer paragraph</p>
</footer>

 

:-webkit-any(header, main, footer) p:hover {
  color: red;
  cursor: pointer;
}
:-moz-any(header, main, footer) p:hover {
  color: red;
  cursor: pointer;
}
:matches(header, main, footer) p:hover {
  color: red;
  cursor: pointer;
}
:is(header, main, footer) p:hover {
  color: red;
  cursor: pointer;
}

 

let matchedItems;
try {
  matchedItems = document.querySelectorAll(':is(header, main, footer) p');
} catch(e) {
  try {
    matchedItems = document.querySelectorAll(':matches(header, main, footer) p');
  } catch(e) {
    try {
      matchedItems = document.querySelectorAll(':-webkit-any(header, main, footer) p');
    } catch(e) {
      try {
        matchedItems = document.querySelectorAll(':-moz-any(header, main, footer) p');
      } catch(e) {
        console.log('Your browser doesn\'t support :is(), :matches(), or :any()');
      }
    }
  }
}
matchedItems.forEach(applyHandler);
function applyHandler(elem) {
  elem.addEventListener('click', function(e) {
    alert('This paragraph is inside a ' + e.target.parentNode.nodeName);
  });
}

 

Упрощение селекторов списка

Псевдокласс :is()может значительно упростить ваши селекторы CSS. Например, следующий CSS:

 

/* 3-deep (or more) unordered lists use a square */
ol ol ul,     ol ul ul,     ol menu ul,     ol dir ul,
ol ol menu,   ol ul menu,   ol menu menu,   ol dir menu,
ol ol dir,    ol ul dir,    ol menu dir,    ol dir dir,
ul ol ul,     ul ul ul,     ul menu ul,     ul dir ul,
ul ol menu,   ul ul menu,   ul menu menu,   ul dir menu,
ul ol dir,    ul ul dir,    ul menu dir,    ul dir dir,
menu ol ul,   menu ul ul,   menu menu ul,   menu dir ul,
menu ol menu, menu ul menu, menu menu menu, menu dir menu,
menu ol dir,  menu ul dir,  menu menu dir,  menu dir dir,
dir ol ul,    dir ul ul,    dir menu ul,    dir dir ul,
dir ol menu,  dir ul menu,  dir menu menu,  dir dir menu,
dir ol dir,   dir ul dir,   dir menu dir,   dir dir dir {
  list-style-type: square;
}

 

... можно заменить на:

 

/* 3-deep (or more) unordered lists use a square */
:is(ol, ul, menu, dir) :is(ol, ul, menu, dir) :is(ul, menu, dir) {
  list-style-type: square;
}

 

Упрощение селекторов разделов

Псевдокласс :is() особенно полезен при работе с разделами и заголовками HTML5 . Так как <section>, <article>, <aside> и <nav> обычно вложены друг в друга, без :is(), стилизовать их так, чтобы они соответствовали друг другу, может быть сложно.

Например, без :is()стилизации всех <h1> элементов на разной глубине было бы очень сложно:

 

/* Level 0 */
h1 {
  font-size: 30px;
}
/* Level 1 */
section h1, article h1, aside h1, nav h1 {
  font-size: 25px;
}
/* Level 2 */
section section h1, section article h1, section aside h1, section nav h1,
article section h1, article article h1, article aside h1, article nav h1,
aside section h1, aside article h1, aside aside h1, aside nav h1,
nav section h1, nav article h1, nav aside h1, nav nav h1 {
  font-size: 20px;
}
/* Level 3 */
/* ... don't even think about it! */

 

Однако с помощью :is()это намного проще:

 

/* Level 0 */
h1 {
  font-size: 30px;
}
/* Level 1 */
:is(section, article, aside, nav) h1 {
  font-size: 25px;
}
/* Level 2 */
:is(section, article, aside, nav)
:is(section, article, aside, nav) h1 {
  font-size: 20px;
}
/* Level 3 */
:is(section, article, aside, nav)
:is(section, article, aside, nav)
:is(section, article, aside, nav) h1 {
  font-size: 15px;
}

 

:is() не выбирает псевдоэлементы

псевдокласс :is() не работает с псевдоэлементам . Итак, вместо этого:

 

some-element:is(::before, ::after) {
  display: block;
}

 

сделайте:

 

some-element::before,
some-element::after {
  display: block;
}

 

Синтаксис

 

:is( <forgiving-selector-list> )