Есть ли селектор CSS по префиксу класса?

175

Я хочу применить правило CSS к любому элементу, один из классов которого соответствует указанному префиксу.

Например, я хочу правило, которое будет применяться к div, класс которого начинается с status-(A и C, но не B в следующем фрагменте):

<div id='A' class='foo-class status-important bar-class'></div>
<div id='B' class='foo-class bar-class'></div>
<div id='C' class='foo-class status-low-priority bar-class'></div>

Какая-то комбинация:
div[class|=status]иdiv[class~=status-]

Это выполнимо под CSS 2.1? Это выполнимо под любой спецификацией CSS?

Примечание: я знаю, что могу использовать jQuery для эмуляции этого.

THX-1138
источник

Ответы:

373

Это не выполнимо с CSS2.1, но можно с атрибутом CSS3 подстрока сопоставления селекторов (которые будут поддерживаться в IE7 +):

div[class^="status-"], div[class*=" status-"]

Обратите внимание на символ пробела во втором селекторе атрибута. Это выбирает divэлементы, classатрибут которых удовлетворяет одному из следующих условий:

  • [class^="status-"] - начинается с "status-"

  • [class*=" status-"]- содержит подстроку «status-», возникающую непосредственно после пробела. Имена классов разделяются пробелами в соответствии со спецификацией HTML , отсюда и символ пробела. Это проверяет любые другие классы после первого, если указано несколько классов, и добавляет бонус проверки первого класса в случае, если значение атрибута заполнено пробелом (что может случиться с некоторыми приложениями, которые выводят classатрибуты динамически).

Естественно, это также работает в jQuery, как показано здесь .

Причина, по которой вам нужно объединить два селектора атрибута, как описано выше, заключается в том, что селектор атрибута, такой как, [class*="status-"]будет соответствовать следующему элементу, что может быть нежелательно:

<div id='D' class='foo-class foo-status-bar bar-class'></div>

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

Если у вас есть контроль над источником HTML или приложением, генерирующим разметку, может быть проще сделать status-префикс своим собственным statusклассом, как предлагает Gumbo .

BoltClock
источник
1
Если по какой-то странной причине у вас есть класс, который status-вы назвали, и вы не хотите соответствовать этому, селектор становится еще более сложным: div[class^="status-"]:not(.status-), div[class*=" status-"]:not(.status-)плюс вы теряете поддержку IE7 / IE8. К счастью, если ваша разметка нормальная, вам не нужно исключать такой класс.
BoltClock
Что случилось с этим: [class*=" anim-overlay-"] a:hover:after{...}. Мои классы CSS anim-overlay-1, anim-overlay-2.....anim-overlay-8
MB Parvez Rony
2
@WebDevRon: Вы забыли часть ^ =. Если ваш атрибут класса гарантированно начинается с anim-overlay-, то вам, вероятно, не нужна часть * =.
BoltClock
Спасибо. Еще одна вещь, я могу использовать это .anim-overlay-*{...}?
MB Parvez Rony
2
@ Даниэль Комптон: Спасибо за редактирование. Оглядываясь назад, я осознал, что подобные слова могут быть снисходительными для кого-то, для кого что-то может быть не столь очевидным. Я знаю, что некоторые люди действительно не ценят такого рода изменения, поэтому я отвечаю главным образом, чтобы вы знали, что я делаю.
BoltClock
14

Селекторы атрибутов CSS позволят вам проверить атрибуты для строки. (в данном случае - имя класса)

https://developer.mozilla.org/en-US/docs/Web/CSS/Attribute_selectors

(похоже, что он на самом деле находится в состоянии «рекомендации» для 2.1 и 3)


Вот схема того, как я * думаю, что это работает:

  • [ ]: это контейнер для сложных селекторов, если вы ...
  • class: 'class' - это атрибут, который вы смотрите в этом случае.
  • * : модификатор (если есть): в этом случае - «подстановочный знак» означает, что вы ищете ЛЮБОЕ совпадение.
  • test- : значение (при условии, что оно есть) атрибута, содержащего строку «test-» (может быть любым)

Так, например:

[class*='test-'] {
  color: red;
}

Вы можете быть более конкретным, если у вас есть веская причина, с элементом тоже

ul[class*='test-'] > li { ... }

Я пытался найти крайние случаи, но я не вижу необходимости использовать комбинацию ^и *- как * получает все ...

пример: http://codepen.io/sheriffderek/pen/MaaBwp

http://caniuse.com/#feat=css-sel2

Все, что выше IE6, будет счастливым. :)

Обратите внимание, что:

[class] { ... }

Выберу что-нибудь с классом ...

sheriffderek
источник
[class*='test-']будет соответствовать таким элементам, как <div class='foo-test-bar'>. Это один крайний случай, который требует объединения ^ и *, как описано в моем ответе. И IE6 не поддерживает селекторы атрибутов.
BoltClock
@BoltClock - спасибо за разъяснения! - Я не поддерживаю <EI9 - и я бы никогда не написал никаких классов, которые бы наступали друг на друга - так что для меня это работает. :)
sheriffderek
6

Это невозможно с CSS-селекторами. Но вы можете использовать два класса вместо одного, например, статус и важный вместо статуса важный .

гумбо
источник
14
Хорошая идея об отделении его в свой класс, но это возможно с CSS селекторами. Смотри мой ответ.
BoltClock
2

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

<html>
<head>
<title>Test Page</title>
<style type="text/css">
div[class|=status] { background-color:red; }
</style>
</head>
<body>
<div id='A' class='status-important bar-class'>A</div>
<div id='B' class='bar-class'>B</div>
<div id='C' class='status-low-priority bar-class'>C</div>

</body>
</html>

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

SBUJOLD
источник
2
да, подумал об этом. Это может стать проблемой, когда jQuery попадает в картинку, так как он может вставить класс спереди.
THX-1138
Да, я отредактирую свой пост, чтобы было ясно, что это не рекомендуемый способ сделать это. Если у вас есть контроль над именами классов, то предложение Gumbo определенно будет правильным (плюс селекторы атрибутов в старых браузерах IE не поддерживаются).
SBUJOLD