Статьи

Будущее поколение селекторов CSS: уровень 4

Еще в январе 2014 года я написал статью «Текущее поколение селекторов CSS3» . Целью этой статьи было представить новое поколение селекторов, которые часто попадают под зонтик «CSS3». Группа селекторов Thabet хорошо документирована во многих местах, и поддержка этих функций в браузерах достаточно сильна (все браузеры, включая IE9 +).

Будущее CSS-селекторов также выглядит блестящим, поскольку спецификация Selectors Level 4 в настоящее время находится в рабочем состоянии, а черновик редактора той же спецификации все еще находится в стадии разработки (черновик редактора обычно рассматривается как более авторитетный).

Эта статья будет посвящена новым селекторам, которые не обсуждались в моей предыдущей статье. Браузерная поддержка многих из них довольно слабая, поэтому я не рекомендую использовать многие из них в производстве. Посмотрите на этот пост как на обзор того, что произойдет, когда спецификация будет продолжена, и браузеры начнут свои реализации. Я включил демонстрации для тех, у кого есть поддержка.

:read-only :read-write и :read-write

Эти селекторы довольно просты. Любой элемент, редактируемый пользователем, находится в состоянии «чтение-запись». В противном случае элемент находится в состоянии «только для чтения».

Возьмите следующий HTML:

 <input type="text" readonly> <input type="text" disabled> <input type="text"> <div contenteditable></div> 

Теперь рассмотрим этот CSS:

 :read-only { outline: solid 1px blue; } :read-write { outline: solid 1px red; } 

Вот разбивка того, что этот CSS делает по отношению к HTML:

  • Первые два элемента будут выделены синим контуром, потому что они установлены на «только чтение» и «отключены» в HTML, соответственно.
  • Третий элемент будет иметь красный контур, потому что он естественно редактируемый («чтение-запись»), как и все входы по умолчанию. textarea будет такой же.
  • Последний элемент ( div ) будет иметь красный контур из-за атрибута contenteditable .

В CSS я использую эти селекторы повсеместно (т.е. без применения их к каким-либо элементам). Это означает, что красный контур будет применен ко всем элементам div, span и другим естественно не редактируемым элементам. Более вероятно, что это будет использоваться на определенных элементах формы или элементах с примененным классом, чтобы быть более определенным.

Псевдокласс :read-write указан в черновике редактора как «подверженный риску», поэтому его можно удалить.

Поддержка браузера для: только для чтения и: для чтения и записи
Chrome, Opera, Firefox, Safari.

Примечание. Как показано в демонстрационном примере ниже, браузеры, которые поддерживают эти селекторы, определяют «отключенный» ввод как «чтение-запись», что является неправильным, согласно спецификации.

Псевдокласс по умолчанию :default

Псевдокласс: default соответствует элементам, которые квалифицируются как «default» по отношению к набору, частью которого они являются. Например, элемент button который является кнопкой отправки по умолчанию для формы или выбранным по умолчанию элементом в наборе переключателей.

Вы также можете иметь несколько значений по умолчанию для одной группы, как показано в следующем фрагменте HTML:

 <input type="checkbox" value ="f" name="group" checked> Fruits <input type="checkbox" value ="v" name="group"> Vegetables <input type="checkbox" value ="m" name="group" checked> Meats <input type="checkbox" value ="p" name="group" checked> Poultry <input type="checkbox" value ="n" name="group"> Nuts <input type="checkbox" value ="b" name="group"> Breads 

Теперь давайте соединим HTML выше со следующим CSS:

 input[type=checkbox]:default { outline: solid 1px hotpink; } 

В этом случае все элементы с атрибутом selected будут оформлены с помощью контура.

Поддержка браузера для: по умолчанию
Chrome, Opera, Firefox, Safari.

Как показано в демонстрации, браузеры WebKit / Blink не применяют схему к флажкам «по умолчанию», даже если они должны . Это похоже на ошибку. Firefox имеет правильное поведение.

Псевдоклассы валидности :valid и :invalid

Эти псевдоклассы полезны в формах HTML для предоставления визуальных подсказок относительно достоверности данных, введенных пользователем, что обычно делается с помощью JavaScript.

Например, если ваша форма имеет следующее поле:

 Email: <input type="email" required> 

