CSS Richtlijnen

Deze stijlgids is bedoeld voor iedereen die in aanraking komt met het schrijven van CSS. De richtlijnen die hier genoemd staan zijn een sterke aanmoediging voor het gebruik van bestaande, algemene en verstandige patronen.

Dit is een document in ontwikkeling en nieuwe ideeën zijn altijd welkom.

Introductie

CSS is geen mooie taal. Hoewel het eenvoudig is om te leren en mee aan de slag te gaan, kan het al snel een probleem worden op grotere schaal. We kunnen niet veranderen hoe CSS werkt, maar we kunnen wel de manier waarop we CSS schrijven en structuren aanpassen.

Als we werken aan grote, langlopende projecten, met meerdere ontwikkelaars van verschillende specialiteiten en capaciteiten, is het belangrijk dat we allemaal op dezelfde manier werken zodat o.a.:

In dit document staan verschillende aanbevelingen, regels en technieken die we kunnen gebruiken om ons te helpen aan al deze doelen te voldoen.

Syntax & opmaak

Het is prettig om met code te werken die er netjes uit ziet. Het is voor andere teamleden ook uitnodigend om het mooi te houden. Lelijke code geeft een verkeerd voorbeeld.

Een standaard manier van CSS schrijven (letterlijk schrijven) helpt mee om alles netjes te houden. Het betekent ook dat code er altijd hetzelfde uit ziet en vertrouwd aanvoelt bij alle leden van het team.

80 karakters breed

Waar mogelijk, limiteer je CSS tot maximaal 80 karakters breed.

/**
    * Dit is een lang commentaar-blok. Hier beschrijf ik in detail de CSS die hierna
    * volgt. Dit is zo'n lang commentaar-blok dat deze makkelijk over de 80 karakter
    * grens gaat, en dus opgedeeld wordt over meerdere regels.
    */

Anatomie van een stijlregel

Voordat we het hebben over de daadwerkelijke stijlregels, laten we eerst de relevante terminologie benoemen:

selector {
        eigenschap: waarde;
        /*  <-- declaratie --->  */
    }

Uit het onderstaande voorbeeld,

.box, .box--promo,
    .widget {
        display: block;
        background-color: #c0ffee;
        color: #decaff;
    }

kun je het volgende afleiden:

Multi-line CSS

Zoals je ook in het vorige voorbeeld ziet, schrijven we CSS altijd over meerdere regels, behalve in hele specifieke gevallen. Hier zijn een aantal voordelen aan:

Uitzonderingen en kleine afwijkingen

Uitzonderingen zijn stijlregels die maar één declaratie bevatten. Dit soort stijlregels kunnen beter op één regel, omdat je dan de selectors snel wilt kunnen scannen. Deze zijn in dit geval belangrijker dan de daadwerkelijke eigenschappen en waardes.

.icon {
        display: inline-block;
        width: 16px;
        height: 16px;
        background: url(img/icon-sprite.png);
    }
    .icon--1 { background-position: 0 0; }
    .icon--2 { background-position: 0 -16px; }
    .icon--3 { background-position: 0 -32px; }
    .icon--4 { background-position: 0 -48px; }

Volgorde van declaraties

Als je er op kan rekenen dat bepaalde properties altijd op dezelfde plaats staan, begrijp je de CSS een stuk sneller (minder zoeken). Dit is belangrijk bij het werken in een team en helpt bij het lezen van code waar je minder bekend mee bent, omdat je het niet zelf geschreven hebt.

De voorkeur gaat uit naar het groeperen van gerelateerde eigenschappen. Structureel belangrijke eigenschappen (b.v. positionering en box-model) worden vóór typografische-, achtergronds- en kleureigenschappen gedeclareerd.

In onderstaand stuk code zie je een voorbeeld van juiste groepering van eigenschappen in een selector met meerdere declaraties. (Het commentaar en de witregel na elk blokje kun je uiteraard weglaten).

selector {
        /* Positionering */
        position: absolute;
        z-index: 10;
        top: 0;
        right: 0;
        /* Display & Box Model */
        display: inline-block;
        overflow: hidden;
        box-sizing: border-box;
        width: 200px;
        height: 100px;
        margin: 10px;
        padding: 10px;
        border: 10px solid #333;
        border-radius: 4px;
        box-shadow: 3px 0 10px 0 rgba(50, 50, 50, 0.5);

        /* Kleuren */
        background: #000;
        color: #fff;

        /* Text */
        font-family: sans-serif;
        font-size: 16px;
        line-height: 1.4em;
        text-align: right;
        text-decoration: none;

        /* Overig */
        cursor: pointer;
        white-space: pre;
        transition: all 0.3s ease;
    }

