Jens Oliver Meiert

DRY CSS: Wie man jede Deklaration nur einmal verwendet

Artikel vom 2. Januar 2018. ISSN 1614-3124, #56.

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

  1. Allgemeine Schritte
  2. Sonderfälle
  3. Beispiele
    1. Optimieren I
    2. Optimieren II
    3. Bearbeiten
  4. Tipps
  5. Ansprüche an Tools

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.

  1. Schreiben Sie CSS auf die herkömmliche und natürliche Weise.
  2. Entscheiden Sie über DRY-Grenzen: Abschnitts- (funktional separate aber gekennzeichnete CSS-Bereiche) oder Datei-/@media-Ebene? (Ich selbst arbeite auf der Datei-/@media-Ebene, das heißt, ich »trockne« im größtmöglichen Bereich.)
  3. Formatieren Sie Code konsistent, da border:0;, border: 0; und border: none; alle dasselbe bedeuten aber die Aufgabe, Duplikate zu finden, erheblich erschweren.
  4. 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.
  5. 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 auf einzelne Abschnitte beschränkt wird, achten Sie darauf, den Suchradius auf diese Abschnitte zu begrenzen).
    • 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.
  6. (Wiederholen Sie Schritte 4 und 5.)
  7. 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.

  1. 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.

  2. Strenge des Ansatzes oder Ausnahmenregelung: Wenn wir sehr 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 wirkliches 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 beziehungsweise 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 sehr 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 wirklich 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):

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:

❧ 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 niemanden 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 den Autor

Jens Oliver Meiert, Foto vom 13. April 2018.

Jens Oliver Meiert ist ein Autor und Entwickler (O’Reilly, W3C, ex-Google). Er spielt mit Philosophie, Kunst und Abenteuer. Hier auf meiert.com teilt und verallgemeinert und übertreibt er einige seiner Gedanken und Erfahrungen. (Vorsicht: Er liegt öfter falsch, als er es haben will.)

Mehr Jens gibt es im Archiv und bei Goodreads. Wenn Sie eine Frage oder ein Anliegen (oder eine Empfehlung) zu dem haben, was er schreibt, senden Sie gerne jederzeit eine Nachricht.

Ähnliche Themen

Das könnte Sie ebenfalls interessieren:

Schwerpunkt:

Sagen Sie hallo auf Twitter oder XING.

Fehler entdeckt? E-Mail an jens@meiert.com.

Sie sind hier: StartseitePublikationen → DRY CSS: Wie man jede Deklaration nur einmal verwendet

Stand: 2. Januar 2018

»Der Zweck heiligt nicht die Mittel