Code Guide door @mdo

Standaarden voor het ontwikkelen van flexibele, bestendige, en duurzame HTML en CSS.

Inhoudsopgave

HTML

CSS

Gouden regel

Hanteer altijd deze, of je eigen, richtlijnen die je afgesproken hebt. Mocht je iets vinden dat niet klopt – of dat nou klein of groot is – laat het weten. Wil je iets toevoegen of bijdragen aan deze Code Guide? Open een issue op GitHub.

Iedere regel code moet eruit zien alsof het door één en dezelfde persoon geschreven is, ongeacht het aantal bijdragers.

HTML

Syntax

<!DOCTYPE html>
<html>
  <head>
    <title>Paginatitel</title>
  </head>
  <body>
    <img src="images/company-logo.png" alt="Company">
    <h1 class="hello-world">Hallo, wereld!</h1>
  </body>
</html>

HTML5-doctype

Dwing in alle browsers standards mode en een consistentere weergave af door dit simpele doctype toe te voegen aan het begin van iedere HTML-pagina.

<!DOCTYPE html>
<html>
  <head>
  </head>
</html>

Taalattribuut

Uit de HTML5-spec:

Het wordt auteurs aangeraden om een lang-attribuut op te geven bij het hoofd-HTML-element, die de taal van het document vastlegt. Dit helpt voorleesprogramma’s bij het bepalen van de juiste uitspraak, vertaalprogramma’s bij het bepalen welke regels moeten worden gebruikt, enzovoorts.

Lees meer over het lang attribuut in de spec.

Ga naar Sitepoint voor een lijst van taalcodes.

<html lang="nl-nl">
  <!-- ... -->
</html>

IE-compatibiliteitsmodus

Internet Explorer ondersteunt het gebruik van een documentcompatibiliteits-<meta>-tag waarmee je kunt vastleggen voor welke versie van IE de pagina moet worden weergegeven. Tenzij de omstandigheden iets anders vragen, is het het beste om IE de meest actueel ondersteunde modus te laten gebruiken met edge-modus.

Lees voor meer informatie dit geweldige Stack Overflow-artikel.

<meta http-equiv="X-UA-Compatible" content="IE=Edge">

Karakterencodering

Zorg snel en gemakkelijk voor de juiste weergave van je content door een expliciete karakterencodering te declareren. Hiermee kun je het gebruik van karakter-entities in je HTML vermijden, mits hun encoding overeenkomt met die van het document (meestal UTF-8).

<head>
  <meta charset="UTF-8">
</head>

CSS- en JavaScript-includes

Volgens de HTML5-spec is het niet nodig om een type op te geven wanneer CSS- en JavaScript-bestanden worden ingevoegd, omdat standaard respectievelijk text/css en text/javascript aangenomen worden.

Links naar HTML5-specs

<!-- Externe CSS -->
<link rel="stylesheet" href="code-guide.css">

<!-- CSS binnen document -->
<style>
  /* ... */
</style>

<!-- JavaScript -->
<script src="code-guide.js"></script>

Praktische bruikbaarheid boven zuiverheid

Streef ernaar om HTML-standaarden en -semantiek te behouden, maar niet ten koste van praktische bruikbaarheid. Gebruik als dat kan een minimale hoeveelheid opmaak met zo min mogelijk verwikkelingen.

Attribuutvolgorde

Code is makkelijker te lezen als HTML-attributen in deze specifieke volgorde genoemd worden.

Klassen zorgen voor geweldige herbruikbare componenten, dus deze komen het eerst aan bod. Id’s zijn specifieker en dienen spaarzaam gebruikt te worden (bijvoorbeeld voor bladwijzers binnen pagina’s), en komen dus als tweede.

<a class="..." id="..." data-toggle="modal" href="#">
  Voorbeeldlink
</a>

<input class="form-control" type="text">

<img src="..." alt="...">

Boolean-attributen

Een boolean-attribuut is een attribuut dat geen waarde nodig heeft. In XHTML was het nodig om een waarde te declareren, maar in HTML5 is dit niet het zo.

Raadpleeg de WhatWG-sectie over boolean-attributen voor meer informatie:

De aanwezigheid van een boolean-attribuut op een element stelt de true-waarde voor, en de afwezigheid van het attribuut de false-waarde.

Als je de attribuutwaarde dan toch moet opnemen (en dat is echt niet nodig), kun je deze WhatWG-richtlijn opvolgen:

Als het attribuut aanwezig is, moet zijn waarde de lege string zijn of [...] de canonieke naam van het attribuut, zonder spaties voor en na.

Kortom: voeg geen waarde toe.

<input type="text" disabled>