Kleuren

Bij het typen van een kleur in hexadecimale notering, gebruik je kleine letters. Dit omdat we vaak kleurcodes kopiëren uit Photoshop, en we dan één formatering aanhouden. Je mag 3-cijferparen of 6-cijferparen gebruiken, maar waar mogelijk de 3-cijfer versie. Dit bespaard een paar bytes.

color: #ff4e50; /* goed */
    color: #FF4E50; /* fout */

    color: #aaa;    /* goed */
    color: #AAA;    /* fout */

Afmetingen

Bij het noteren van afmetingen, width, height, margin, padding, border gebruik je altijd een eenheid (b.v. em, px of %). Als de waarde 0 is, laat je de eenheid weg.

width: 12px;    /* goed */
    width: 12%;     /* goed */
    width: 12em;    /* goed */
    width: 0;       /* goed */
    width: 12;      /* fout */
    width: 0px;     /* fout */

Notatie van aanhalingstekens

Gebruik bij voorkeur enkele (' ') i.p.v. dubbele (" ") aanhalingstekens.
De URL-waarde, van b.v. de background-property behoeft geen aanhalingstekens.

font-family: "open sans", arial, sans-serif;    /* fout */
    font-family: 'open sans', arial, sans-serif;    /* goed */
    background: url('/Img/sprite.png');             /* fout */
    background: url(/Img/sprite.png);               /* goed */

Shorthand notaties

Wanneer mogelijk is het gebruik van shorthand notaties gewenst. Deze kunnen worden gebruikt bij o.a. background, border, margin, padding, list-style en font declaraties.

/* goed */
    background: #e2fda1 url(/img/icon.png) no-repeat left top;
    /* fout */
    background-color: #e2fda1;
    background-image: url(/img/icon.png);
    background-repeat: no-repeat;
    background-position: left top;

    /* goed */
    border: 2px dashed #f90;
    /* fout */
    border-width: 2px;
    border-style: dashed;
    border-color: #f90;

    /* goed */
    padding: 5px 10px 20px;
    /* fout */
    padding-top: 5px;
    padding-right: 10px;
    padding-bottom: 20px;
    padding-left: 10px;

Vermijd onnodige shorthand declaraties

Wel moet je uitkijken dat je hiermee geen eerder gezette waardes overschrijft. Als je b.v. alleen maar de margin-bottom wilt wijzigen, doe je dat het best zonder de shorthand notatie.

/* gevaarlijk */
    margin: 0 0 20px;
    /* in dit geval beter */
    margin-bottom: 20px;

Pas op voor onopzettelijke CSS resets

Elke keer dat je een shorthand oplossing gebruikt in CSS, zet je alle waarden voor alle eigenschappen van het element waar het om gaat. Als je dus een waarde bepaald kun je deze in een regel later per ongeluk weer resetten.

.module {
        background-repeat: no-repeat;
        background: url(test.jpg);
        /* Oeps! Hier wordt de repeat overschreven. */
    }

Zinvolle witruimte

Door het verstandig gebruik van witruimte tussen de stijlregels kunnen we een heleboel informatie verstrekken.

.box { eigenschap: waarde; }
    .box__hdr { eigenschap: waarde; }
    .box--special { eigenschap: waarde; }

    /* Widgets
    ------------------------------------- */
    .widget { eigenschap: waarde; }

Inspringen

Voor het inspringen gebruiken we tabs, een tab is gelijk aan 4 spaties en is binnen Microsoft visual studio vast in te stellen. Dit kun je doen onder het menu 'Tools' > 'Options', in het scherm zoals hieronder in het voorbeeld weergegeven kun je de waardes instellen. Deze stellen we standaard in op 4.

HTML

Aangezien HTML en CSS onafscheidelijk aan elkaar verbonden zijn, moeten we ook hierover wat richtlijnen benoemen.

Gebruik altijd aanhalingstekens bij attributen, al werken ze ook zonder. Dit verkleint de kans op ongelukken, en is ook het meest vertrouwd bij ontwikkelaars.

