Czy istnieje selektor CSS według prefiksu klasy?

175

Chcę zastosować regułę CSS do dowolnego elementu, którego jedna z klas pasuje do określonego prefiksu.

Np. Chcę regułę, która będzie miała zastosowanie do div, którego klasa zaczyna się od status-(A i C, ale nie B w następującym fragmencie):

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

Jakaś kombinacja:
div[class|=status]idiv[class~=status-]

Czy jest to wykonalne w CSS 2.1? Czy jest to możliwe w ramach dowolnej specyfikacji CSS?

Uwaga: wiem, że mogę użyć jQuery, aby to emulować.

THX-1138
źródło

Odpowiedzi:

373

Nie da się tego zrobić w CSS2.1, ale jest to możliwe dzięki selektorom dopasowania podciągów atrybutów CSS3 (które obsługiwane w IE7 +):

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

Zwróć uwagę na spację w drugim selektorze atrybutu. Spowoduje to pobranie divelementów, których classatrybut spełnia jeden z następujących warunków:

  • [class^="status-"] - zaczyna się od „status-”

  • [class*=" status-"]- zawiera podciąg „status-” występujący bezpośrednio po znaku spacji. Nazwy klas są oddzielane spacjami zgodnie ze specyfikacją HTML , stąd znaczący znak spacji. To sprawdza wszystkie inne klasy po pierwszej, jeśli określono wiele klas, i dodaje premię polegającą na sprawdzeniu pierwszej klasy w przypadku, gdy wartość atrybutu jest dopełniona spacjami (co może się zdarzyć w przypadku niektórych aplikacji, które generują classatrybuty dynamicznie).

Oczywiście działa to również w jQuery, jak pokazano tutaj .

Powodem, dla którego musisz połączyć dwa selektory atrybutów, jak opisano powyżej, jest to, że selektor atrybutu, taki jak, [class*="status-"]będzie pasował do następującego elementu, co może być niepożądane:

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

Jeśli możesz zapewnić, że taki scenariusz nigdy się nie wydarzy, możesz skorzystać z takiego selektora ze względu na prostotę. Jednak powyższa kombinacja jest znacznie bardziej niezawodna.

Jeśli masz kontrolę nad źródłem HTML lub aplikacją generującą znaczniki, prościej może być po prostu uczynić status-prefiks własną statusklasą zamiast, jak sugeruje Gumbo .

BoltClock
źródło
1
Jeśli z jakiegoś dziwnego powodu masz wywołaną klasę status-i nie chcesz jej dopasowywać, selektor staje się jeszcze bardziej skomplikowany: dodatkowo div[class^="status-"]:not(.status-), div[class*=" status-"]:not(.status-)tracisz obsługę IE7 / IE8. Na szczęście, jeśli Twój znacznik jest rozsądny, nie będziesz musiał wykluczać takiej klasy.
BoltClock
Co jest złego w tym: [class*=" anim-overlay-"] a:hover:after{...}. Kim są klasy CSS anim-overlay-1, anim-overlay-2.....anim-overlay-8
MB Parvez Rony
2
@WebDevRon: Zapomniałeś o części ^ =. Jeśli atrybut klasy ma na pewno zaczynać się od anim-overlay - wtedy prawdopodobnie nie potrzebujesz części * =.
BoltClock
Dziękuję Ci. Inna rzecz, czy mogę tego użyć .anim-overlay-*{...}?
MB Parvez Rony,
2
@Daniel Compton: Dzięki za zmianę. Z perspektywy czasu uświadomiono mi, jak takie słowa mogą być protekcjonalne wobec kogoś, dla kogo coś może nie być tak oczywiste. Wiem, że niektórzy ludzie naprawdę nie doceniają tego rodzaju zmian, więc odpowiadam głównie po to, żebyś wiedział, że tak.
BoltClock
14

Selektory atrybutów CSS pozwolą Ci sprawdzić atrybuty łańcucha. (w tym przypadku - nazwa klasy)

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

(wygląda na to, że ma status „rekomendacja” dla wersji 2.1 i 3)


Oto zarys tego, jak * myślę, że to działa:

  • [ ]: to kontener dla złożonych selektorów, jeśli chcesz ...
  • class: „klasa” to atrybut, na który patrzysz w tym przypadku.
  • * : modyfikator (jeśli istnieje): w tym przypadku - „symbol wieloznaczny” oznacza, że ​​szukasz DOWOLNEGO dopasowania.
  • test- : wartość (zakładając, że istnieje jeden) atrybutu - który zawiera ciąg „test-” (który może być cokolwiek)

Na przykład:

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

Możesz być bardziej szczegółowy, jeśli masz dobry powód, także z elementem

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

Próbowałem znaleźć skrajne przypadki, ale nie widzę potrzeby używania kombinacji ^i *- jak * dostaje wszystko ...

przykład: http://codepen.io/sheriffderek/pen/MaaBwp

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

Wszystko powyżej IE6 z radością będzie posłuszne. :)

zauważ, że:

[class] { ... }

Wybierze wszystko z klasą ...

szeryfderek
źródło
[class*='test-']dopasuje elementy takie jak <div class='foo-test-bar'>. To jedyny skrajny przypadek, który wymaga połączenia ^ i *, jak opisano w mojej odpowiedzi. IE6 nie obsługuje selektorów atrybutów.
BoltClock
@BoltClock - dzięki za wyjaśnienie! - Nie obsługuję <EI9 - i nigdy nie napisałbym żadnych zajęć, które nadepnęłyby na siebie - więc dla mnie to działa. :)
sheriffderek
6

Nie jest to możliwe w przypadku selektorów CSS. Ale możesz użyć dwóch klas zamiast jednej, np. Status i ważne zamiast statusu-ważne .

Gumbo
źródło
14
Dobry pomysł na podzielenie go na własną klasę, ale jest to możliwe za pomocą selektorów CSS. Zobacz moją odpowiedź.
BoltClock
2

Nie możesz tego zrobić, nie. Istnieje jeden selektor atrybutu, który pasuje dokładnie lub częściowo do znaku -, ale nie zadziała tutaj, ponieważ masz wiele atrybutów. Jeśli nazwa klasy, której szukasz, zawsze byłaby pierwsza, możesz to zrobić:

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

Zwróć uwagę, że ma to na celu tylko wskazanie, który selektor atrybutu CSS jest najbliższy. Nie zaleca się zakładania, że ​​nazwy klas zawsze będą na początku, ponieważ javascript może manipulować atrybutem.

SBUJOLD
źródło
2
tak, pomyślałem o tym. Może to stać się problemem, gdy jQuery dostanie się do obrazu, ponieważ może wstawić klasę z przodu.
THX-1138
Tak, edytuję mój post, aby było jasne, że nie jest to zalecany sposób robienia tego. Jeśli masz kontrolę nad nazwami klas, zdecydowanie najlepszym rozwiązaniem byłaby sugestia Gumbo (plus selektory atrybutów w starszych przeglądarkach IE nie są obsługiwane).
SBUJOLD