Обратите внимание, что поле ожидает, что введенные данные будут действительным адресом электронной почты. Затем вы можете сделать следующее:

 input[type=email]:invalid { outline: red solid 1px; } input[type=email]:valid { outline: lightgreen solid 1px; } 

При использовании вышеуказанного CSS поле электронной почты будет выделено красным контуром еще до того, как пользователь что-либо введет. Как только пользователь введет действительный адрес электронной почты, контур станет зеленым.

С помощью этих псевдоклассов вы можете легко добавить псевдоэлемент в виде зеленой галочки (или чего-то подобного), чтобы указать действительные данные поля.

Некоторые примечания по этим селекторам:

  • Интересно, что валидность также может применяться к самому элементу формы, указывая, все ли поля являются действительными.
  • Они не работают с общими элементами, такими как div или p потому что эти элементы не имеют никакого способа указать ожидаемые форматы данных.
  • Обычный «текстовый» тип ввода, который не требует определенного формата, является «допустимым» по умолчанию, но будет «недействительным» без данных, если у него установлен required атрибут.

Браузерная поддержка для: действительный и: недействительный
Все браузеры, включая IE10 +.

Псевдоклассы диапазона :in-range и :out-of-range

Эти два псевдокласса полезны для элементов формы, которые допускают данные, попадающие в указанный диапазон. Вы можете стилизовать указанный ввод в зависимости от того, находится ли элемент в допустимом диапазоне.

Таким образом, ваш HTML будет выглядеть примерно так:

 <input type="date" min="1994-01-01" max="2015-03-01" value="1993-01-01"> 

Обратите внимание на значение по умолчанию «1993-01-01», которое находится за пределами допустимого диапазона дат. Затем вы можете стилизовать ввод динамически, основываясь на данных по умолчанию или любых введенных данных, что-то вроде этого:

 input[type=date]:in-range { outline: lightgreen solid 1px; } input[type=date]:out-of-range { outline: red solid 1px; } 

Некоторые примечания по этим селекторам:

  • Они могут использоваться для number , datetime , datetime-local , month , week и любых других типов ввода, которые допускают диапазоны.
  • Технически они также работают с типом ввода range , но я не думаю, что есть способ сделать такой элемент «вне диапазона», поэтому полезность в этом случае кажется ограниченной.
  • Как и в случае других псевдоклассов, они будут работать только с элементами, которые могут определять допустимые диапазоны.

Поддержка браузера: в диапазоне и вне диапазона
Opera, Chrome, Firefox, Safari.

Псевдоклассы необязательности :required и :optional

Эти псевдоклассы позволяют стилизовать элементы формы в зависимости от того, требуется ли их заполнять или нет. Возьмите следующий HTML:

 <div> <label for="name">name:</label> <input type="text" id="name" required> <span class="msg"></span> </div> <div> <label for="email">Email:</label> <input type="email" id="email" required> <span class="msg"></span> </div> <div> <label for="address">Address:</label> <input type="text" id="address"> <span class="msg"></span> </div> 

Обратите внимание на пустые элементы span добавленные рядом с каждым входом. Также обратите внимание, что первые два поля обязательны для заполнения, а третье — нет. Имея этот HTML-код, вы можете сделать следующее в своем CSS:

 input:required ~ .msg:after { content: '*'; color: red; } input:optional ~ .msg:after { content: '(optional)'; } 

Здесь я использую общий братский комбинатор, чтобы добавить красную звездочку рядом с каждым обязательным полем, и я добавляю слово «необязательный» в скобках рядом с каждым необязательным полем.

Это использует дополнительные элементы, которые я добавил. Если вы предпочитаете не использовать дополнительные элементы, вы можете либо динамически добавлять их с помощью JavaScript, либо применять стили непосредственно к самому вводу. Но обратите внимание, что вы не можете использовать псевдоэлементы с входами формы, поэтому вам придется применить другой вид стилей в этом случае.

Поддержка браузера для: требуется и: необязательно
Все браузеры.

Нечувствительные к регистру селекторы атрибутов: i

По умолчанию в CSS селекторы атрибутов чувствительны к регистру. Так, например, если вы выберете все элементы со значениями href , оканчивающимися на «pdf», он не выберет значения href , оканчивающиеся на «PDF» (верхний регистр).