<div class=box>  <!-- dit zal gewoon werken -->
    <div class="box">  <!--  maar dit geniet de voorkeur -->

Bij meerdere waardes in een class attribuut, scheid je deze met 2 spaties. Dit doen we om de leesbaarheid te vergroten. Zeker bij meer dan 2 classes is dit erg prettig.

<li class="widget__item box box--large push-left"> <!-- slecht leesbaar -->
    <li class="widget__item  box  box--large  push-left"> <!-- Dit is beter -->

Ook in de HTML is zinvolle witruimte tussen bepaalde blokken aan te raden om ze visueel van elkaar te scheiden. Dit zorgt dat ontwikkelaars snel losse delen van de DOM kunnen scannen.

Commentaar

Goed becommentarieerde code is extreem belangrijk. Bij een groot project is het soms al lastig om de stukken CSS die je zelf schrijft te onthouden en begrijpen, laat staan die van een collega. Daarom wordt commentaar sterk aangemoedigd.

CSS heeft meer comments nodig

Door alleen naar een stuk CSS te kijken is het is vaak moeilijk om te onderscheiden

Omdat met alleen de CSS vaak niet het hele plaatje duidelijk is, is het een taal die echt baat heeft bij veel commentaar. Alles dat niet vanzelf spreekt vanuit de CSS-code zou je kunnen voorzien van commentaar. Ga dus niet alles becommentariëren, alleen als het verduidelijking vereist.

Het commentaar mag dan meteen achter de declaratie staan.

Dit commentaarblok komt dan voorafgaand aan de selector. Hou bij deze blokken ook rekening met de 80 karakters regel.

Secties en modules

Begin ieder nieuwe sectie of module met een titel commentaarblok.

/* Sectie of module titel commentaarblok
    -------------------------------------------- */

Specifieke declaratie

Soms is het nodig om bij een specifieke declaratie commentaar toe te voegen om bijvoorbeeld een "hack" toe te lichten.

.google-marker {
        color: #222 !important; /* Nodig omdat op het element een inline style staat. */
    }

Meerdere regels

Als je een langere uitleg nodig hebt, die over meerdere regels gaat, gebruik je het best een groep commentaarblok:

/*
    * Groep commentaarblok.
    * Ideaal voor uitleg over meerdere regels en documentatie die uitleg vereist
    * over een bepaalde module
    */
    selector {
        eigenschap: waarde;
    }

Comment Summary

Om een toelichting te geven aan bepaalde CSS blokken is het mogelijk en overzichtelijk om een comment summary toe te passen. Hiermee kun je op 1 plek in de CSS puntsgewijs een toelichting geven op de CSS die daarop volgt doormiddel van een comment.

/*
    * [1] Background-color for some element
    * [2] Font-size for some text
    * [3] Height & Width for a content area
    */
    selector {
        background-color: #000; /*[1]*/
        font-size: 14px; /*[2]*/
        height: 50%; /*[3]*/
        width: 50%; /*[3]*/
    }

Naamgevingsconventies

Naamgevingsconventies zijn erg nuttig om de CSS heel strikt, transparant en informatief te maken. Het maakt duidelijk

Gescheiden met koppelteken

Selector benamingen altijd in lowercase, indien nodig gescheiden met een koppelteken (-).

.widget {}
    .main-menu {}
    .portaal-user-login {}

Camel case en een liggend streepje (_) worden niet gebruikt voor normale classes. Onderstaande voorbeelden zijn dus niet juist:

.headerLogo {} /* Camelcasing is niet gewenst in CSS*/
    .main_menu {} /* Liggend streepje niet gebruiken als koppelteken */

BEM

Voor objecten in CSS gebruiken we de naamgevings methode van 'BEM'.
BEM splits de classes van bepaalde onderdelen in 3 groepen:

.widget {} /* Block */
    .widget__header {} /* Element */
    .widget--special {} /* Modifier */

Elementen worden gescheiden met twee (2) liggende streepjes (__), en Modifiers worden gescheiden door twee (2) koppeltekens (--).

<div class="widget">
        <div class="widget__header">
            <h1 class="widget__title">Titel</h1>
            <!-- ... -->
        </div>
        <div class="widget__body">
            <!-- ... -->
        </div>
    </div>
    <div class="widget  widget--special">
        <!-- ... -->
    </div>

Meer lagen

