PPK legte eine interessante Situation in „Two options for using custom properties“ dar, wo er und Stefan Judis zwei unterschiedliche Ansätze hatten, um dasselbe mit benutzerdefinierten Eigenschaften zu tun. Bei einem Ansatz werden Hover- und Fokusstile für einen Link mit zwei verschiedenen benutzerdefinierten Eigenschaften behandelt, eine für jeden Zustand. Beim anderen Ansatz wird eine einzige benutzerdefinierte Eigenschaft verwendet.
Zwei benutzerdefinierte Eigenschaften
.component1 {
--linkcolor: red;
--hovercolor: blue;
}
.component2 {
--linkcolor: purple;
--hovercolor: cyan;
}
a {
color: var(--linkcolor);
}
a:hover,a:focus {
color: var(--hovercolor)
}
Eine benutzerdefinierte Eigenschaft
.component1 a {
--componentcolor: red;
}
.component1 :is(a:hover,a:focus) {
--componentcolor: blue;
}
.component2 a {
--componentcolor: purple;
}
.component2 :is(a:hover,a:focus) {
--componentcolor: cyan;
}
a {
color: var(--componentcolor)
}
Es gibt etwas Natürliches an der Verwendung von zwei Eigenschaften, als ob sehr deutlich wäre, was eine bestimmte benutzerdefinierte Eigenschaft tun soll. Aber es gibt viel Eleganz bei der Verwendung einer einzigen benutzerdefinierten Eigenschaft. Nicht nur, weil es eine benutzerdefinierte Eigenschaft weniger ist, sondern weil die benutzerdefinierte Eigenschaft 1-zu-1 mit einer einzigen Eigenschaft übereinstimmt.
Wenn man das noch weiter treibt, könnte man einen einzigen Regelblock mit einer benutzerdefinierten Eigenschaft pro Eigenschaft einrichten, was ihm eine Art *Menü* dessen gibt, was sich ändern wird. Dazu sagt PPK
Jetzt haben Sie im Wesentlichen eine Definitionsdatei gefunden. Sie sehen nicht nur die Standardstile der Komponente, sondern auch, was sich ändern könnte und was nicht.
Das heißt, Sie würden eine benutzerdefinierte Eigenschaft für alles verwenden, was Sie ändern möchten, und für alles, was Sie nicht ändern möchten, würden Sie es nicht tun. Das ist sicherlich ein interessanter Ansatz, den ich niemandem verdenken würde, der ihn ausprobiert.
.lil-grid {
/* will change */
--padding: 1rem;
padding: var(--padding);
--grid-template-columns: 1fr 1fr 1fr;
grid-columns: var(--grid-template-columns);
/* won't change */
border: 1px solid #ccc;
gap: 1rem;
}
Mein Zögern dabei ist, dass es bestenfalls ein Hinweis darauf ist, was sich ändern wird und was nicht. Zum Beispiel kann ich immer noch Dinge ändern, auch wenn sie nicht in einer benutzerdefinierten Eigenschaft festgelegt sind. Später könnte ich tun
.lil-grid.two-up {
grid-columns: 1fr 1fr;
}
Das macht die Verwendung der benutzerdefinierten Eigenschaft zunichte. Ähnlich könnte ich den Wert von --grid-template-columns *nie* ändern, was bedeutet, dass er sich unter verschiedenen Umständen zu ändern scheint, aber nie tut.
Ebenso könnte ich tun
.lil-grid.thick {
border-width: 3px;
}
…und obwohl meine ursprüngliche Komponentenregel impliziert, dass sich die Rahmenbreite nicht ändert, tut sie sich mit einer Modifikatorklasse.
Damit ein solcher Ansatz funktioniert, muss man ihn wie eine Konvention behandeln, an die man sich hält, wie einen generellen Codierungsstandard. Ich befürchte jedoch, dass er zu einer Qual wird. Für jede Deklaration, die Sie ändern möchten, müssen Sie zurückgehen und sie umgestalten, entweder zu einer benutzerdefinierten Eigenschaft machen oder nicht.
Das bringt mich zum Nachdenken über die „implizite Styling-API“, die HTML und CSS darstellen. Wir haben bereits eine Styling-API in Browsern. HTML wird im Browser in das DOM umgewandelt, und wir stylen das DOM mit CSS. Elemente auswählen, sie stylen.
Vielleicht brauchen wir kein Menü dafür, was wir stylen können und was nicht, denn das sind DOM und CSS bereits. Das soll nicht heißen, dass eine gut gestaltete Sammlung benutzerdefinierter Eigenschaften nicht Teil davon sein kann, aber sie müssen keine strikten Regeln dafür darstellen, was sich ändert und was nicht.
Wo wir gerade von impliziten Styling-APIs sprechen, schreibt Jim Nielsen in „Shadow DOM and Its Effect on the Unofficial Styling API“
[…] das Shadow DOM bricht die selbstbeschreibende Style-API, die wir seit Jahren im Web haben.
Welche Style-API? Wenn Sie ein Element auf dem Bildschirm stylen möchten, öffnen Sie die Entwicklertools, schauen Sie sich das DOM an, finden Sie das gewünschte Element, ermitteln Sie den richtigen Selektor, um dieses Element anzusprechen, schreiben Sie Ihren Selektor und Ihre Stile, und fertig.
Das ist bemerkenswert, wenn man darüber nachdenkt.
Ich denke, das ist mein größter Kritikpunkt an Web Components. Ich mag das Shadow DOM nicht; tatsächlich ist es wahrscheinlich mein Lieblingsteil an Web Components. Ich mag einfach nicht, wie ich eine Styling-API dafür erfinden muss (à la benutzerdefinierte Eigenschaften, die sich darin winden, oder ::part), anstatt die Styling-API zu verwenden, die uns seit Ewigkeiten gute Dienste leistet: DOM + CSS.
Was ich nachvollziehen kann, ist „Jetzt haben Sie im Wesentlichen eine Definitionsdatei gefunden.“
Das bringt mich zum Nachdenken, oh, es ist ein Ort, an dem ich meine Design-System-Tokens ablegen kann. Alle Schriftarten, Farben, Abstände und so weiter, Dinge, die sich innerhalb einer einzelnen Komponente ändern oder in mehreren Komponenten verwendet werden könnten.