Есть полезный новый флаг, который может быть добавлен к селектору атрибута, который отменяет это поведение.

 a[href$="pdf" i] { color: red; } 

Теперь селектор атрибутов будет выбирать все ссылки href указывающие на файлы PDF, независимо от того, записано ли расширение .pdf в нижнем, верхнем или даже смешанном регистре.

Браузер Поддержка нечувствительных к регистру селекторов атрибутов:
Опера (доступна только под флагом; спасибо Шиме Видасу за указание на это).

:blank Псевдокласс

Псевдокласс: blank является своего рода более симпатичным родственником :empty , о котором я говорил в предыдущей статье. С помощью :empty вы можете выбрать элемент, основываясь на том, что в нем нет дочерних элементов, будь то элементы, текстовые узлы или даже пробельные узлы. Так что с :empty , даже если элемент содержит один пробел и больше ничего, он не будет считаться «пустым».

Однако псевдокласс :blank выберет элемент, если у него нет текста и других дочерних элементов, независимо от пробелов. Таким образом, он может содержать пробелы, разрывы строк и т. Д., И все равно будет соответствовать требованиям.

Вот пример HTML:

 <p></p> <p> </p> 

Обратите внимание, что первый элемент абзаца полностью пуст, но у второго есть один пробел. Вот CSS:

 p:blank { outline: solid 1px red; } p:empty { border: solid 1px green; } 

В этом случае я применяю красный контур для «пустых» элементов и зеленую рамку для «пустых» элементов. Псевдокласс :empty выберет только первый элемент, потому что он полностью пуст. Но псевдокласс :blank будет применяться к обоим, потому что они оба «пустые» по отношению к тексту и элементам.

Может быть трудно вспомнить разницу, потому что названия звучат слишком похоже, и это то, что отмечено в проблеме в спецификации . Так что вполне возможно, что этот селектор изменит имена. Как также указывает спецификация, существует эквивалентная версия этого селектора только для Mozilla .

Поддержка браузера: пусто
Никто.

Matches-any Псевдо-класс :matches()

Псевдокласс: match () — это способ сделать группу селекторов более лаконичной и должен быть полезным дополнением к спецификации, когда улучшается поддержка браузера.

В примере, взятом из MDN , у вас может быть следующий слишком многословный CSS, который пытается иметь дело со стилем для основных заголовков, которые вложены в различные контексты:

 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; } 

С помощью :matches() это можно упростить до:

 :matches(section, article, aside, nav) :matches(section, article, aside, nav) h1 { font-size: 20px; } 

Упрощенная версия может быть интерпретирована как: «Если h1 находится внутри любого из этих четырех элементов, который, в свою очередь, находится внутри любого из тех же четырех элементов, сделайте следующее».

Примечания :matches() :

  • Раньше это было :any в спецификации, поддерживаемое с -moz- и -webkit- .
  • Как указывают CSS-хитрости , принцип здесь аналогичен вложенности селекторов в препроцессорах.
  • Аргумент селектора должен быть «простым селектором» (т. Е. Он не может быть псевдоэлементом и не может использовать комбинатор, кроме потомка).

Поддержка браузера: match ()
Однако ни один, ни WebKit / Blink, ни Mozilla не имеют своих собственных эквивалентов от поставщиков.

Реляционный псевдокласс:: :has()