Het is het niet nodig om elke laag van de DOM te doorlopen. Zoals je in het vorige voorbeeld kan zien zit in de .widget__header nog een titel element. De classes volgen de DOM structuur niet 1 op 1, dus wordt dit niet .widget__header__title maar .widget__title.

Modifiers

Je kan een Modifier op een Block element gebruiken (zoals in het vorige voorbeeld met .widget--special), maar ook direct op een Element:

<div class="widget"> <!-- Block -->
        <div class="widget__intro  widget__intro--small"> <!-- Elem + Modifier -->
            <!-- ... -->
        </div>
    </div>

Naamgevingsconventies in HTML

Deze vorm van naamgeving is niet meteen al nuttig in je CSS. Waar de kracht van deze naamgeving ligt is in je markup. In het voorbeeld hieronder een stukje HTML, zonder naamgevingsconventie:

<div class="box  reactie  definitief">
        <img class="icon  image"/>
        <p class="datum">...</p>
    </div>

Hoe zijn de classes reactie en icon aan elkaar zijn gerelateerd? Of zijn ze dat helemaal niet? Kan je de class definitief naast datum gebruiken? Staan de classes image en reactie bij elkaar in de CSS? Kun je icon ook nog ergens anders gebruiken?

Met de voorgaande opmaak, is het moeilijk om op al deze vragen een antwoord te geven. Het gebruik van een naamgevingsconventie verandert de zaak:

<div class="box  reactie  reactie--definitief">
        <img class="icon  reactie__image"/>
        <p class="reactie__datum">...</p>
    </div>

Nu kunnen we duidelijk zien welke classes wel, en welke niet aan elkaar gerelateerd zijn, en hoe. We weten welke classes we niet buiten het component kunnen gebruiken, en welke classes we overal kunnen hergebruiken.

Javascript hooks

Het is niet verstandig om CSS styling en javascript functionaliteit aan dezelfde class te verbinden. Deze zouden anders niet los van elkaar te gebruiken zijn. We gebruiken daar dus een aparte class voor, en deze worden altijd voorafgegaan door js-.

<a class="btn  js-reageer-btn">Ik wil reageren</a>

Dit betekent dat we door de btn class toe te voegen, een ander element dezelfde styling kunnen geven, maar zonder de functionaliteit die aan js-reageer-btn gekoppeld zit.

CSS Selectors

Misschien enigszins verrassend, maar een van de meest belangrijke aspecten bij het schrijven van onderhoudbare en schaalbare CSS zijn de selectors.

Selector Intentie

Bij het schrijven van CSS is het belangrijk dat we goed opletten wat het bereik is van een selector, en dat we de juiste dingen selecteren voor de juiste redenen.
Selector Intentie is het proces van het beslissen en definiëren wat we willen stylen en hoe we het gaan selecteren. Als je bijvoorbeeld het hoofdmenu van een website wilt stylen, is het onverstandig om een selector als deze te gebruiken:

.menu ul {}

De Selector's Intentie is om elke ul in de class .menu te stylen, waar het onze bedoeling was om het hoofdmenu te stylen. Dit is slechte Selector Intentie; je kunt namelijk meer dan één .menu element op een pagina hebben, en deze kunnen ook meerdere ul's bevatten, dus een selector als deze loopt het risico dat die zeer specifieke styling toepast op een groot aantal elementen.

Het is dan beter om een selector als deze te gebruiken:

.main-nav {}

Dit is een eenduidige, expliciete selector. We selecteren nadrukkelijk het juiste ding voor precies de juiste reden.

Slechte Selector Intentie is een van de grootste redenen voor problemen bij een project met veel CSS. Als je CSS niet expliciet genoeg is, loop je vaak tegen onverwachte bijwerkingen aan, zoals selectors die ongerelateerde stijlregels beïnvloeden en in de weg zitten.

Herbruikbaarheid

Omdat we steeds meer UI's willen maken op basis van componenten, is herbruikbaarheid erg belangrijk. We willen de optie hebben om componenten te verplaatsten, kopieëren en te hergebruiken in onze projecten.

Daarom maken we veel gebruik van classes. ID's zijn naast het feit dat ze over-specifiek zijn, ook niet meer dan één keer te gebruiken op een pagina. Classes daarentegen kunnen oneindig keer worden hergebruikt.

Locatie afhankelijkheid

Aangezien projecten aan veranderingen onderhevig zijn, is het beter om dingen niet te stylen op basis van waar ze staan in het design. Componenten moeten helemaal onafhankelijk zijn van de locatie waar ze zich bevinden.