<input type="checkbox" value="1" checked>

<select>
  <option value="1" selected>1</option>
</select>

Minder opmaak

Voorkom, waar mogelijk, overbodige ouder-elementen bij het schrijven van HTML. Vaak vereist dit iteraties en refactoring, maar het levert wel minder HTML op. Neem het volgende voorbeeld:

<!-- Niet zo geweldig -->
<span class="avatar">
  <img src="...">
</span>

<!-- Beter -->
<img class="avatar" src="...">

Met JavaScript gegenereerde opmaak

Het schrijven van opmaak in een JavaScript-bestand zorgt ervoor dat de content moeilijker te vinden is, moeilijker te wijzigen is, en minder snel wordt verwerkt. Vermijd het als dat kan.

CSS

Syntax

Vragen over hier genoemde termen? Zie de syntaxsectie van het Cascading Style Sheets-artikel op Wikipedia.

/* Slechte CSS */
.selector, .selector-secondary, .selector[type=text] {
  padding:15px;
  margin:0px 0px 15px;
  background-color:rgba(0, 0, 0, 0.5);
  box-shadow:0px 1px 2px #CCC,inset 0 1px 0 #FFFFFF
}

/* Goede CSS */
.selector,
.selector-secondary,
.selector[type="text"] {
  padding: 15px;
  margin-bottom: 15px;
  background-color: rgba(0,0,0,.5);
  box-shadow: 0 1px 2px #ccc, inset 0 1px 0 #fff;
}

Declaratievolgorde

Property-declaraties die met elkaar te maken hebben, dienen in de volgende volgorde gegroepeerd te worden:

  1. Positionering
  2. Boxmodel
  3. Typografisch
  4. Visueel

Positionering komt als eerste, omdat dat een element uit de normale flow van het document kan verwijderen en stijlen die te maken hebben met het boxmodel kan overschrijven. Het boxmodel komt daarna, omdat het de afmetingen en plaatsing van een component voorschrijft.

Al het andere vindt plaats binnen het component of zonder invloed te hebben op de vorige twee groepen, en komt daarom als laatst.

Voor een complete lijst van properties en hun volgordes, zie Recess.

.declaration-order {
  /* Positionering */
  position: absolute;
  top: 0;
  right: 0;
  bottom: 0;
  left: 0;
  z-index: 100;

  /* Box-model */
  display: block;
  float: right;
  width: 100px;
  height: 100px;

  /* Typografie */
  font: normal 13px "Helvetica Neue", sans-serif;
  line-height: 1.5;
  color: #333;
  text-align: center;

  /* Visueel */
  background-color: #f5f5f5;
  border: 1px solid #e5e5e5;
  border-radius: 3px;

  /* Overig */
  opacity: 1;
}

Gebruik geen @import

Vergeleken met <link>s is @import langzamer, voegt het extra paginarequests toe, en kan het andere onvoorziene problemen veroorzaken. Vermijd ze, en kies een alternatieve benadering:

Lees voor meer informatie dit artikel van Steve Souders.

<!-- Gebruik link-elementen -->
<link rel="stylesheet" href="core.css">

<!-- Vermijd @imports -->
<style>
  @import url("more.css");
</style>

Mediaqueryplaatsing

Plaats mediaquery’s zo dicht mogelijk bij de regels waar ze over gaan. Zet ze niet allemaal in een aparte stylesheet of aan het einde van het document; dat maakt het in de toekomst alleen maar makkelijker voor mensen om ze te vergeten. Dit is een typische setup.

.element { ... }
.element-avatar { ... }
.element-selected { ... }

@media (min-width: 480px) {
  .element { ...}
  .element-avatar { ... }
  .element-selected { ... }
}

Prefixed properties

Spring bij het gebruik van vendor-specifieke properties iedere property zo in dat de declaratiewaarden verticaal uitgelijnd zijn en meerdere regels moeiteloos tegelijk gewijzigd kunnen worden.

Gebruik in TextMate Text → Edit Each Line in Selection (⌃⌘A). Gebruik in Sublime Text 2 Selection → Add Previous Line (⌃⇧↑) en Selection → Add Next Line (⌃⇧↓).

/* Prefixed properties */
.selector {
  -webkit-box-shadow: 0 1px 2px rgba(0,0,0,.15);
          box-shadow: 0 1px 2px rgba(0,0,0,.15);
}

Enkele declaraties

In gevallen waarin een verzameling regels slechts één declaratie bevat, is het goed voor de leesbaar- en wijzigbaarheid om regeleindes te verwijderen. Iedere verzameling CSS-regels met meerdere declaraties moet worden opgesplitst in meerdere regels.

