Beachten Sie den Doppelpunkt ::before im Vergleich zum Doppelpunkt :before. Welcher ist korrekt?
Technisch gesehen ist die richtige Antwort ::before. Das bedeutet aber nicht, dass Sie es automatisch verwenden sollten.
Die Situation ist die:
- Doppelpunkt-Selektoren sind Pseudoelemente.
- Einpunkt-Selektoren sind Pseudoselektoren.
::before ist definitiv ein Pseudoelement, daher sollte es den Doppelpunkt verwenden.
Die Unterscheidung zwischen einem Pseudoelement und einem Pseudoselektor ist bereits verwirrend. Glücklicherweise sind ::after und ::before ziemlich unkompliziert. Sie fügen buchstäblich etwas Neues zur Seite hinzu, ein Element.
Aber etwas wie ::first-letter ist ebenfalls ein Pseudoelement. So argumentiere ich das in meinem Kopf: Es wählt einen Teil von etwas aus, für den es kein bestehendes HTML-Element gibt. Es gibt kein <span> um den ersten Buchstaben, den Sie ansprechen, also ist dieser erste Buchstabe fast wie ein neues Element, das Sie auf der Seite hinzufügen. Das unterscheidet sich von Pseudoselektoren, die Dinge auswählen, die bereits existieren, wie z. B. :nth-child(2) oder was auch immer.
Auch wenn ::before ein Pseudoelement ist und der Doppelpunkt die korrekte Art ist, Pseudoelemente zu verwenden, sollten Sie es tun?
Es gibt ein Argument, dass Sie vielleicht :before verwenden sollten, das wie folgt lautet:
- Internet Explorer 8 und darunter unterstützte nur
:before, nicht::before - Alle modernen Browser unterstützen es auf beide Arten, da unzählige Websites
:beforeverwenden und Browser Rückwärtskompatibilität sehr schätzen. - Als Bonus ist es ein Zeichen weniger.
Ich habe gehört, dass Leute sagen, sie hätten einen CSS-Linter, der sie zur Verwendung von Einzelpunkten zwingt (oder dies automatisiert). Persönlich bin ich damit einverstanden, wenn Leute das tun. Scheint in Ordnung. Ich würde Konsistenz über die von Ihnen gewählte Methode stellen.
Auf der anderen Seite gibt es ein Argument für die Verwendung von ::before, das wie folgt lautet:
- Einzelpunkt-Pseudoelemente waren ein Fehler. Es wird nie mehr Pseudoelemente mit Einzelpunkt geben.
- Wenn Sie die Unterscheidung klar im Kopf haben, trainieren Sie Ihre Finger ruhig, es richtig zu machen.
- Das ist ohnehin schon verwirrend genug, also folgen wir einfach dem korrekt spezifizierten Weg.
Ich habe meinen Linter so eingestellt, dass er mich zwingt, Doppelpunkte zu verwenden. Ich unterstütze Internet Explorer 8 sowieso nicht und es fühlt sich gut an, die Dinge auf die "richtige" Art und Weise zu tun.
Ich glaube, die Erfahrung hat bereits gezeigt, dass wir uns auf den Einzelpunkt verlassen könnten. Warum den Doppelpunkt nicht fallen lassen und die Verwirrung beenden?
Ich stimme zu! Warum die Unterscheidung nicht ganz aufgeben? Selbst wenn es ein Fehler war, ist es leichter zu merken, als die Syntax aufgrund eines so abstrakten Konzepts ändern zu müssen.
Absolut einverstanden – offensichtlich ist ein Doppelpunkt alles, was benötigt wird, wenn sie austauschbar sind. Warum die Dinge schwieriger machen als sie sein müssen?
Ein paar interessante(?) Anmerkungen:
Die CSS-Regel
content: 'some string'funktioniert nur mit::beforeund::after, nicht mit anderen Pseudoelementen.Zumindest in Chrome wählte
::first-letteralles bis einschließlich des ersten Buchstabens aus. Zum Beispiel würdekbd::first-letter { color: red }auf<kbd>#!/usr/bin/python</kbd>den Text#!/uhervorheben.Funktioniert, wenn kbd als "
block"-Element angezeigt wird (kleine Einschränkung für::first-letter).kbd {
display: inline-block; /* display: block */
}
Laut Mozilla „Interpunktion, die dem ersten Buchstaben vorangestellt ist oder ihm unmittelbar folgt, ist in der Übereinstimmung enthalten. Interpunktion umfasst jedes Unicode-Zeichen, das in den Klassen öffnend (Ps), schließend (Pe), initialer Anführungsstrich (Pi), finaler Anführungsstrich (Pf) und andere Interpunktion (Po) definiert ist.“ (https://developer.mozilla.org/en-US/docs/Web/CSS/::first-letter)
Dies ist ein klassisches Beispiel, bei dem es eine klar korrekte Schreibweise zu geben scheint (
::before, für Spezifikationskonformität / zukunftsorientiert) und die Bereitstellung (:before, Unterstützung und die kostbaren Zeichenanzahl), und sie stehen im Gegensatz zueinander.Build-Tools und Bereitstellungsprozesse machen es einfach, einen Schalter umzulegen, wenn CSS8 endlich die Einzelpunkt-Syntax abschafft :)
Pseudoklassen sind Selektoren, die auf Zustand basieren, Pseudoelemente sind Selektoren, die auf Inhalt basieren. Es ist eigentlich einfacher zu merken, wenn etwas eine Pseudoklasse ist, und anzunehmen, dass es sich, wenn es dieser Definition nicht entspricht, um ein Pseudoelement handeln muss.
Pseudoklassen können sich aufgrund einer Benutzeraktion (oder Interaktion) ändern.
:hoverist ein einfaches Beispiel. Sie nimmt diesen Stil nur an, wenn der Benutzer über das Element fährt. Ein kniffligeres Beispiel könnte:validsein, da der Inhalt das ist, was gültig oder ungültig ist, aber dies wird sich voraussichtlich mit der Benutzereingabe ändern. Das Eingabeelement selbst ist nicht ungültig, es hat lediglich einen ungültigen Wert und somit einen Zustand von nicht gültig (und der Stil wird angewendet).Ich bin mir nicht sicher, warum
::first-letterverwirrend sein sollte, aber auch hier kann man feststellen, dass es kein Pseudoelement ist, indem man denkt: "Ist dies etwas, von dem erwartet wird, dass es sich aufgrund von Benutzeraktionen ändert?" Sicher, es könnte etwas lustiges JavaScript geben, das einen neuen Absatz erstellt, wenn ein Benutzer auf eine Schaltfläche klickt, aber dies hat den Zustand des "ersten Buchstabens" nicht geändert, es hat lediglich etwas anderes zum ersten Buchstaben gemacht. Da es sich nicht wie eine Pseudoklasse anhört, ist es daher ein Pseudoelement.Ähm... Ihre Analogie funktioniert größtenteils, aber was ist mit
:first-child?Das ist kein wirklich zustandsbasierter Selektor. Es sei denn, es handelt sich um dynamischen Inhalt, der Benutzer kann nicht ändern, was das erste Kind-Element ist.
Der Doppelpunkt ist technisch gesehen der richtige Weg, aber normalerweise würde ich den Einzelpunkt verwenden, um die Unterstützung zu erweitern. Nicht, dass ich aktiv IE8 unterstützen würde, aber es schadet nicht.
Nebenbei bemerkt, ist die Unterscheidung zwischen Pseudoelementen und Pseudoklassen in den meisten Fällen kristallklar, aber einige sind komplizierter. Selbst Browserentwickler scheinen sich nicht einig zu sein.
Betrachten Sie zum Beispiel Platzhalter. Webkit-Browser verwenden
::-webkit-input-placeholder, also ist es für sie ein Pseudoelement. Trident verwendet:-ms-input-placeholder, was bedeuten würde, dass sie es als Pseudoklasse betrachten. Und Gecko hat seine Pseudoklasse:-moz-placeholderin Firefox 19 zu::-moz-placeholdergeändert...Ihr letzter Satz ist der beste.
Was Ihnen wirklich den Kopf verdrehen wird, ist, wenn Sie
::beforeverwenden und dann gulp-sass dies in/beforetranspilieren – aber nur auf dem Build-Server, nicht auf der lokalen Entwicklungsumgebung eines jeden (alle Versionen abgestimmt). Wir mussten auf Einzelpunkte zurückwechseln, um diesen Fehler zu vermeiden.Vielleicht lebe ich in einer Fantasiewelt, aber sicherlich, sicherlich ist die IE8-Unterstützung nichts, worüber wir uns Sorgen machen müssen?
Microsoft unterstützt seit mehreren Jahren keine Version von IE außer 11 mehr.
Außerdem ist IE 8 über 10 Jahre alt. Das bedeutet, er ist älter als (zum Beispiel) das gesamte Marvel Cinematic Universe.
Unser Hauptprodukt befasst sich mit vertraulichen Informationen. Wir unterstützen keine IE-Versionen unter 11 (und werden diese auslaufen lassen), da sie implizit unsicher sind und nur auf Betriebssystemen verfügbar sind, die weit über das Ende ihrer Lebensdauer hinaus sind.
Ich kann mir ehrlich gesagt keinen Grund vorstellen, eine Funktion beizubehalten, nur um jahrzehntealte Software zu unterstützen, weil ich keinen gültigen Grund dafür finden kann, sie zu benutzen. Kann mir jemand einen Grund nennen?
Wir sollten es mit Doppelpunkt schreiben, weil das die richtige Art ist – wenn wir Einzelpunkt-Unterstützung benötigen, sollte sie beispielsweise mit Autoprefixer hinzugefügt werden (ernste Frage: Unterstützt Autoprefixer das Hinzufügen von Einzelpunkten für Browser, die die Doppelpunkt-Version nicht unterstützen?) – die gleiche Situation wie bei Gradients – wir haben drei Syntaxen, sollten aber nur eine (korrekte) verwenden – neu und Autoprefixer lässt tweener- und alte Syntaxen bei Bedarf hinzufügen.
Autoprefixer würde
:beforenicht hinzufügen. Es ist kein Präfix und sie sind bei dieser Regel ziemlich streng, um die Ausweitung des Umfangs zu vermeiden.Selbst wenn es das täte, müssten Sie in Ihrer Konfiguration explizit angeben, dass Sie IE8 unterstützen möchten, damit es in Ihrem Ausgabe-CSS enthalten ist.
Kann man das nicht so sehen: Man hat das Pseudoelement
::before, das sieht man auch, wenn man sich den Code z.B. in den Chrome Dev Tools ansieht. In CSS **selektiert** man das Pseudoelement::beforemit dem Pseudo-**Selektor**:before. Also ein Doppelpunkt...Werden sie nicht beide als Pseudoselektoren bezeichnet? Und aufgeteilt in Pseudoelemente (Doppelpunkt, ::before ::after) und Pseudoklassen (Einzelpunkt wie :hover, :focus :disabled etc..)?
Ich habe kürzlich für mein Unternehmen einen Screencast zu diesem Thema erstellt (noch nicht öffentlich). Ähnlich wie Sie, Chris, kam ich zu dem Schluss, dass, wenn der Browser "etwas hinzufügen" muss, um die Stile zu rendern, es sich um ein Pseudoelement handelt (der Browser muss "den ersten Buchstaben in etwas einpacken", damit wir
::first-letteranwenden können). Wenn die Stile zu bereits vorhandenen Elementen hinzugefügt werden, handelt es sich um eine Pseudoklasse.Ich plädiere seit langem dafür, die Spezifikation zu verwenden, aber bis zur Erstellung dieses Videos hatte ich keine gültige Definition, wie sich die Pseudoelemente unterscheiden.
Es gibt jetzt Pseudoelemente wie
::placeholder, die einen Doppelpunkt benötigen. Daher sollten zur Konsistenz alle Pseudoelemente (einschließlich::before) ebenfalls Doppelpunkte haben.Der ewige Kampf zwischen Spezifikationen und realer Nutzung.
Ich hatte Kompatibilitätsprobleme im Browser, als ich den Doppelpunkt ::before verwendete, seitdem habe ich ihn nie mehr mit Doppelpunkt verwendet.
Ich bin nicht verwirrt über die Unterscheidung, sondern nur darüber, warum die Unterscheidung notwendig ist. Der Doppelpunkt erschien mir schon immer als eine Verschwendung eines Tastendrucks.
Ich habe einen CSS-Linter, der sie zur Verwendung von Einzelpunkten zwingt (oder dies automatisiert). Also, was kann ich tun?