Stel je hebt een knop in een inschrijfformulier die je styled met de volgende selector:

.inschrijven a {}

Dit is niet alleen slechte Selector Intentie, omdat het elke link in het inschrijfformulier zal stylen, maar ook erg locatie afhankelijk. We kunnen deze styling niet hergebruiken voor een andere knop buiten het inschrijfformulier. Een veel betere selector zou zijn:

.btn {}

Deze class kan overal worden hergebruikt en zal altijd de juiste styling hebben. Door een betere selector, is dit component verplaatsbaar, herbruikbaar, en heeft het geen afhankelijkheden. Een component zou niet op een specifieke plaats moeten staan om er op een bepaalde manier uit te zien.

Verplaatsbaarheid

Locatie afhankelijkheid willen we zoveel mogelijk terugdringen, het liefst zelfs helemaal voorkomen. Ook zet je beter geen element-naam voor een selector.

input.btn {} /* deze class is niet inzetbaar voor andere elementen */

Door de input voor je selector te zetten gaat de herbruikbaarheid van je component verloren. Als je de input hier weg laat kan de styling ook worden hergebruikt voor een <a> of een <button>.

Naamgeving

Naamgeving binnen CSS kan erg lastig zijn. Het advies is om namen te gebruiken die verstandig zijn, maar ook niet té specifiek. Let hierbij vooral op grote herbruikbaarheid. Bijvoorbeeld, een class als .side-nav kun je beter vervangen door .sub-nav. Of i.p.v. .footer-links te gebruiken, kies je beter voor .sub-links.

Het verschil in naamgeving zit in dat de eerste van elk van de 2 voorbeelden is gebonden aan een specifiek geval. Ze kunnen alleen worden gebruikt als navigatie in de sidebar, of als links in de footer. Door een wat minder specifieke naam te kiezen vergroten we de mogelijkheid om deze componenten ook in andere omstandigheden in te zetten.

Specificiteit

Als je ooit problemen hebt gehad met specificiteit in CSS weet je hoe vervelend dit kan zijn. Het beste is om de specificiteit zo laag mogelijk te houden, en het zo veel mogelijk proberen te vermijden. De volgende punten helpen je hierbij:

IDs in CSS

Om de specificiteit zo laag mogelijk te houden is er een simpele regel: gebruik géén IDs in je CSS. Ze zijn niet herbruikbaar, en ze geven een element een enorm hoge specificiteit (100). Door deze regel besparen we onszelf een hele hoop problemen. Mocht er toch sprake zijn van een uitzondering, bijvoorbeeld in geval van script toepassingen op specifieke IDs, dan heeft de volgende notatie de voorkeur:

div[id="wrapper"] { ... }

Nesting

Bij het declareren van je style gebruik je het minimum aantal selectors dat nodig is om een element te stylen. Bekijk het volgende voorbeeld:

.mod {
        padding: 10px;
        border: 1px solid #bada55;
    }

    .mod > .mod__title {
        color: blue;
    }

Om het element .mod__title te stylen hebben we een selector die 2 keer zo specifiek is als nodig. Dat betekent dat als we de titel willen aanpassen, we een minstens gelijkwaardige selector nodig hebben:

.mod { ... }
    .mod > .mod__title { ... }
    .mod > .mod__title--sub {
        color: orange;
    }

Dit is iets wat je wilt vermijden. Als regel kun je stellen, als een selector werkt zonder genest te zijn, gebruik dan geen nesting.

!important

Het gebruik van !important is meestal een direct gevolg van specificiteits problemen. Het word vaak gebruikt als laatste uitweg om een element toch maar goed te kunnen stylen, omdat je eerder in de CSS een selector te specifiek hebt gemaakt. Je kunt het vergelijken met 'cheaten'.

Gebruik geen !important in je CSS om een specificiteits probleem op te lossen. Het mag alléén gebruikt worden wanneer het gebruikt word als een garantie i.p.v. een fix. Bij voorbeeld:

.is-hidden {
        display: none !important;
    }

Deze helper-class heeft een erg specifiek doel (content verbergen). Je gebruikt deze class alleen als je die echt wilt. Daarom is in dit geval een !important wel toegelaten. Bedenk dus voor je !important wilt gebruiken goed na of het niet een 'fix' is voor een eerder veroorzaakt probleem.

