Gibt es einen CSS-Selektor nach Klassenpräfix?

175

Ich möchte eine CSS-Regel auf jedes Element anwenden, dessen eine Klasse dem angegebenen Präfix entspricht.

ZB möchte ich eine Regel, die für div gilt, deren Klasse mit status-(A und C, aber nicht B im folgenden Snippet) beginnt :

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

Eine Kombination aus:
div[class|=status]unddiv[class~=status-]

Ist es unter CSS 2.1 machbar? Ist es unter einer CSS-Spezifikation machbar?

Hinweis: Ich weiß, dass ich jQuery verwenden kann, um dies zu emulieren.

THX-1138
quelle

Antworten:

371

Es ist nicht machbar mit CSS2.1, aber es ist möglich , mit CSS3 Attributstring-matching Selektoren (das ist in IE7 + unterstützt):

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

Beachten Sie das Leerzeichen in der zweiten Attributauswahl. Dies nimmt divElemente auf, deren classAttribut eine der folgenden Bedingungen erfüllt:

  • [class^="status-"] - beginnt mit "status-"

  • [class*=" status-"]- enthält die Teilzeichenfolge "status-", die direkt nach einem Leerzeichen steht. Klassennamen werden gemäß der HTML-Spezifikation durch Leerzeichen getrennt , daher das signifikante Leerzeichen. Dies überprüft alle anderen Klassen nach der ersten, wenn mehrere Klassen angegeben sind, und fügt einen Bonus hinzu, wenn die erste Klasse überprüft wird, falls der Attributwert mit Leerzeichen aufgefüllt ist (was bei einigen Anwendungen vorkommen kann, die classAttribute dynamisch ausgeben ).

Dies funktioniert natürlich auch in jQuery, wie hier gezeigt .

Der Grund, warum Sie zwei Attributselektoren wie oben beschrieben kombinieren müssen, liegt darin, dass ein Attributselektor wie [class*="status-"]der mit dem folgenden Element übereinstimmt, was unerwünscht sein kann:

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

Wenn Sie sicherstellen können, dass ein solches Szenario niemals eintritt, können Sie der Einfachheit halber einen solchen Selektor verwenden. Die obige Kombination ist jedoch viel robuster.

Wenn Sie die Kontrolle über die HTML-Quelle oder die Anwendung haben, die das Markup generiert, ist es möglicherweise einfacher, das status-Präfix statusstattdessen zu einer eigenen Klasse zu machen, wie Gumbo vorschlägt .

BoltClock
quelle
1
Wenn Sie aus irgendeinem seltsamen Grund eine Klasse namens haben status-und diese nicht anpassen möchten, wird die Auswahl noch komplizierter: div[class^="status-"]:not(.status-), div[class*=" status-"]:not(.status-)Außerdem verlieren Sie die IE7 / IE8-Unterstützung. Zum Glück müssen Sie eine solche Klasse nicht ausschließen, wenn Ihr Markup vernünftig ist.
BoltClock
Was ist daran falsch : [class*=" anim-overlay-"] a:hover:after{...}. Meine CSS-Klassen sind anim-overlay-1, anim-overlay-2.....anim-overlay-8
WebDevRon
2
@WebDevRon: Du hast den Teil ^ = vergessen. Wenn Ihr Klassenattribut garantiert mit Anim-Overlay beginnt, benötigen Sie wahrscheinlich nicht den Teil * =.
BoltClock
Danke dir. Kann ich das noch benutzen .anim-overlay-*{...}?
WebDevRon
2
@ Daniel Compton: Danke für die Bearbeitung. Ich bin im Nachhinein darauf aufmerksam gemacht worden, wie solche Worte für jemanden herablassend sein können, für den etwas möglicherweise nicht so offensichtlich ist. Ich weiß, dass einige Leute diese Art von Veränderung wirklich nicht schätzen, deshalb antworte ich hauptsächlich, um Sie wissen zu lassen, dass ich es tue.
BoltClock
14

Mit CSS-Attributselektoren können Sie Attribute für eine Zeichenfolge überprüfen. (in diesem Fall - ein Klassenname)

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

(sieht so aus, als ob es tatsächlich den Empfehlungsstatus für 2.1 und 3 hat)


Hier ist ein Überblick darüber, wie ich denke, dass es funktioniert:

  • [ ]: ist der Container für komplexe Selektoren, wenn Sie so wollen ...
  • class: 'class' ist das Attribut, das Sie in diesem Fall betrachten.
  • * : Modifikator (falls vorhanden): In diesem Fall zeigt "Platzhalter" an, dass Sie nach einer Übereinstimmung suchen.
  • test- : der Wert (vorausgesetzt, es gibt einen) des Attributs - der die Zeichenfolge "test-" enthält (was alles sein kann)

Also zum Beispiel:

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

Sie könnten genauer sein, wenn Sie einen guten Grund haben, auch mit dem Element

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

Ich habe versucht, Randfälle zu finden, aber ich sehe keine Notwendigkeit, eine Kombination von ^und zu verwenden *- da * alles bekommt ...

Beispiel: http://codepen.io/sheriffderek/pen/MaaBwp

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

Alles über IE6 wird gerne gehorchen. :)

beachten Sie, dass:

[class] { ... }

Wählt irgendetwas mit einer Klasse aus ...

Sheriffderek
quelle
[class*='test-']passt zu Elementen wie <div class='foo-test-bar'>. Dies ist der Fall mit einer Kante, bei dem ^ und * kombiniert werden müssen, wie in meiner Antwort beschrieben. Und IE6 unterstützt keine Attributselektoren.
BoltClock
@BoltClock - danke für die Klarstellung! - Ich unterstütze <EI9 nicht - und ich würde niemals Klassen schreiben, die aufeinander treten würden - also funktioniert das für mich. :)
sheriffderek
6

Dies ist mit CSS-Selektoren nicht möglich. Sie können jedoch zwei Klassen anstelle einer verwenden, z. B. status und wichtig anstelle von status wichtig .

Gumbo
quelle
14
Gute Idee, es in eine eigene Klasse zu unterteilen, aber es ist mit CSS-Selektoren möglich. Siehe meine Antwort.
BoltClock
2

Das kannst du nicht machen, nein. Es gibt einen Attributselektor , der bis zum a - Zeichen genau oder teilweise übereinstimmt, aber hier würde er nicht funktionieren, da Sie mehrere Attribute haben. Wenn der gesuchte Klassenname immer an erster Stelle steht, können Sie Folgendes tun:

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

Beachten Sie, dass dies nur darauf hinweist, welcher CSS-Attributselektor am nächsten ist. Es wird nicht empfohlen anzunehmen, dass Klassennamen immer im Vordergrund stehen, da Javascript das Attribut manipulieren könnte.

SBUJOLD
quelle
2
Ja, daran gedacht. Es kann zu einem Problem werden, wenn jQuery ins Bild kommt, da möglicherweise eine Klasse an der Vorderseite eingefügt wird.
THX-1138
Ja, ich werde meinen Beitrag bearbeiten, um klar zu machen, dass dies keine empfohlene Methode ist. Wenn Sie die Kontrolle über die Klassennamen haben, ist Gumbos Vorschlag definitiv der richtige Weg (plus Attributselektoren in älteren IE-Browsern werden nicht unterstützt).
SBUJOLD