CSS-Auswahl "(A oder B) und C"?

176

Dies sollte einfach sein, aber ich habe Probleme, die Suchbegriffe dafür zu finden.
Nehmen wir an, ich habe Folgendes:

<div class="a c">Foo</div>
<div class="b c">Bar</div>

Wie kann ich in CSS einen Selektor erstellen, der mit etwas übereinstimmt, das mit "(.a oder .b) und .c" übereinstimmt?

Ich weiß, dass ich das tun kann:

.a.c,.b.c {
  /* CSS stuff */
}

Aber unter der Annahme, dass ich diese Art von Logik mit einer Vielzahl von logischen Kombinationen häufig ausführen muss, gibt es eine bessere Syntax?

Josh
quelle
Seien Sie vorsichtig, wenn Sie Internet Explorer 6 unterstützen müssen, da nur mehr als ein Klassenname in einem CSS-Selektor ignoriert wird.
Vor dem
24
Glücklicherweise kann ich IE6-Benutzern für dieses Projekt sagen, dass sie selbst ein Upgrade durchführen sollen.
Josh
12
Aus Gründen der Klarheit versuche ich, immer eine neue Zeile nach den Kommas oder zumindest ein Leerzeichen zu setzen.
Aneves
2
@ANeves +1 für neue Zeile. Dies ist meiner Meinung nach der beste Ansatz, insbesondere bei Verwendung der Quellcodeverwaltung.
Curt

Antworten:

149

Gibt es eine bessere Syntax?

Nein. CSS ' oroperator ( ,) erlaubt keine Gruppierungen. Es ist im Wesentlichen der logische Operator mit der niedrigsten Priorität in Selektoren, daher müssen Sie ihn verwenden .a.c,.b.c.

Matt Ball
quelle
25

Noch nicht, aber es gibt die experimentelle :matches()Pseudoklassenfunktion, die genau das tut:

:matches(.a .b) .c {
  /* stuff goes here */
}

Weitere Informationen dazu finden Sie hier und hier . Derzeit unterstützen die meisten Browser die ursprüngliche Version :any(), die auf die gleiche Weise funktioniert, jedoch durch ersetzt wird :matches(). Wir müssen nur ein bisschen länger warten, bevor wir dies überall verwenden (ich werde es sicherlich tun).

Metallcodierer
quelle
Es ist unvernünftig, den IE dafür verantwortlich zu machen, dass er etwas nicht implementiert hat, an das er einfach nie gedacht hat und das zunächst in keinem Entwurf enthalten war. :-moz-any()und :-webkit-any()tauchte lange auf, bevor Mozilla es für Selectors 4 vorschlug (was zu seiner aktuellen Inkarnation als führte :matches()).
BoltClock
1
Es ist ebenso unvernünftig zu erwarten, dass ein Anbieter eine Funktion aus einem instabilen Entwurf implementiert, unabhängig davon, wie lange der Entwurf verfügbar ist (dies ist darauf zurückzuführen, dass Selectors 4 mehr als drei Jahre nach seiner FPWD instabil und weitgehend nicht implementiert bleibt). .
BoltClock
@BoltClock, sie beschuldigten IE6 ein ganzes Jahrzehnt lang für Dinge, die es 2001 nicht gab. Die Leute wollen nur jemanden beschuldigen.
GetFree
Ein Wort zu experimentellen ist, dass Sie sich nicht auf sie verlassen möchten, es sei denn, es wurde offiziell implementiert. Es könnte zwar eine großartige Lösung sein - die Möglichkeit, dass sie verschwindet, was mich persönlich daran hindert, sie in meinen Projekten umzusetzen. Selbst wenn ich eine experimentelle Pseudoklasse im Auge habe, fühle ich mich nicht sicher. Höchstwahrscheinlich wird es an mehr als einer Stelle im Projekt verwendet, und falls Sie mehr als eine Stelle haben, an der Sie es verwenden, müssen Sie irgendwie den Überblick behalten. Sie können sicherlich Fallbacks haben und es trotzdem schaffen, aber das klingt nicht sauber
Alexey Shevelyov
Bin ich der einzige, der einen Fehler bekommt Uncaught DOMException: Failed to execute 'querySelector' on 'Document': ':any(.a .b)' is not a valid selector.? 🤔
Thomas
12