Gebruik de !important alleen in combinatie met een utility class of zoals hierboven in het voorbeeld in een bepaalde state.

SASS

Sinds 2016 passen we SASS (Syntactically Awesome Style Sheets) toe op nieuwe projecten. SASS is een uitbreiding van CSS die kracht en elegantie toevoegt aan de basistaal. Hiermee kun je variabelen, extends, mixins, imports, en meer gebruiken met een volledig CSS-compatible syntax. SASS zorgt ervoor dat grote stylesheets goed georganiseerd blijven, en krijgt kleine stylesheets super snel up and running.

SCSS Syntax

Maar waarom gebruiken wij SCSS en niet SASS? Dit komt eigenlijk gewoon neer op een kwestie van persoonlijke smaak en keuze. De voornamelijke reden waarom wij SCSS toepassen en niet SASS is dat de syntax van SCSS nagenoeg hetzelfde is aan die van CSS. Een standaard CSS bestand is met de syntax ook gewoon een legitiem SCSS bestand, alleen worden hierin dan niet de handigheden zoals variabelen, nesting en mixins gebruikt. En omdat SCSS veel meer weg heeft van de CSS syntax, is het overstappen en het toepassen ervan natuurlijk veel makkelijker gebleken.

Geen SMACSS maar ITCSS

Bij het toepassen van SCSS is de SMACSS architectuur niet meer relevant. In ons geval maken we gebruik van de ITCSS (Inverted Triangle CSS) architectuur. Waarom deze architectuur? Deze vorm vertegenwoordigt een model wat zorgt voor een geordende CSS structuur, en dat in de meest effectieve, minst verspillende manier. Binnen deze ITCSS architectuur maken we gebruik van namespacing.

Een van de belangrijkste principes van ITCSS is dat het je CSS onderbrengt in lagen, en dat in de vorm van een omgekeerde driehoek (Inverted triangle). Dit betekend dat je CSS is onderverdeeld van bovenin de algemene zaken, zoals bijvoorbeeld het kleurgebruik tot aan onderin de hele specifieke zaken, zoals een bepaalde button.

De lagen zijn dan alsvolgt ingedeeld:

De driehoek laat ook zien hoe de stijlen van de selectors worden gerangschikt in de resulterende CSS: van generieke stijlen tot zeer expliciete, van laag-specifieke selectors tot zeer-specifieke selectors en van ver reikend tot gelokaliseerde selectors.

Namespacing

Het gebruik van een namespacing is niet alleen handig om een specifiek element te voorzien van opmaak, ook door de namespacing is een element makkelijk terug te vinden in een project, waar het element allemaal terug komt.

Door alleen dit korte lijstje al kun je zien hoe veel meer informatie we ontwikkelaars kunnen geven door simpelweg één of twee tekens toe te voegen aan onze classes.

Imports

CSS heeft een import-optie waarmee je CSS kunt splitsen in kleinere, meer onderhoudbare porties. Het enige nadeel bij het gebruik van de @import mogelijkheid binnen CSS is dat je bij elke import dan ook elke keer een HTTP request uitvoert. SCSS bouwt verder op de huidige CSS @import functie, maar in plaats van een HTTP-verzoek, zal SCSS het bestand dat je wil importeren, combineren met het bestand dat je importeert. Hiermee stuur je uiteindelijk maar één CSS bestand richting de browser. In onze projecten wordt het meest gebruik gemaakt van de @import in onze main SCSS, dit ziet er alsvolgt uit:

