Die Spezifität von :where() als CSS Reset verwenden

Avatar of Mojtaba Seyedi
Mojtaba Seyedi am

DigitalOcean bietet Cloud-Produkte für jede Phase Ihrer Reise. Starten Sie mit 200 $ kostenlosem Guthaben!

Ich weiß nicht, wie es Ihnen geht, aber ich schreibe diese drei Deklarationen viele Male in meinem CSS

ul {
  padding: 0;
  margin: 0;
  list-style-type: none;
}

Sie könnten mich anschreien und sagen, ich könne das einfach in meine CSS-Resets einfügen. Ich wünschte, ich könnte, aber ich will nicht, und ich sage Ihnen gleich warum.

Benutzeragenten setzen Werte für diese Eigenschaften in einer Liste aus einem bestimmten Grund, und zwar um Listen lesbarer zu machen. Dies sind die Standardstile in Chromium-Browsern für ein <ul>-Element

ul {
  list-style-type: disc;
  margin-block-start: 1em;
  margin-block-end: 1em;
  margin-inline-start: 0px;
  margin-inline-end: 0px;
  padding-inline-start: 40px;
}

Also, ohne eine Klasse in HTML oder einen Stil in CSS hinzuzufügen, bekommen wir das kostenlos. Das ist eine schöne Sache und ich möchte sie nicht verlieren. Aber ich wäre dankbar, wenn ich dem Browser verständlich machen könnte, dass die Wahrscheinlichkeit sehr hoch ist, dass ich diese Standardfunktion nicht möchte, falls ich dem Element eine Klasse hinzufüge.

Hier ist also eine schnelle Lösung, um ein <ul>-Element mit einer Klasse zurückzusetzen

ul[class] {
  padding: 0;
  margin: 0;
  list-style-type: none;
}

Jetzt verliere ich den Standardstil nicht, außer wenn ich meinem <ul>-Element eine Klasse hinzufüge.

Das Problem

Dieses Problem hat eine Lösung. Stellen Sie sich eine Liste vor, für die wir eine andere list-style-type haben möchten, wie die folgende

ul[class] {
  padding: 0;
  margin: 0;
  list-style-type: none;
}

.list {
  list-style-type: square;
}

Das funktioniert nicht, da ul[class] eine höhere Spezifität hat. Hier versagt unsere Lösung.

Wir könnten dem Selektor mehr Gewicht verleihen

ul.list {
  list-style-type: square; /* Specificity: 0, 1, 1 */
}

/* or */

.sidebar .list {
  list-style-type: square; /* Specificity: 0, 2, 0 */
}

Wenn es Ihnen nichts ausmacht, dem Selektor mehr Gewicht zu verleihen, dann können Sie loslegen. Aber ich persönlich bin damit nicht einverstanden. Zum Beispiel möchte ich aufgrund des Prinzips der Trennung von Belangen meistens nicht den Elementnamen in meinen CSS-Code aufnehmen. Oder, wenn Sie die BEM-Methodik befolgen, werden mit ziemlicher Sicherheit Probleme auftreten, da dies damit kollidiert.

Was können wir also tun?

Die Lösung

Vor ein paar Monaten habe ich einige angesagte Selektoren kennengelernt, darunter :is() und :where(). Eines an diesen beiden funktionalen Pseudo-Selektoren ist, dass sie die Spezifität ändern können, was uns die Macht gibt, diese Spezifität zu nullifizieren oder zu erhöhen.

Der Schlüssel zu :where() ist, dass es immer eine Spezifität von 0 hat. So können wir unser Problem ganz einfach wie folgt lösen

:where(ul[class]) {
  list-style: none;
}

.list {
  list-style: square; /* Now this works like a charm! */
}

Mit der Macht dieses Selektors können Bibliotheken uns Stile ohne Spezifität geben. Es gäbe also keine Spezifität, mit der wir als Autoren CSS schreiben müssten, um zu konkurrieren.

Demo

In der folgenden Demo können Sie :where() entfernen, um zu sehen, worüber wir gesprochen haben