Псевдокласс: has похож на jasu .has (), но обладает более широкими возможностями. Примеры прояснят, что возможно. Обратите внимание на комментарии в коде, которые объясняют, что выбирает каждый пример:

 /* Section elements that contain a footer */ section:has(footer) { background: #ccc; } /* Any element containing ap element with a class of "alert" */ :has(p.alert) { background-color: red; } /* img element with paragraph immediately following. */ img:has(+p) { color: red; } /* list item with ul as a direct child */ li:has(> ul) { color: red; } 

Как видите, имя «имеет» — это не просто другое слово «содержит» (именно так работает метод jQuery); это также может означать «имеет непосредственного потомка», «имеет указанный элемент после него» и т. д.

Примечание :has псевдокласс :has находится в черновике редактора, но не в рабочем черновике. Кроме того, как отметил Ральф в комментариях, этот селектор может быть доступен только в JavaScript (вроде как querySelectorAll ), но не в CSS. См. Динамические и статические профили селектора в спецификации.

Поддержка браузера для: has ()
Никто.

Этот селектор работает как ярлык для стилизации любого элемента, который может принимать атрибут href . Это включает a себя элементы, area и link . Он также может быть использован в качестве общего ярлыка для следующего:

 :link, :visited { color: #555; } 

Поэтому вместо вышесказанного вы бы написали:

 :any-link { color: #555; } 

Но, как уже упоминалось, это будет охватывать и другие элементы, а не только якоря ( a ), поэтому полезность этого селектора может быть трудно различить.

Следует отметить, что рабочий проект имел селектор под названием :local-link , который был удален в редакторе.

Поддержка браузера: любая ссылка
Chrome, Opera и Firefox (с префиксами поставщиков; спасибо Selen в комментариях за указание на это).

Псевдокласс обобщенного ввода фокуса :focus-within

Это интересный, который я определенно вижу полезным. Псевдокласс: focus-внутри выберет не только элемент, к которому обычно применяется :focus , но и родительский элемент.

Вот пример HTML:

 <div class="outer"> <label for="email">Email:</label> <input type="email" id="email"> </div> 

С этим вы можете написать следующий CSS:

 :focus-within { outline: yellow solid 1px; } 

Это приведет к тому, что желтый контур будет применяться не только к сфокусированному вводу, но и к родительскому элементу div , потому что они оба соответствуют состоянию focus-within . Спецификация также указывает, что это будет работать так же внутри элементов «теневого дерева», применяя стили к «элементу хоста».

Поддержка браузера для: focus-inside
Никто.

Псевдо-класс :drop и :drop()

Теперь, когда функциональность перетаскивания так распространена в приложениях, эти селекторы могут оказаться полезными для улучшения взаимодействия с пользователем.

Селектор :drop позволяет стилизовать зону перетаскивания (место, где элемент должен быть отброшен), в то время, когда пользователь перетаскивает (или переносит) элемент, который должен быть отброшен.

 .spot { background: #ccc; } .spot:drop { background: hotpink; } 

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

Синтаксис alternate :drop() принимает одно или несколько из следующих значений ключевых слов:

  • active : указывает текущую цель удаления для перетаскиваемого элемента.
  • valid : указывает, является ли цель удаления действительной по отношению к перетаскиваемому элементу (например, если цель принимает только файлы, другие элементы не будут действительными)
  • invalid : в противоположность предыдущему, позволяет стилизовать объект перетаскивания, если он недопустим по отношению к перетаскиваемому элементу.

Можно использовать несколько ключевых слов, чтобы сделать вещи более конкретными, и если аргумент не указан, он будет действовать как :drop , так что нет смысла использовать скобки, если вы не планируете указать аргумент.

Важные заметки:

  • Версия спецификации в рабочем проекте имела совершенно другой набор псевдоклассов, поэтому они все еще находятся в движении.
  • Синтаксис drop() находится под угрозой, поэтому его можно удалить.

Поддержка браузера для: drop и: drop ()
Никто.

Похвальные грамоты

В дополнение к рассмотренным выше, есть некоторые другие новые функции, о которых я не буду вдаваться в подробности, но которые стоит кратко упомянуть:

  • Комбинатор столбцов ( || ), для определения отношений между ячейками и столбцами в таблицах и сетках.
  • Псевдоклассы :nth-column() и :nth-last-column() для таргетинга на конкретные столбцы таблиц и сеток.
  • Селектор узла атрибута attr() , который является первым неэлементным селектором .
  • Альтернативная версия комбинатора-потомка, представленная >> (вместо просто пробела)
  • Псевдокласс :user-error для стилизации входных данных, в которых введены неверные данные.
  • Пространства имен, определенные с помощью @namespace at-rule.
  • Псевдокласс :dir() , который позволяет выбирать элементы в зависимости от их направленности (например, ltr ).
  • Псевдокласс :scope , который предоставляет область или опорную точку для выбора элементов.
  • Размерно-временные :current :past и :future псевдоклассы для нацеливания на элементы во время временной шкалы, такие как субтитры в видео.
  • :placeholder-shown псевдокласс для стилизации текста заполнителя в элементах формы.

Заключительные замечания и дополнительная информация

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

Чтобы не отставать от прогресса, вот некоторые ресурсы по селекторам уровня 4:

Если вы заметили какие-либо ошибки или ошибки, укажите их в комментариях.