>@charset "utf-8";

    /* 1 SETTINGS - Global variables, site-wide settings, config switches etc.
    *
    * The order in which these Sass files are loaded is critical!
    * So please be careful when editing
    =========================================================== */
    @import "1-Settings/settings.colors";
    @import "1-Settings/settings.config";
    @import "1-Settings/settings.typography";
    @import "1-Settings/settings.spacing";
    @import "1-Settings/settings.responsive";
    @import "1-Settings/settings.grid";
    @import "1-Settings/settings.site";
    @import "1-Settings/settings.zindex";

    /* 2 Tools - Site wide mixins and functions
    =========================================================== */
    @import "2-Tools/tools.debug";
    @import "2-Tools/tools.givebreakpoint";
    @import '2-Tools/tools.icons-sprite-main';
    @import "2-Tools/tools.toolbox";

    /* 3 Generic - Ground-zero styles / Low-specificity, far-reaching rulesets. (resets, box-sizing etc.)
    =========================================================== */
    @import "3-Generic/generic.normalize";
    @import "3-Generic/generic.reset";

    /* 4 Elements - Unclassed HTML elements (type selectors)
    =========================================================== */
    @import "4-Elements/elements.animations";
    @import "4-Elements/elements.images";
    @import "4-Elements/elements.lists";
    @import "4-Elements/elements.page";
    @import "4-Elements/elements.typography";

    /* 5 Objects - Design patterns (e.g. .media)
    =========================================================== */
    @import "5-Objects/objects.arrange";
    @import "5-Objects/objects.datalist";
    @import "5-Objects/objects.grid";
    @import "5-Objects/objects.lists";
    @import "5-Objects/objects.media";
    @import "5-Objects/objects.wrappers";

    /* 6 Components - Discrete complete chunks of UI. Designed components
    =========================================================== */
    @import "6-Components/components.headings";
    @import "6-Components/components.icons";
    @import "6-Components/components.labels";
    @import "6-Components/components.links";
    @import "6-Components/components.loader";
    @import "6-Components/components.messages";
    @import "6-Components/components.nav";
    @import "6-Components/components.notice";
    @import "6-Components/components.popup";
    @import "6-Components/components.rte";
    @import "6-Components/components.tabs";
    @import "6-Components/components.toggle";

    /* 7 Utility - High-specificity, very explicit selectors. Overrides and helper classes.
    =========================================================== */
    @import "7-Utility/utility.helpers";
    @import "7-Utility/utility.spacing";

    /* 8 Libs
    =========================================================== */
    @import "8-Libs/libs.libstyles";

Variabelen

Het gebruik van variabelen is een manier om de stijlen die je wilt hergebruiken in de stylesheet op te slaan en te gebruiken. Je stelt deze stijl in de variabelen 1 keer in en kunt deze vervolgens overal gaan gebruiken. Het grote voordeel hiervan is dat je de variabelen 1 keer hoeft te wijzigen, alle stijlen die voorzien zijn van deze variabele veranderd in deze automatisch mee.

Om een variabele te defineren maken we gebruik van het $ symbool. Een voorbeeld:

$font-stack:        Helvetica, sans-serif;
    $primary-color:     #333;

    body {
        font: $font-stack;
        color: $primary-color;
    }

Wanneer de SCSS wordt verwerkt worden de variabelen die zijn gedefineerd voor de $font-stack en $primary-color omgezet naar normaal CSS. Dit is ideaal wanneer er wordt gewerkt met huisstijl kleuren die consequent door de hele site moeten worden toegepast. Het resultaat van bovenstaande voorbeeld is dan alsvolgt:

body {
        font:   Helvetica, sans-serif;
        color:  #333;
    }

Functions

Met SCSS maken we gebruik van Functions en Mixins. Deze onderscheiden we in 2 apparte bestanden binnen de SCSS, een bestand voor Functions en een bestand voor Mixins. Voor website specifieke functions en mixins hebben we een gecombineerd toolbox bestand. Bij mixins krijg je CSS terug, bij functions is dit niet het geval, functions retourneren een waarde. Zie hieronder hoe je een function kunt toepassen:

@txtFunction calc-function($val1, $val2) {
        @txtReturn $val1 + $val2
    }

Na het maken van de function kun je deze gebruiken in je SCSS waaronder ook in je Mixins. Een simpel voorbeeld van het toevoegen van een function in de SCSS:

.my-module {
        padding: calc-function(10px, 5px);
    }

Mixins

Met een mixin is het mogelijk om een groep CSS stijlen te maken en deze vervolgens overal te kunnen hergebruiken op de website. Ook is het mogelijk om een variabele mee te geven om het nog flexibeler te maken. Hieronder een mixin voorbeeld voor het afbreken van een titel wanneer deze de maximale breedte overschrijd:

@mixin truncate($truncation-boundary) {
        max-width: $truncation-boundary;
        white-space: nowrap;
        overflow: hidden;
        text-overflow: ellipsis;
    }

    .titel { @include truncate(500px); }