Wenn Sie dies haben:

<div class="a x">Foo</div>
<div class="b x">Bar</div>
<div class="c x">Baz</div>

Und Sie möchten nur die Elemente auswählen, die .xund ( .aoder .b) haben, die Sie schreiben könnten:

.x:not(.c) { ... }

Dies ist jedoch nur dann praktisch, wenn Sie drei "Unterklassen" haben und zwei davon auswählen möchten.

Auswahl nur einer Unterklasse (zum Beispiel .a):.a.x

Auswahl von zwei Unterklassen (zum Beispiel .aund .b):.x:not(.c)

Auswahl aller drei Unterklassen: .x

Šime Vidas
quelle
6
Jede logische Klausel des Formulars a or b or c or dist dieselbe wie not(not(a) and not(b) and not(c) and not(d))'oder' ist eigentlich nur eine Komfortfunktion. Theoretisch sollte es in allen Fällen möglich sein, ohne auszukommen. Im Fall des OP (.a or .b) and .c->:not(:not(.a):not(.b)).c
Max Murphy
2
@MaxMurphy Hast du das getestet?
Šime Vidas
4
Ab heute morgen um fünf Uhr ja! Ich habe js, das Logik erster Ordnung ausspuckt, mit Selektoren an den Blättern, die Ergebnisse wie liefern :not(:not([data-status="ACT"]):not([data-status="ISS"]):not([data-status="COR"]))[data-month="08"]. Der Code ist noch nicht sauber genug für die öffentliche Einsicht, sonst würde ich ihn posten. Ich habe auf Chrome, Safari und einem Low-End-Android-Handy getestet.
Max Murphy
2
@MaxMurphy Sie haben einen tollen Punkt, aber ich denke, Sie haben sich auf eine ziemlich gequälte Definition von "Convenience-Funktion" berufen. Alles, was ein digitaler Computer tun kann, kann in NAND-Gatter zerlegt werden, aber ich würde den Rest der Softwareentwicklung nicht als "eine Reihe von Komfortfunktionen" bezeichnen. Gradunterschiede werden schnell zu De-facto-Unterschieden, wenn Konstrukte kombiniert werden können.
Sarah G
1
@MaxMurphy Es fiel mir schwer herauszufinden, dass du nur Spaß gemacht hast. :( Die Negations-CSS-Pseudoklasse: not (X) ist eine funktionale Notation, die einen einfachen Selektor X als Argument verwendet. Sie entspricht einem Element, das nicht durch das Argument dargestellt wird. X darf keinen anderen Negationsselektor enthalten . (Von Mozilla docs , Schwerpunkt meiner)
törzsmókus
5

Nein. Standard-CSS bietet nicht das, wonach Sie suchen.

Möglicherweise möchten Sie jedoch WENIGER und SASS untersuchen .

Dies sind zwei Projekte, die darauf abzielen, die Standard-CSS-Syntax durch Einführung zusätzlicher Funktionen zu erweitern, darunter Variablen, verschachtelte Regeln und andere Verbesserungen.

Mit ihnen können Sie viel strukturierteren CSS-Code schreiben, und beide lösen mit ziemlicher Sicherheit Ihren speziellen Anwendungsfall.

Natürlich unterstützt keiner der Browser seine erweiterte Syntax (zumal die beiden Projekte jeweils unterschiedliche Syntax und Funktionen haben), aber sie bieten einen "Compiler", der Ihren LESS- oder SASS-Code in Standard-CSS konvertiert, was Sie dann können auf Ihrer Site bereitstellen.

Spudley
quelle
An diesem Punkt könnte ich genauso gut den PHP-Druck "Content-type: text / css" verwenden
Josh