Hier werden die Unterschiede zwischen zwei Versionen der Seite angezeigt.
Vorherige Überarbeitung | |||
— | css:guidelines [2015/12/03 19:32] (aktuell) – Externe Bearbeitung 127.0.0.1 | ||
---|---|---|---|
Zeile 1: | Zeile 1: | ||
+ | ====== CSS Guidelines ====== | ||
+ | Dies ist eine kurze, unvollständige Zusammenfassung der weit ausführlicheren, | ||
+ | |||
+ | |||
+ | |||
+ | ===== Namenskonventionen ===== | ||
+ | |||
+ | Die folgenden Namenskonventionen helfen nicht direkt beim Schreiben der CSS. Im HTML beschreiben die Klassennamen allerdings, wie einzelne Elemente miteinander im Verhältnis stehen. Dies sorgt bei größeren Projekten für mehr Transparenz und unterstützt so die Teamkollegen. | ||
+ | |||
+ | ==== Allgemein ==== | ||
+ | * Namen werden ausschließlich durch Bindestriche verknüpft, z.B. '' | ||
+ | * Bedeutet: keine Unterstriche, | ||
+ | * JavaScript: Eigene Klassennamen für JS verwenden, um unabhängig zu bleiben; z.B. '' | ||
+ | * Bei zusammenhängenden, | ||
+ | |||
+ | **Block:** ein eigenständiger Bestandteil einer Website\\ | ||
+ | **Element: | ||
+ | **Modifier: | ||
+ | |||
+ | ==== Schreibweise ==== | ||
+ | .block {}\\ | ||
+ | %%.block__element {}%%\\ | ||
+ | %%.block--modifier {}%% | ||
+ | |||
+ | ==== Regeln ==== | ||
+ | * Die Klassenbezeichnung soll nicht die DOM-Struktur abbilden (zu lange Klassennamen)!\\ | ||
+ | * Gut: Ein Modifier '' | ||
+ | * Schlecht: Verschachtelte Unterelemente '' | ||
+ | * Elemente direkt mit Klasse ansprechen: '' | ||
+ | * BEM soll nicht überall angewendet werden. Aus '' | ||
+ | * //to be continued ...// | ||
+ | |||
+ | ==== Beispiel ==== | ||
+ | <code html> | ||
+ | <div class=" | ||
+ | <ul class=" | ||
+ | <li class=" | ||
+ | <li class=" | ||
+ | <li class=" | ||
+ | </ul> | ||
+ | </ | ||
+ | </ | ||
+ | |||
+ | |||
+ | |||
+ | ===== CSS-Selektoren ===== | ||
+ | |||
+ | ==== Wahl des Selektors ==== | ||
+ | |||
+ | Die gewünschte Absicht ist immer die Grundlage für die Wahl der Selektoren. | ||
+ | |||
+ | Wenn es die Absicht ist, das Hauptmenü im Header zu gestalten, sollte man nicht | ||
+ | <code css> | ||
+ | header ul {} | ||
+ | // oder | ||
+ | .header ul {} | ||
+ | </ | ||
+ | verwenden, da dies alle eventuell im Header befindlichen Listen trifft. Wird dort nachträglich eine Liste hinzugefügt, | ||
+ | |||
+ | Besser ist daher | ||
+ | <code css> | ||
+ | .site-nav {} | ||
+ | </ | ||
+ | als eindeutiger Selektor für das gewünschte Ergebnis. | ||
+ | |||
+ | ==== Wiederverwendbarkeit ==== | ||
+ | |||
+ | Für einen Komponenten-basierten Ansatz bei der Entwicklung von Websites ist es wichtig, Klassen innerhalb eines oder auch verschiedener Projekte wiederverwenden zu können.\\ | ||
+ | Erhöhe hierfür die Anzahl der verwendeten Klassen innerhalb eines HTML-Elements und teile die CSS-Deklarationen sinnvoll auf (siehe auch " | ||
+ | <code html> | ||
+ | <div class=" | ||
+ | </ | ||
+ | |||
+ | ==== Unabhängigkeit vom Einsatzort ==== | ||
+ | |||
+ | Gestalte ein Objekt nicht abhängig davon, **wo** sie sind, sondern **was** sie sind. So kann es an anderer Stelle wiederverwendet (und ggf. mit einem Block-Modifier angepasst) werden. | ||
+ | |||
+ | Beispiel eines // | ||
+ | <code css> | ||
+ | // Schlecht: | ||
+ | .promo a {} | ||
+ | |||
+ | // Besser: | ||
+ | .btn {} | ||
+ | </ | ||
+ | |||
+ | ==== Übertragbarkeit einer Klasse ==== | ||
+ | |||
+ | Selektoren sollten nicht von HTML-Elementen abhängig sein, z.B. | ||
+ | <code css> | ||
+ | // Schlecht: | ||
+ | input.btn {} | ||
+ | </ | ||
+ | Diese Klasse ließe sich nicht auf andere HTML-Elemente anwenden und bringt in dieser Form auch keinen Mehrwert für die // | ||
+ | Falls es darum geht, zusätzliche CSS-Deklarationen bei einem bestimmten HTML-Element hinzuzufügen, | ||
+ | <code css> | ||
+ | // Okay: | ||
+ | /* Fehlermeldungen allgemein */ | ||
+ | .error { | ||
+ | color: red; | ||
+ | font-weight: | ||
+ | } | ||
+ | |||
+ | /* Falls das Element ein div ist, wird es zudem als Box gestaltet */ | ||
+ | div.error { | ||
+ | border: 1px solid; | ||
+ | padding: 10px; | ||
+ | } | ||
+ | |||
+ | |||
+ | // Besser: | ||
+ | .error-text { | ||
+ | color: red; | ||
+ | font-weight: | ||
+ | } | ||
+ | |||
+ | .error-box { | ||
+ | border: 1px solid; | ||
+ | padding: 10px; | ||
+ | } | ||
+ | </ | ||
+ | |||
+ | ==== Namensgebung ==== | ||
+ | |||
+ | Aus Gründen der Wiederverwendbarkeit sollte man Namen wählen, die sinnvoll, aber nicht zu eindeutig sind: | ||
+ | * '' | ||
+ | * '' | ||
+ | |||
+ | Während '' | ||
+ | |||
+ | Bezeichnungen sollten weder den konkreten Einsatzzweck noch die genaue Deklaration beschreiben: | ||
+ | <code css> | ||
+ | // Schlecht: Die Farbe könnte sich mal ändern | ||
+ | .blue { | ||
+ | color: blue; | ||
+ | } | ||
+ | |||
+ | // Schlecht: Ist vom Einsatzort abhängig | ||
+ | .header span { | ||
+ | color: blue; | ||
+ | } | ||
+ | |||
+ | // Schlecht: Zu spezifisch, kann schlecht wiederverwendet werden | ||
+ | .header-color { | ||
+ | color: blue; | ||
+ | } | ||
+ | |||
+ | // Gut: wiederverwendbar, | ||
+ | .highlight-color { | ||
+ | color: blue; | ||
+ | } | ||
+ | </ | ||
+ | |||
+ | |||
+ | ==== Performance von Selektoren ==== | ||
+ | |||
+ | Bei der Qualität der heutigen Browser ist es eher interessant als wichtig, wie schnell CSS-Selektoren den Knoten im DOM zugeordnet werden können. | ||
+ | |||
+ | Im Allgemeinen gilt: Je komplexer ein Selektor, desto aufwändiger ist er für den Browser zu verarbeiten. | ||
+ | |||
+ | <code css> | ||
+ | body.home div.header ul {} | ||
+ | </ | ||
+ | |||
+ | Browser lesen Selektoren von rechts nach links. Daher muss er folgende Arbeitsschritte durchführen: | ||
+ | * finde alle ul-Elemente im DOM | ||
+ | * prüfe nun, ob diese irgendwo innerhalb eines Elements mit der Klasse '' | ||
+ | * prüfe jetzt, ob die '' | ||
+ | * prüfe nun, ob sich dies alles innerhalb eines Elements mit der Klasse '' | ||
+ | * prüfe als letztes, ob '' | ||
+ | |||
+ | Hinzu kommt, dass sich zwischen '' | ||
+ | |||
+ | Logischerweise ist der folgende Selektor wesentlich effizienter: | ||
+ | <code css> | ||
+ | .primary-nav {} | ||
+ | </ | ||
+ | |||
+ | ==== Der Schlüssel-Selektor ==== | ||
+ | Da Browser die Selektoren von rechts nach links verarbeiten, | ||
+ | |||
+ | Ein Extrembeispiel ist das folgende: So einfach der Selektor zuerst erscheint - schließlich kann eine ID nur einmal vorkommen - so verzwickt wird es mit dem Schlüssel-Selektor '' | ||
+ | <code css> | ||
+ | #foo * {} | ||
+ | </ | ||
+ | Dieser würde wirklich *alle* Knoten im DOM (inkl. ''< | ||
+ | |||
+ | ==== Zusammenfassung ==== | ||
+ | |||
+ | * Wähle das gewünschte Element direkt aus, statt es vom Umfeld abhängig zu machen. | ||
+ | * Verwende viele Klassen, vermeide IDs; teile CSS-Deklarationen sinnvoll auf Klassen auf, um sie wiederverwenden zu können. | ||
+ | * Verschachtele Selektoren nicht unnötig, da es den Einsatzzweck zu genau bestimmt und dies Einfluss auf die Wiederverwendbarkeit hat. | ||
+ | * Beschränke den Selektor nicht unnötig auf ein bestimmtes HTML-Element. | ||
+ | * Halte Selektoren so kurz wie möglich. | ||
+ | |||
+ | |||
+ | |||
+ | ===== Gewichtung (Spezifizierung) ===== | ||
+ | |||
+ | Hat jeder schon erlebt - eine ID im allgemeineren Selektor und die spezielle Klasse wird ignoriert: | ||
+ | <code css> | ||
+ | #content table {} | ||
+ | |||
+ | // diese Klasse wird immer vom oberen Selektor überschrieben: | ||
+ | .my-new-table {} | ||
+ | </ | ||
+ | Was tun, wenn es zu umständlich wird, das bestehende Projekt umzubauen? Der neue Selektor muss noch eine noch stärkere Gewichtung erhalten! Und wenn ich später eine weitere Variante einführen möchte? ... damit setzt man eine Abwärtsspirale in Gang, die Selektoren müssen eine immer stärkere Gewichtung erhalten. | ||
+ | |||
+ | Am besten hält man die Gewichtung möglichst niedrig, indem man | ||
+ | * keine IDs in Selektoren verwendet, | ||
+ | * Selektoren nicht verschachtelt, | ||
+ | * Klassen nicht an HTMl-Elemente bindet, | ||
+ | * nicht mehrere Klassen im Selektor verwendet. | ||
+ | |||
+ | |||
+ | ==== !important ==== | ||
+ | |||
+ | Wer die Gewichtung niedrig hält, wird '' | ||
+ | Seine Daseinsberechtigung hat das Schlüsselwort vor allem bei proaktivem Gebrauch, also wenn es nichts reparieren soll, sondern die Funktion von Vornhinein sicherstellen: | ||
+ | <code css> | ||
+ | .hidden { | ||
+ | display: none !important; | ||
+ | } | ||
+ | </ | ||
+ | Wer diese Klasse an einem HTML-Element verwendet, möchte auf jeden Fall, dass es nicht angezeigt wird. | ||
+ | |||
+ | |||
+ | ==== Gewichtung steuern ==== | ||
+ | |||
+ | Irgendwann kommt immer der Punkt, an dem man trotz geringer Gewichtung etwas tricksen muss. | ||
+ | |||
+ | Wenn ein Selektor mit zwei Klassen überschrieben werden muss, kann man einfach den Schlüssel-Selektor zweimal notieren (ohne Leerzeichen). So bleibt auch die Übertragbarkeit in andere Seitenbereiche gegeben. | ||
+ | |||
+ | <code css> | ||
+ | // muss überschrieben werden: | ||
+ | .header .nav {} | ||
+ | |||
+ | // Lösung: dieselbe Klasse zweimal im Selektor, ohne Leerzeichen: | ||
+ | .nav.nav {} | ||
+ | </ | ||
+ | |||
+ | Falls mal ein HTML-Element mit ID gestaltet werden muss, dessen Quellcode man nicht um eine Klasse ergänzen kann, hilft folgender Trick: | ||
+ | |||
+ | <code css> | ||
+ | // Handhabung der ID als Attribut: | ||
+ | [id=" | ||
+ | </ | ||
+ | |||
+ | |||
+ | |||
+ | ===== Architekturprinzipien ===== | ||
+ | |||
+ | CSS ist keine Programmiersprache, | ||
+ | |||
+ | Architekturen sind jeweils allumfassende Sammlungen von Richtlinien, | ||
+ | |||
+ | Die gewählte Architektur sollte | ||
+ | * eine vernünftige, | ||
+ | * Änderungen ermöglichen, | ||
+ | * Skalierung der Codebasis sicherstellen, | ||
+ | * Wiederverwendbarkeit und Effizienz fördern, | ||
+ | * Produktivität steigern. | ||
+ | |||
+ | Für gewöhnlich führt dies zu einer Klassen- und Komponenten-basierten Arbeitsweise, | ||
+ | |||
+ | ==== Objektorientierung (OOCSS) ==== | ||
+ | |||
+ | Bei objektorientiertem CSS wird das User Interface in **Struktur** und **Erscheinungsbild** unterteilt: UI-Komponenten werden auf ihre formgebenden Teile (Abstände, Layout, ...) reduziert und können über separate Klassen um ihre gewünschte Gestaltung (Farben, Schriften, ...) ergänzt werden. | ||
+ | |||
+ | Man kann sich die Struktur als ein Grundgerüst vorstellen, eine wiederverwendbare Vorlage ohne weitere Gestaltung. | ||
+ | <code css> | ||
+ | .btn { | ||
+ | display: inline-block; | ||
+ | padding: 1em 2em; | ||
+ | vertical-align: | ||
+ | } | ||
+ | |||
+ | .btn--positive { | ||
+ | background-color: | ||
+ | color: white; | ||
+ | } | ||
+ | |||
+ | .btn--negative { | ||
+ | background-color: | ||
+ | color: white; | ||
+ | } | ||
+ | </ | ||
+ | <code html> | ||
+ | <button class=" | ||
+ | </ | ||
+ | Die '' | ||
+ | |||
+ | |||
+ | ==== Das Single-Responsibility-Prinzip ==== | ||
+ | |||
+ | Laut diesem Prinzip hat jede Klasse nur eine fest definierte Aufgabe zu erfüllen. Bezogen auf CSS werden Deklarationen in kleinere Blöcke aufgeteilt. Jede Deklaration ist nur noch für einen Zweck da und wird für das gewünschte Ergebnis mit weiteren kombiniert. | ||
+ | <code css> | ||
+ | .error-message { | ||
+ | display: block; | ||
+ | padding: 10px; | ||
+ | border-top: 1px solid #f00; | ||
+ | border-bottom: | ||
+ | background-color: | ||
+ | color: #f00; | ||
+ | font-weight: | ||
+ | } | ||
+ | |||
+ | .success-message { | ||
+ | display: block; | ||
+ | padding: 10px; | ||
+ | border-top: 1px solid #0f0; | ||
+ | border-bottom: | ||
+ | background-color: | ||
+ | color: #0f0; | ||
+ | font-weight: | ||
+ | } | ||
+ | </ | ||
+ | Diese beiden Klassen steuern Layout, Struktur und Gestaltung; viele Deklarationen wiederholen sich. Wenn man dieses CSS anhand von OOCSS umschreibt und dabei noch das Single-Responsibility-Prinzip anwendet, erhält man vier kleinere Klassen: | ||
+ | <code css> | ||
+ | .box { | ||
+ | display: block; | ||
+ | padding: 10px; | ||
+ | } | ||
+ | |||
+ | |||
+ | .message { | ||
+ | border-style: | ||
+ | border-width: | ||
+ | font-weight: | ||
+ | } | ||
+ | |||
+ | .message--error { | ||
+ | background-color: | ||
+ | color: #f00; | ||
+ | } | ||
+ | |||
+ | .message--success { | ||
+ | background-color: | ||
+ | color: #0f0; | ||
+ | } | ||
+ | </ | ||
+ | Jetzt haben wir ein allgemeines " | ||
+ | |||
+ | |||
+ | ==== Das Open-Closed-Prinzip ==== | ||
+ | |||
+ | Dieses Prinzip gehört ebenfalls zur objektorientierten Programmierung. Es besagt, dass Module **für Erweiterungen offen** sein sollen, aber **geschlossen gegenüber Modifikationen**. | ||
+ | |||
+ | Bei CSS werden Anpassungen demnach nicht direkt an der bestehenden Klasse vorgenommen, | ||
+ | <code css> | ||
+ | // Falsch: | ||
+ | .box { | ||
+ | display: block; | ||
+ | padding: 10px; | ||
+ | } | ||
+ | .content .box { | ||
+ | padding: 20px; | ||
+ | } | ||
+ | |||
+ | // Richtig: | ||
+ | .box { | ||
+ | display: block; | ||
+ | padding: 10px; | ||
+ | } | ||
+ | .box--large { | ||
+ | padding: 20px; | ||
+ | } | ||
+ | </ | ||
+ | Beim schlechten Beispiel wird die Anpassung über einen unnötig stark gewichteten, | ||
+ | |||
+ | |||
+ | ==== DRY: Don't Repeat Yourself! ==== | ||
+ | |||
+ | Laut diesem Prinzip sollte man Wiederholungen auf ein nötiges Minimum reduzieren. Man darf es nicht übertreiben, | ||
+ | |||
+ | <code css> | ||
+ | .btn { | ||
+ | display: inline-block; | ||
+ | padding: 1em 2em; | ||
+ | font-weight: | ||
+ | } | ||
+ | .page-title { | ||
+ | font-size: 3rem; | ||
+ | line-height: | ||
+ | font-weight: | ||
+ | } | ||
+ | .user-profile__title { | ||
+ | font-size: 1.2rem; | ||
+ | line-height: | ||
+ | font-weight: | ||
+ | } | ||
+ | </ | ||
+ | Obwohl hier dreimal '' | ||
+ | Wenn jedoch z.B. ein Webfont verwendet wird, der bei jeder Nutzung über '' | ||
+ | <code css> | ||
+ | @mixin my-web-font() { | ||
+ | font-family: | ||
+ | font-weight: | ||
+ | } | ||
+ | |||
+ | .btn { | ||
+ | display: inline-block; | ||
+ | padding: 1em 2em; | ||
+ | @include my-web-font(); | ||
+ | } | ||
+ | .page-title { | ||
+ | font-size: 3rem; | ||
+ | line-height: | ||
+ | @include my-web-font(); | ||
+ | } | ||
+ | .user-profile__title { | ||
+ | font-size: 1.2rem; | ||
+ | line-height: | ||
+ | @include my-web-font(); | ||
+ | } | ||
+ | </ | ||
+ | Wenn der Webfont nun ausgetauscht werden soll und dadurch auf '' | ||
+ | |||
+ | Man sollte also nur Wiederholungen reduzieren, wo eine thematische Verbindung besteht. |