Om gebruik te maken van een ​​mixin maak je gebruik van de @mixin richtlijnen en geef je deze een duidelijke en toepasselijke naam. In ons voorbeeld hebben we onze mixin truncate genoemd. Ook maken we in het voorbeeld gebruik van de variabele $truncation-boundary tussen de haakjes, hiermee kunnen we een waarde meegeven die wordt toegepast binnen de mixin. Nadat de mixin is gemaakt, is het vervolgens mogelijk om deze te gebruiken als een CSS stijl te beginnen met een @include gevolgd door de naam van de mixin. Wanneer de CSS wordt gegenereerd zal het er als volgt uitzien:

.titel {
        max-width: 500px;
        white-space: nowrap;
        overflow: hidden;
        text-overflow: ellipsis;
    }

Selector Nesting

Selector nesting is een kenmerk van SCSS, hiermee kun je selectors binnen selectors plaatsen, het is hierbij niet verplicht om de hele classnaam te noteren, echter is dan het terugvinden van een class bij bijvoorbeeld een modifier (BEM) niet echt handig. Daarom hieronder een voorbeeld van hoe het niet en wel moet.

/* fout */
    .c-button {
        display: inline-block;
        text-decoration: none;
        color: #000;

        &--light {
            color: #FFF;
        }
    }

    /* goed */
    .c-button {
        display: inline-block;
        text-decoration: none;
        color: #000;
    }

    .c-button--light {
        color: #FFF;
    }

In dit voorbeeld is .c-button--dark de modifier die bij .c-button geplaatst kan worden. Bij het incorrecte voorbeeld is het door het hele project heen de class .c-button--dark moeilijk vindbaar, mits je zoekt op --dark, in dit geval is het wel sneller mogelijk dat de classnaam vaker in de zoekresultaten terugkomen omdat het niet om een bijzonder specifieke classnaam gaat.

In het geval van een bijvoorbeeld een :hover of een ::before en ::after passen we wel gemakkelijk de nesting toe. Zie hieronder een voorbeeld van de eerder genoemde situatie maar nu inclusief een hover:

.c-button {
        display: inline-block;
        text-decoration: none;
        color: #000;

        &:hover {
            color: #FFF;
        }
    }

Gulp Autoprefixer

Werken met de Gulp autoprefixer is eenvoudig, je schrijft gewoon SCSS en de vendor prefixes kun je hierbij gewoon vergeten, deze worden door de autoprefixer op basis van de laatste W3C specs toegevoegd. In je Gulp file hoef je alleen nog maar aan te geven welke browsers je wil ondersteunen met 'Can I Use' statistieken. In de Gulpfile komt deze configuratie alsvolgt terug:

  1. Eerst wordt er een variabele gezet waarin je aangeeft naar welke browsers gekeken moet worden waarvoor vendor prefixes moeten worden toegepast. Dit werkt via de Browserlist key in de gulp file, het specificeren van de browsers gaat dan via verschillende standaard queries

    Gulp Autoprefixer

  2. Vervolgens wordt deze variabele geplaatst binnen de gulp build, waarbij de autoprefixer wordt geactiveerd en zorgt voor de vendor prefixes binnen de gegenereerde CSS daar waar dat nodig is.

    Gulp Autoprefixer

Kortom, in de SCSS schrijf je de normale CSS en de autoprefixer zorgt voor de rest.

SVG Sprite

Binnen je project vind je de map svg-sprites, in deze map vind je een verzameling van je svg bestanden. Via een Gulp script wordt hiervan een sprite ontwikkeld en kun je deze via een makkelijke mixin gebruiken binnen het project. Geef je svg bestand binnen het project een unieke naam, deze naam kun je vervolgens in de SCSS gebruiken om de Mixin toe te passen, de mixin zorgt er vervolgens voor dat er een template in elkaar wordt gezet welke vervolgens uitgelezen kan worden en een CSS gebouwd kan worden. Een voorbeeld van een svg toepassing vind je hieronder.

/* SCSS */
    .c-icon {
        @include sprite(message-notification);
    }

    .c-icon[data-icon='alert'] {
        @include sprite(message-alert, elem);
    }

    .c-icon[data-icon='error'] {
        @include sprite(message-error, elem);
    }

    /* Output */
    .c-icon {
        display: inline-block;
        background-image: url("../img/Icons-sprite.svg");
        background-size: 538px 532px;
        font-size: 1rem;
        width: 32px;
        height: 32px;
        background-position: -384px -384px;
    }

    .c-icon--alert {
        width: 32px;
        height: 32px;
        background-position: -320px -320px;
    }

    .c-icon--error {
        width: 32px;
        height: 32px;
        background-position: -352px -352px;
    }