DRY CSS: Wie man jede Deklaration nur einmal verwendet
Artikel vom 2. Januar 2018. ISSN 1614-3124, #56. Schwerpunkt: Webentwicklung (RSS-Feed für alle Themen).
Wenn Sie sich speziell mit der Optimierung von CSS beschäftigen, ich habe einige Grundlagen in einem kleinen Buch zusammengetragen: CSS Optimization Basics.
Deklarationen nur einmal zu verwenden stellt eine Möglichkeit dar, Wiederholung in Stylesheets zu kontrollieren. Der Ansatz ist kein Allheilmittel, wie wir mit jüngsten Daten gesehen haben, aber er ist so mächtig, dass er eine Hauptmethode zur Stylesheet-Optimierung bildet. Da ich ihn nahezu ein Jahrzehnt angewandt und studiert habe, gehe ich im vorliegenden Artikel einmal über den Prozess – den Prozess, Deklarationen nur einmal zu verwenden.
Inhalt
Allgemeine Schritte
Bevor wir uns mit allen Details befassen, wie man Stylesheets durch einmalige Deklarationen »trocknet«, beachten Sie, dass es sich hierbei um eine Methode handelt, die nicht trivial zu automatisieren ist. Dies liegt an der Kaskade. Aber auch wenn das folgende entsprechend nicht sofort automatisierbar ist, werde ich versuchen, nicht allzu schludrig zu sein.
- Schreiben Sie CSS auf die herkömmliche und natürliche Weise.
- Entscheiden Sie ĂĽber DRY-Grenzen: Abschnitts- (funktional separate aber gekennzeichnete CSS-Bereiche) oder Datei-, Komponenten-,
@media
-Ebene? (Ich selbst arbeite auf der Datei-/@media
-Ebene, das heißt, ich »trockne« im größtmöglichen Bereich.) - Formatieren Sie Code konsistent, da
border:0;
,border: 0;
undborder: none;
alle dasselbe bedeuten aber die Aufgabe, Duplikate zu finden, erheblich erschweren. - Suchen Sie nach mehrmals vorkommenden Deklarationen:
- Bei neuen Stylesheets: nach dem initialen Aufsetzen.
- Bei neuen Funktionen sowie Bugfixes: nachdem die entsprechenden Arbeiten abgeschlossen wurden.
- Tipp: Wenn die Hervorhebung durch Versionskontrollsoftware nicht ausreicht, rücken Sie geänderte Deklarationen einfach kurzzeitig ein, um dann ihre Einmaligkeit zu prüfen.
-
Lösen Sie Deklarationswiederholungen auf:
- Prüfen Sie jede Deklaration (in neuen Stylesheets) oder jede geänderte Deklaration auf Wiedervorkommen innerhalb des gewählten Bereichs (wenn die Deduplizierung einzelne Abschnitte betreffen soll, begrenzen Sie den Suchradius auf diese Abschnitte).
-
FĂĽr jede wiederholte Deklaration (die eigentliche Arbeit):
- Bestimmen Sie, welche Regel im Stylesheet zuerst kommen sollte (dafür sollte man einen – unausgesprochenen oder ausgeschriebenen – Standard haben, wie man Selektoren sortiert).
- Wenn diese erste Regel noch andere Deklarationen beinhaltet, also Deklarationen, die noch nicht auf Wiederholung geprĂĽft wurden, kopieren Sie die ganze Regel und fĂĽgen Sie sie hinter der Originalregel ein; behalten Sie die entdeckte Duplikatsregel in der ersten Regel und entfernen Sie die anderen Deklarationen, und umgekehrt in der zweiten Regel, so dass diese wie die ursprĂĽngliche Regel ist, nur ohne die Deklaration, die mehr als einmal verwendet wurde.
- Kopieren Sie die Selektoren der anderen Regeln, die die identifizierte wiederholte Deklaration beinhalten, zu der Regel, die als erstes kommt.
- Stellen Sie sicher, die wiederholten Deklarationen von den Regeln zu entfernen, dessen Selektoren nun hochkopiert wurden, und die ganze Regel zu löschen, wenn so eine Regel nur aus der wiederholten Deklaration bestand.
- (Wiederholen Sie dies.)
- Stellen Sie sicher, dass bei den Regeln, die nun die zuvor wiederholten Deklarationen beinhalten, die Reihenfolge der Selektoren stimmt.
- Stellen Sie sicher, dass die Regeln, die nun zuvor wiederholte Deklarationen umfassen, korrekt platziert sind.
- (Wiederholen Sie Schritte 4 und 5.)
- Testen Sie.
Der Prozess ist nicht einfach, und dennoch ist er auch nicht so schlimm, wie er zunächst anmutet. Wir befassen uns damit nun en détail und schauen uns gleich auch ein paar Beispiele an.
Sonderfälle
Es gibt zwei Szenarien, die besondere Aufmerksamkeit erfordern.
-
Aufgeteilte Dateien: Separate Stylesheet-Dateien können nützlich sein, besonders wenn sie zur Produktion wieder zusammengefügt werden, aber wenn es darum geht, Deklarationen zu trocknen bilden sie eine »harte« Grenze – es ist prohibitiv mehr Arbeit, wiederholte Deklarationen über einzelne Dateien hinaus zu konsolidieren. Wenn wir mit einer kleinen bis mittleren CSS-Code-Basis arbeiten, kann es ratsam sein, auf ein Stylesheet umzustellen, und wenn wir es mit einem komplexen Stylesheet-Setup zu tun haben, oder wir uns vor Auge führen, dass ein bisschen Wiederholung okay ist, können wir diese Dateigrenze auch hinnehmen.
-
Strenge des Ansatzes oder Ausnahmenregelung: Wenn wir streng sind, was das Vermeiden von Wiederholung anbelangt (wenn wir diese also gänzlich meiden wollen), werden wir ab und an auf Ausnahmen von der Regel stoßen. Diese Ausnahmen, wenn sie nicht strukturbedingt sind wie bei selbstauferlegten Abschnitts- oder Dateigrenzen oder sprachbedingten wie wenn die Reihenfolge (Kaskade) ausschlaggebend ist, kommen oft als Support-Probleme daher. Selektoren-Hacks sind auch so eine Ausnahme, da manche Selektoren so funktionieren, dass sie quasi einen User-Agent daran hindern, die entsprechende Regel zu interpretieren. In solchen Fällen können wir wiederholte Deklarationen nicht einfach auflösen, da wenn wir die entsprechenden Selektoren kombinieren, wir den Selektoren-Hack beeinflussen und dieser nicht mehr wie zuvor funktionieren würde.
Beispiele
Wollen wir nun durch ein paar nicht-präprozessierte aber ansonsten repräsentative Stylesheets arbeiten, um diese zu trocknen. Wir werden uns auf Optimierung auf Dateiebene konzentrieren, da man sich den betroffenen Code leicht als Abschnitte oder Module innerhalb einer Datei vorstellen kann, um dieselben Schritte zu ergreifen (aber eben ohne dasselbe Gesamtergebnis an Nicht-Wiederholung).
Optimieren I
Das erste Beispiel kommt von Engadget, wo wir in der Vergangenheit schon 92% Deklarationswiederholung gefunden haben; der Ausschnitt ist zufällig gewählt, aber zumindest alphabetisch sortiert. Wir nehmen an, dass die Selektorenordnung nach unserem Geschmack ist, und wir passen Klassennamen und ähnliches weder an, noch sollen sie hier kommentiert werden.
.arrow-left {
border-color: transparent;
border-style: solid;
border-width: 10px 10px 10px 0;
height: 0;
width: 0;
}
.arrow-down {
border-bottom: 10px solid transparent;
border-left: 10px solid transparent;
border-right: 10px solid transparent;
border-top: 10px solid #2b2d32;
bottom: 0;
height: 0;
left: 20px;
width: 0;
}
.faq-list .faq-item-title {
cursor: pointer;
}
.faq-list .faq-item-title:after {
border-left: 5px solid transparent;
border-right: 5px solid transparent;
border-top: 5px solid #111;
content: '';
display: inline-block;
float: right;
height: 0;
opacity: .5;
vertical-align: top;
width: 0;
}
#contact input:focus,
#contact textarea:focus {
border: 1px solid #3398db;
}
.flickity-slider>.table {
table-layout: fixed;
}
::selection {
background: #9b59b6;
color: #fff;
}
.videoWrapper {
height: 0;
padding-bottom: 56.25%;
position: relative;
}
.videoWrapper iframe {
height: 100%;
left: 0;
position: absolute;
top: 0;
width: 100%;
}
.i-rail-followus__socials {
display: table;
}
.i-rail-followus__tw {
vertical-align: sub;
}
Wenn wir auf unsere Liste schauen, bemerken wir, dass wir schon bereit sind, wiederholte Deklarationen zu suchen und aufzulösen. Ich wünschte, dies könnte als separater Schritt abgebildet werden, aber bis ich mal dazu komme, hierzu ein Video aufzuzeichnen (in Arbeit), schreibe ich einfach nieder, was man machen muss, und zeige dann den daraus resultierenden Code.
Da wir noch am Anfang des DRY-Optimierungsprozesses stehen, arbeiten wir uns einfach von oben nach unten das Stylesheet hinunter, wobei wir uns jede Deklaration anschauen. Die erste Deklaration ist dabei border-color: transparent;
. Wird diese noch irgendwo verwendet? Nein. Dann, border-style: solid;
? Einmalig. Dasselbe bei border-width: 10px 10px 10px 0;
. Wie ist es mit height: 0;
? Nicht einmalig.
Entsprechend beginnt unsere Arbeit mit height: 0;
. Wir bemerken, dass diese Deklaration in drei anderen Regeln verwendet wird: .arrow-down
, .faq-list .faq-item-title:after
und .videoWrapper
. Da wir keine Regel haben, die genau diese vier Selektoren umfasst, kopieren wir sie, um eine neue Regel zu bilden, genau vor der Regel, in der wir das erste Vorkommen von height: 0;
fanden (.arrow-left
). In anderen Worten (und diese Worte mögen sich leicht von denen unterscheiden, die anfangs kamen), wir schreiben eine neue Regel nur für height: 0;
:
.arrow-left,
.arrow-down,
.faq-list .faq-item-title:after,
.videoWrapper {
height: 0;
}
Dann entfernen wir height: 0;
von allen anderen Regeln; da keine davon ausschließlich aus dieser Deklaration besteht, müssen wir (bislang) keine Regel ganz entfernen. (Ich behandle dies normalerweise in einem Schritt: Wenn ich ein »unkontroverses« Duplikat finde, bilde ich eine neue Regel, suche nach weiteren Vorkommen, entferne die zu bewegende Deklaration und kopiere die einzufügenden Selektor(en). Mit Übung wird dies alles einfacher.)
Wir fahren mit der .arrow-left
-Regel fort, und der Deklaration, die nach height: 0;
folgte: width: 0;
. Duplikat? Ja. Und dieses ist ein gutes in dem Sinne, dass wenn wir schauen, wo width: 0;
noch verwendet wird, wir sehen, dass es wenn auch nicht ganz doch fast identisch ist mit den Selektoren, die jetzt height: 0;
beherbergen. Das heiĂźt nun, dass wir eine neue Regel mit width: 0;
aufmachen und sicherstellen, dass wir alle vorherigen Vorkommen auflösen:
.arrow-left,
.arrow-down,
.faq-list .faq-item-title:after {
width: 0;
}
Diese Regel folgt gleich nach der, die wir fĂĽr height: 0;
gebildet haben und vor der .arrow-left
-Regel, die wir gerade erfolgreich geprüft und von Wiederholung befreit haben. Aus meiner Sicht ist die sich ergebende Reihenfolge nützlich, da ich es bevorzuge, wenn Regeln in einer Folge von Wichtigkeit und Einfluss (Wirkungsgrad) erscheinen und da wir durch das Zusammenführen von Selektoren die entsprechenden Regeln einflussreicher (wirkungsvoller) gemacht haben – um also erst zu kommen.
Als nächstes arbeiten wir uns durch die .arrow-down
-Regel. Keine wiederholten Deklarationen, aber es fällt auf, dass wie in der .arrow-left
-Regel diese ebenfalls etwas eleganter geschrieben werden könnte: border: 10px solid transparent; border-top-color: #2b2d32;
. Aber dies ist nicht das Thema hier.
Weiter mit .faq-list .faq-item-title
. Keine Wiederholung. In der Tat war dieses Stylesheet-Fragment recht dankbar, da wir keine zusätzliche Wiederholung mehr auffinden können:
.arrow-left,
.arrow-down,
.faq-list .faq-item-title:after,
.videoWrapper {
height: 0;
}
.arrow-left,
.arrow-down,
.faq-list .faq-item-title:after {
width: 0;
}
.arrow-left {
border-color: transparent;
border-style: solid;
border-width: 10px 10px 10px 0;
}
.arrow-down {
border-bottom: 10px solid transparent;
border-left: 10px solid transparent;
border-right: 10px solid transparent;
border-top: 10px solid #2b2d32;
bottom: 0;
left: 20px;
}
.faq-list .faq-item-title {
cursor: pointer;
}
.faq-list .faq-item-title:after {
border-left: 5px solid transparent;
border-right: 5px solid transparent;
border-top: 5px solid #111;
content: '';
display: inline-block;
float: right;
opacity: .5;
vertical-align: top;
}
#contact input:focus,
#contact textarea:focus {
border: 1px solid #3398db;
}
.flickity-slider>.table {
table-layout: fixed;
}
::selection {
background: #9b59b6;
color: #fff;
}
.videoWrapper {
padding-bottom: 56.25%;
position: relative;
}
.videoWrapper iframe {
height: 100%;
left: 0;
position: absolute;
top: 0;
width: 100%;
}
.i-rail-followus__socials {
display: table;
}
.i-rail-followus__tw {
vertical-align: sub;
}
Optimieren II
Als unser zweites Beispiel nehmen wir uns eBay an. Auch dieses Mal wollen wir uns nur kurz um einfache Umformatierung kümmern (Einrückung, alphabetische Deklarationssortierung), aber wieder begegnen wir Praktiken, die zu vermeiden sind (vor allem präsentationsbezogene Klassennamen, aber auch Mangel an Fallback-Schriften – wobei ein solcher Mangel bei Schriften wie Arial in der Praxis kein Problem darstellt).
.sh-GifCont {
color: #999;
font-family: Verdana !important;
font-size: 10px;
font-weight: normal;
padding: 0 10px 4px 10px;
}
.sh-GetFastImg {
background-image: url('http: //ir.ebaystatic.com/pictures/aw/pics/de/viewitem/spr4VI.png');
background-position: 0 -178px;
background-repeat: no-repeat;
float: left;
height: 16px;
margin-right: 4px;
width: 56px;
}
.sh-float-l {
float: left;
}
.sh-FrZip {
padding: 10px 0 0 15px;
width: 12%;
}
.sh-FrDelLoc {
padding: 10px 15px 0 10px;
width: 10%;
}
.sh-FrCnt {
padding-left: 10px;
padding-right: 0;
text-align: left;
}
.sh-FrZipCnt {
padding: 0 0 0 15px;
}
.sh-FrDelLocCnt {
padding: 0;
}
.sh-FrBtn {
padding: 5px 15px 10px 8px;
}
.sh-FrDelSite {
padding: 6px 0 0;
}
.vi-frs-sh-FrSlctr {
display: inline;
padding: 6px 15px 0 10px;
}
.sh-FrZipDiv {
display: inline;
padding: 6px 15px 0 0;
}
.sh-FrTxt {
color: #333;
font-family: Arial;
font-size: 12px;
font-weight: normal;
padding-left: 15px;
}
.sh-FrLrnMore {
display: inline;
padding: 10px 10px 10px 15px;
}
.sh-FrQuote {
display: inline;
}
.sh-FrLnk {
margin-top: 5px;
}
.sh-Tbl {
padding: 10px;
}
.sh-TblCnt {
color: #333;
font-family: Arial;
font-size: 12px;
font-weight: normal;
padding-left: 15px;
}
.sh-TblHdr {
color: #5d5d5d;
font-family: Verdana;
font-size: 12px;
font-weight: normal;
padding-left: 15px;
}
.sh-Info {
color: #999;
font-family: Arial;
font-size: 11px;
font-weight: normal;
}
.sh-FrSbTxt {
color: #999;
font-family: arial;
font-size: 11px;
font-weight: normal;
padding-left: 15px;
}
.sh-FreightHdr {
color: #333;
font-family: Verdana !important;
font-size: 10px;
font-weight: normal;
padding: 5px 0 5px 23px;
}
.sh-Freight-Hdr {
color: #333;
font-family: Verdana !important;
font-size: 10px;
font-weight: normal;
padding-left: 13px;
}
.sh-Cnt {
color: #5d5d5d;
font-family: Arial;
font-size: small;
font-weight: normal;
padding-left: 13px;
}
.vi-frs-sh-TxtCnt {
color: #333;
font-family: Arial;
font-size: 12px;
font-weight: normal;
}
.sh-BtnTxt {
color: #333;
font-family: Verdana,Tahoma,Arial;
font-size: 12px;
font-weight: normal;
height: 24px;
margin: 0;
padding: 0 3px;
position: relative;
text-decoration: none;
top: 0;
}
.sh-bubble-position {
float: left;
padding-top: 5px;
}
.sh-del-lrge b {
font-size: 15px;
}
.sh-gspFirstLine {
color: #333;
font-family: Arial;
font-size: 15px;
padding: 25px 10px 5px 0;
}
.sh-gspSecondLine {
color: #777;
font-family: Arial;
font-size: 12px;
padding: 0 10px 15px 0;
}
Wir wissen bereits, was der erste Schritt ist: Wurde color: #999;
mehr als einmal gebraucht? Ja. Und so erstellen wir dafĂĽr eine eigene Regel:
.sh-GifCont {
color: #999;
}
… und fügen dieser die Selektoren der beiden anderen Vorkommen hinzu:
.sh-GifCont,
.sh-Info,
.sh-FrSbTxt {
color: #999;
}
Was uns auch hier wieder behilflich ist sind die Annahmen, dass unser Stylesheet bereits die Selektorenordnung benutzt, die wir wollen, und dass Regelverschiebungen unproblematisch sind. (Ich vertraue darauf, dass nachvollziehbar ist, warum eine solche Ordnung nützlich ist und wie man Probleme mit der Kaskade auflösen würde – dadurch, dass man die betroffenen Regeln nicht verschiebt bzw. zusammenführt.)
Nun kommt font-family: Verdana !important;
; diese Deklaration wird ebenfalls dreimal verwendet. Dann font-size: 10px;
– und hier gibt es wieder etwas, auf das wir aufpassen müssen, etwas, das zeigt, warum es gut ist, über »echten« Code zu gehen, nämlich das Vermeiden von Selektorenwiederholung: Diese Deklaration wird von denselben Selektoren herangezogen, die wir gerade für »Verdana« gruppiert haben. Und anstatt
.sh-GifCont,
.sh-FreightHdr,
.sh-Freight-Hdr {
font-family: Verdana !important;
}
.sh-GifCont,
.sh-FreightHdr,
.sh-Freight-Hdr {
font-size: 10px;
}
fassen wir die Regeln also entsprechend ganz zusammen:
.sh-GifCont,
.sh-FreightHdr,
.sh-Freight-Hdr {
font-family: Verdana !important;
font-size: 10px;
}
Auf diese Art arbeiten wir uns durch das ganze Stylesheet, bis wir das folgende Ergebnis erhalten:
.sh-GifCont,
.sh-Info,
.sh-FrSbTxt {
color: #999;
}
.sh-GifCont,
.sh-FreightHdr,
.sh-Freight-Hdr {
font-family: verdana !important;
font-size: 10px;
}
.sh-GifCont,
.sh-FrTxt,
.sh-TblCnt,
.sh-TblHdr,
.sh-Info,
.sh-FrSbTxt,
.sh-FreightHdr,
.sh-Freight-Hdr,
.sh-Cnt,
.vi-frs-sh-TxtCnt,
.sh-BtnTxt {
font-weight: normal;
}
.sh-GifCont {
padding: 0 10px 4px 10px;
}
.sh-GetFastImg,
.sh-float-l,
.sh-bubble-position {
float: left;
}
.sh-GetFastImg {
background-image: url('http: //ir.ebaystatic.com/pictures/aw/pics/de/viewitem/spr4VI.png');
background-position: 0 -178px;
background-repeat: no-repeat;
height: 16px;
margin-right: 4px;
width: 56px;
}
.sh-FrZip {
padding: 10px 0 0 15px;
width: 12%;
}
.sh-FrDelLoc {
padding: 10px 15px 0 10px;
width: 10%;
}
.sh-FrCnt {
padding-left: 10px;
padding-right: 0;
text-align: left;
}
.sh-FrZipCnt {
padding: 0 0 0 15px;
}
.sh-FrDelLocCnt {
padding: 0;
}
.sh-FrBtn {
padding: 5px 15px 10px 8px;
}
.sh-FrDelSite {
padding: 6px 0 0;
}
.vi-frs-sh-FrSlctr,
.sh-FrZipDiv,
.sh-FrLrnMore,
.sh-FrQuote {
display: inline;
}
.vi-frs-sh-FrSlctr {
padding: 6px 15px 0 10px;
}
.sh-FrZipDiv {
padding: 6px 15px 0 0;
}
.sh-FrTxt,
.sh-TblCnt,
.sh-FreightHdr,
.sh-Freight-Hdr,
.vi-frs-sh-TxtCnt,
.sh-BtnTxt,
.sh-gspFirstLine {
color: #333;
}
.sh-FrTxt,
.sh-TblCnt,
.sh-Info,
.sh-FrSbTxt,
.sh-Cnt,
.vi-frs-sh-TxtCnt,
.sh-gspFirstLine,
.sh-gspSecondLine {
font-family: arial;
}
.sh-FrTxt,
.sh-TblCnt,
.sh-TblHdr,
.vi-frs-sh-TxtCnt,
.sh-BtnTxt,
.sh-gspSecondLine {
font-size: 12px;
}
.sh-FrTxt,
.sh-TblCnt,
.sh-TblHdr,
.sh-FrSbTxt {
padding-left: 15px;
}
.sh-FrLrnMore {
padding: 10px 10px 10px 15px;
}
.sh-FrLnk {
margin-top: 5px;
}
.sh-Tbl {
padding: 10px;
}
.sh-TblHdr,
.sh-Cnt {
color: #5d5d5d;
}
.sh-TblHdr {
font-family: verdana;
}
.sh-Info,
.sh-FrSbTxt {
font-size: 11px;
}
.sh-FreightHdr {
padding: 5px 0 5px 23px;
}
.sh-Freight-Hdr,
.sh-Cnt {
padding-left: 13px;
}
.sh-Cnt {
font-size: small;
}
.sh-BtnTxt {
font-family: verdana,tahoma,arial;
height: 24px;
margin: 0;
padding: 0 3px;
position: relative;
text-decoration: none;
top: 0;
}
.sh-bubble-position {
padding-top: 5px;
}
.sh-del-lrge b,
.sh-gspFirstLine {
font-size: 15px;
}
.sh-gspFirstLine {
padding: 25px 10px 5px 0;
}
.sh-gspSecondLine {
color: #777;
padding: 0 10px 15px 0;
}
Bearbeiten
Was wir bisher behandelten wird wie viel komplizierte Arbeit anmuten – aber alles, was benötigt wird, sind Wille, Übung sowie das Verständnis, dass die komplizierte und langwierige Arbeit nur dann auftritt, wenn man es mit völlig unsortierten, natürlich »nassen« Stylesheets zu tun hat. Sobald wir uns über Code-Richtlinien und Optimierungsschritte einig sind, ist das Bearbeiten und Warten von Stylesheets eher einfach. Alles, was man machen muss, ist, Änderungen einmal zu prüfen.
Lassen Sie uns auch das kurz durchgehen, in einem dritten Beispiel, einem Ausschnitt von Code Responsibly. Genau, weil es so bequem ist.
h1,
h2 {
color: #000;
font-family: futurastd-book, futura, 'droid sans', 'helvetica neue', helvetica, sans-serif;
font-weight: 400;
line-height: 1.13;
}
h1 {
font-size: 1.86em;
margin: 0 0 .53em;
}
h2 {
counter-increment: counter;
font-size: 1.5em;
margin: 1em 0 0;
}
Neben der Bequemlichkeit können wir uns auch eine einfache Änderung konstruieren: Nehmen wir an, dass wir einen anderen h1
-Abstand brauchen, und dieser zufällig margin: 1em 0 0;
ist. Manch einer wird bereits bemerken, was wir machen können und sollten. Aber um ein mögliches Verfahren aufzuzeigen, hier ist, was ich in einem ansonsten komplexeren Stylesheet tun würde.
Als erstes käme das Durchführen der Änderung, deren Markierung (mein Editor – normalerweise IntelliJ IDEA – zeigt Änderungen an und macht es leicht, diese zu finden, aber ich rücke neue oder angepasste Deklarationen auch immer noch gerne kurzzeitig ein) und Testen:
h1,
h2 {
color: #000;
font-family: futurastd-book, futura, 'droid sans', 'helvetica neue', helvetica, sans-serif;
font-weight: 400;
line-height: 1.13;
}
h1 {
font-size: 1.86em;
margin: 1em 0 0;
}
h2 {
counter-increment: counter;
font-size: 1.5em;
margin: 1em 0 0;
}
Nachdem erfolgreichen Testen der Änderungen prüfe ich jeweils alle Zeilen, die modifiziert wurden, darauf, ob sie nun Wiederholung bedeuten – mit dem Prozess, den wir nun ein paar Mal durchgespielt haben. Wir würden hier nun entdecken, dass der Außenabstand für sowohl Überschriften der ersten als auch der zweiten Ebene identisch ist.
Entsprechend, auch wenn wir hier jetzt ein paar Dinge zusammenschmeiĂźen, kreieren wir nun eine Regel fĂĽr h1, h2
, bemerken aber ebenso, dass diese bereits ihre eigene Regel haben, die wir also statt dessen benutzen. Dies fĂĽhrt fĂĽr unseren Auszug zu dem folgenden Endergebnis:
h1,
h2 {
color: #000;
font-family: futurastd-book, futura, 'droid sans', 'helvetica neue', helvetica, sans-serif;
font-weight: 400;
line-height: 1.13;
margin: 1em 0 0;
}
h1 {
font-size: 1.86em;
}
h2 {
counter-increment: counter;
font-size: 1.5em;
}
Dies hoffe ich gibt nun den Vorgeschmack, dass das Warten von Stylesheets weit weniger kompliziert und einschüchternd sein sollte, als diese erstmal in Ordnung zu bringen. Das nämlich, und ich habe mir selbst nochmal eine gute Dosis meiner eigenen Medizin verabreicht, als ich Yandex optimierte, kann erstmal einige Arbeit bedeuten. Wichtige Arbeit, auf jeden Fall – darum machen wir das alles –, aber nicht unbedingt aufregende Arbeit. Niemand sagt allerdings, dass Optimierung leicht sein und Spaß machen muss.
Tipps
Schlussendlich sollen nun noch ein paar Tipps folgen (da ich alle Artikel auf meiert.com regelmäßigen Updates unterziehe, mögen diese im Laufe der Zeit ergänzt werden):
-
Suchen Sie schreibungsunabhängig. In Multi-Entwickler-Umgebungen und der Tatsache geschuldet, dass wir gewohnheits- oder zufallsbedingt mal Shift drücken mögen, kann es vorkommen, dass Deklarationen aus denselben Buchstaben, aber unterschiedlicher Groß- und Kleinschreibung bestehen. Es ist denkbar, dass dieser Unterschied wichtig ist (manche Stylesheet-Bereiche, wie generierte Inhalte oder URLs, mögen schreibungsabhängig sein), aber da es einfacher ist, die Unterschiede auszumachen, die wichtig sind, als die, die es nicht sind, sollten wir schreibungsunabhängig suchen.
eBay bot uns dafür ein gutes Beispiel: Unabhängig von den fehlenden Schriften-Fallbacks sind manche der verwendeten Schriftdeklarationen unterschiedlich in ihrer Großschreibung – wir finden zum Beispiel
font-family: Arial;
genauso wiefont-family: arial;
. Diese sollten konsolidiert werden, und entsprechend verwendet die wiederholungsbereinigte Version nur eine Deklaration in natĂĽrlich auch nur einer Schreibweise (kleingeschrieben). -
Beenden Sie jede Deklaration mit einem Semikolon (vor Produktionseinsatz). Um uns vor zu weit ausgelegten Suchabfragen zu schützen, sollten wir sicherstellen, immer das Semikolon einzuschließen (diejenigen, die sowieso immer alle Deklarationen schließen – meine Empfehlung für operative Dateien – sind hier im Vorteil). Das macht es leichter, Deklarationen einfach zu kopieren und herumzubewegen – aber erspart uns auch eine Menge falsch positiver Ergebnisse.
Die (bei aller Liebe wichtige)
!important
-Markierung ist dafür ein großartiges Beispiel – wenn wir mit »ungeschlossenen« Ausdrücken suchen, trifftborder: 0
ganz sicher auch aufborder: 0 !important
zu, und so gibt es eine schier endlose Menge anderer tatsächlich unterschiedlicher Deklarationen, die aufkommen können. Das macht unsere Arbeit sonst langwieriger und fehleranfälliger. -
Standardisieren Sie die Selektorenreihenfolge. Nicht nur begrenzen wir so Stylesheet-Entropie, sondern, da neue Regeln »automatisch« an klar definierten Stellen landen, wir erhalten eine natürliche Verteidigungslinie gegen Selektorenwiederholung – und wir wollen nicht auch noch Artikel wie diesen, um auch noch Selektoren trocken zu halten. Überlegen Sie, ob mein Entwurf zu Selektorenordnung für Sie in Frage kommt, ob Sie uns, der Webentwicklergemeinschaft, helfen können, einen Entwurf zu standardisieren oder ob Sie Ihren eigenen bauen wollen.
AnsprĂĽche an Tools
Während wir die Effizienz dieses Ansatzes und Wege, ihn zu verbessern, weiter prüfen, gibt es auch ein paar Dinge, die unsere Werkzeuge machen könnten, um bei der Vermeidung von Wiederholung zu helfen. Ebenfalls in Listenform, da wir über die Zeit mehr Anforderungen formulieren werden:
-
Editoren können uns helfen, wiederholte Deklarationen zu vermeiden, indem sie solche Deklarationen hervorheben. Persönlich denke ich, kann ein kleines »⚠« am Ende jede Zeile helfen, das in Einstellungen konfigurierbar sein sollte, zusammen mit einer Option, solche Benachrichtigungen in bestimmten Zeilen zu ignorieren oder auszuschalten. Dies könnte die Arbeit, unsere Stylesheets trocken zu halten, wesentlich einfacher machen – nicht nur, da es Redundanz einmal visuell zeigt, sondern auch, um die Problematik klarer zu machen. Wie wir gesehen haben, bestehen Stylesheets bis zu 90% aus Deklarationswiederholung.
❧ Am Ende dieser umfassenden Behandlung, wie man deklarationstrockene Stylesheets erhält und mit ihnen arbeitet, werden sicher einige Punkte noch offen sein; und dennoch hoffe ich, sind dies weniger als zuvor, als wir diese Optimierungsmaßnahme viele Jahre vernachlässigt haben. (Aus meiner Sicht hätte uns DRY CSS einen wesentlich nüchterneren Blick auf Variablen und andere Features erlaubt, die in den CSS-Spezifikationen gelandet sind.)
Diese offenen Punkte sollen natürlich berücksichtigt werden, und ich hoffe, dass Sie uns allen mit der Arbeit daran helfen können. Zum einen, wie das Yandex-Beispiel zeigte, ist die Abwesenheit von Deklarationswiederholung kein Allheilmittel. Sie hilft, CSS kompakter und leichter handhabbar zu machen, aber es gibt immer noch Extremfälle, in denen sie sie komplexer macht. Es wird nützlich sein, sich diese Extremfälle näher anzusehen. Zum anderen wird sich die eine oder andere Ungenauigkeit eingeschlichen haben. Mir fiel schon während des Schreibens auf, dass mir die Aufmerksamkeit fehlte, um absolute Präzision zu gewährleisten, als es um die genau benötigten Schritte für einen etwaigen DRY-Algorithmus ging. Vielleicht war das sogar nützlich, um niemand abzuschrecken. Vielleicht aber mangelt es an Präzision an einer wichtigen Stelle. Bitte helfen Sie, dass wir uns solcher Probleme annehmen.
Schlussendlich erachte ich die Vermeidung von Deklarationswiederholung als einen entscheidenden Weg, um mit CSS zu arbeiten. Tatsächlich sehe ich keine andere derart herausstechende Optimierungsmethode, abgesehen davon, eigene Code-Richtlinien aufzusetzen – weil ohne einen systematischen Ansatz, CSS zu schreiben, was der Fokus auf Wiederholungsvermeidung bietet, all unsere Arbeit nur Entropie erzeugt, und Entropie nicht zu hochwertigem Code führt. Hochwertiger Code aber ist, was wir als Profis in unserem Feld anstreben. Lassen Sie uns mehr auf hochwertigen Code achten, mehr Aufmerksamkeit auf DRY CSS legen und sehen, was wir alles automatisieren können, ohne unser Handwerk zu vernachlässigen.
Ăśber mich
Ich bin Jens (lang: Jens Oliver Meiert), und ich bin ein Frontend-Engineering-Leiter und technischer Autor/Verleger. Ich habe als technischer Leiter für Firmen wie Google und als Engineering Manager für Firmen wie Miro gearbeitet, bin Mitwirkender an verschiedenen Webstandards und schreibe und prüfe Fachbücher für O’Reilly und Frontend Dogma.
Ich experimentiere gerne, nicht nur in der Webentwicklung (und im Engineering Management), sondern auch in anderen Bereichen wie der Philosophie. Hier auf meiert.com teile ich einige meiner Erfahrungen und Ansichten. (Bitte sei kritisch, interpretiere wohlwollend und gib Feedback.)
Ähnliche Beiträge
Das könnte dich ebenfalls interessieren:
- 70% Wiederholung in Stylesheets: Wie wir bei der Optimierung von CSS scheitern
- The Little Book of HTML/CSS Coding Guidelines
- Was ich beim Entwickeln von Googles Frameworks gelernt habe
Die Webentwicklung gut überblicken? Probier WebGlossary.info – und The Web Development Glossary 3K. Mit Erklärungen und Definitionen zu tausenden Begriffen aus Webentwicklung, Webdesign und verwandten Feldern, aufbauend auf Wikipedia sowie MDN Web Docs. Erhältlich bei Apple Books, Kobo, Google Play Books und Leanpub.