De voornaamste reden hiervoor is foutdetectie. Neem bijvoorbeeld een CSS-validator die een fout meldt op regel 183. Met een enkele declaratie is die niet te missen. Als er meerdere declaraties zijn aparte regels een absolute must als je niet gek wilt worden.

/* Enkele declaraties op één regel */
.span1 { width: 60px; }
.span2 { width: 140px; }
.span3 { width: 220px; }

/* Meerdere declaraties, één per regel */
.sprite {
  display: inline-block;
  width: 16px;
  height: 15px;
  background-image: url(../img/sprite.png);
}
.icon           { background-position: 0 0; }
.icon-home      { background-position: 0 -20px; }
.icon-account   { background-position: 0 -40px; }

Korte notatie

Streef ernaar om het gebruik van korte notaties te beperken tot gevallen waarin alle waarden expliciet opgegeven moeten worden. Properties waarvoor te vaak de korte notatie wordt gebruikt, zijn:

Vaak is het niet nodig om alle mogelijke waarden met de korte notatie op te geven. Voor HTML-koppen worden bijvoorbeeld alleen de top- en bottom-margin opgegeven. Overschrijf in zulke gevallen dus alleen die twee waarden. Overgebruik van de korte notatie voor properties leidt vaak tot slordigere code met onnodige overrides en onbedoelde zij-effecten.

Het Mozilla Developer Network heeft een heel goed artikel over shorthand properties for hen die niet bekend zijn met notatie en gedrag.

/* Slecht voorbeeld */
.element {
  margin: 0 0 10px;
  background: red;
  background: url("image.jpg");
  border-radius: 3px 3px 0 0;
}

/* Goed voorbeeld */
.element {
  margin-bottom: 10px;
  background-color: red;
  background-image: url("image.jpg");
  border-top-left-radius: 3px;
  border-top-right-radius: 3px;
}

Nesting in Less en Sass

Voorkom onnodige nesting. Dat je kunt nesten, betekent niet dat je dat ook altijd moet doen. Overweeg om alleen te nesten als je stijlen moet beperken tot een parent, en er meerdere elementen zijn om te nesten.

Meer informatie:

// Zonder nesting
.table > thead > tr > th {  }
.table > thead > tr > td {  }

// Met nesting
.table > thead > tr {
  > th {  }
  > td {  }
}

Operators in Less en Sass

Plaats voor een betere leesbaarheid alle wiskundige bewerkingen tussen haakjes, met een enkele spatie tussen waarden, variabelen, en operators.

// Slecht voorbeeld
.element {
  margin: 10px 0 @variable*2 10px;
}

// Goed voorbeeld
.element {
  margin: 10px 0 (@variable * 2) 10px;
}

Commentaar

Code wordt geschreven en onderhouden door mensen. Zorg ervoor dat je code beschrijvend is, goed voorzien is van commentaar, en toegankelijk is voor anderen. Echt goed codecommentaar vertelt iets over de context of het doel ervan. Herhaal niet simpelweg een component- of klassenaam.

Gebruik volledige zinnen voor uitgebreider commentaar en korte zinnen voor algemene opmerkingen.

/* Slecht voorbeeld */
/* Modale header */
.modal-header {
  ...
}

/* Goed voorbeeld */
/* Omhullend element voor .modal-title en .modal-close */
.modal-header {
  ...
}

Klassenamen

Veel van deze zelfde regels kunnen ook toegepast worden bij het aanmaken van Sass- en Less-variabelenamen.

/* Slecht voorbeeld */
.t { ... }
.red { ... }
.header { ... }

/* Goed voorbeeld */
.tweet { ... }
.important { ... }
.tweet-header { ... }

Selectors

Verder lezen:

/* Slecht voorbeeld */
span { ... }
.page-container #stream .stream-item .tweet .tweet-header .username { ... }
.avatar { ... }

/* Goed voorbeeld */
.avatar { ... }
.tweet-header .username { ... }
.tweet .avatar { ... }

Organisatie

/*
 * Component sectiekop
 */

.element { ... }


/*
 * Component sectiekop
 *
 * Soms moet je optionele context meenemen voor het gehele component. Doe dat hier als dat belangrijk genoeg is.
 */

.element { ... }

/* Contextueel subcomponent of modifier */
.element-heading { ... }

Tekstverwerkervoorkeuren

Stel je tekstverwerker als volgt in om vaak voorkomende code-inconsistenties en vieze diffs te vermijden

Overweeg het documenteren en toepassen van deze voorkeuren in het .editorconfig-bestand van je project. Voor een voorbeeld, zie dat in Bootstrap. Leer meer over EditorConfig.