# Component based development

Een site analyseren, opdelen met Atomic Design en benoemen met BEM

Multimedia & Creatieve Technologie · 2.1 Web production · Les 5 · versie 1.5.1 · 2026-10-21

Tags: css, html, bem, design-systems, architecture

Slides: <https://slides.mctantwerp.be/nl/web-production/04b-component-based-development>

Speaker notes: <https://slides.mctantwerp.be/nl/web-production/04b-component-based-development.notes.md>

<!-- slide 2 -->

## Agenda

1. Analyse
2. Atomic Design
3. BEM
4. Utilities en frameworks

<!-- slide 3 -->

## Na deze les kan je

- Een site analyseren en er een styleguide van maken
- Een pagina opdelen in atoms, molecules en organisms
- Een component en zijn varianten benoemen met BEM
- Het verschil tussen BEM, utility classes en een framework uitleggen

<!-- slide 4 -->

## Wat is een component?

Een card, een zoekveld of een navigatie: elk is een herkenbaar stuk interface dat je opnieuw kan gebruiken.

Je hergebruikt de HTML-structuur en de CSS. Titel, foto en tekst verschillen per exemplaar.

Een aanpassing aan de gedeelde CSS geldt voor alle exemplaren.

**Nieuwe studieruimte**: Een story card op de nieuwspagina.

**Workshop fotografie**: Dezelfde soort card met een andere titel en inhoud.

<!-- slide 5 -->

## 1. Analyse

<!-- slide 6 -->

### Wat je zoekt

|   | Wat je zoekt |
| --- | --- |
| Kleuren | De neutrale kleuren, de brand colors, kleuren voor buttons, voor fouten en validatie |
| Typografie | Hoe titels en leestekst eruitzien, een apart font voor quotes, de fonts op buttons |
| Iconen | Of er iconen zijn, waarvoor ze dienen, en of ze varianten hebben zoals een hover state |
| Spacing | Patronen in margins en paddings, en of er een grid onder de pagina zit |
| Toegankelijkheid | Regels voor contrast en een minimum font size, alles bereikbaar met het toetsenbord, buttons groot genoeg en ver genoeg uit elkaar |

<!-- slide 7 -->

**Elke kleur heeft een functie.**

Drie gelijkaardige grijzen kunnen dienen voor tekst, randen en een disabled state. Twee verschillende grijzen voor dezelfde functie zijn een reden om het na te vragen.

<!-- slide 8 -->

### Design systems

- **[Apple](https://developer.apple.com/design/human-interface-guidelines/color)**: Human Interface Guidelines
- **[Google](https://m3.material.io/styles/color/system/overview)**: Material Design 3
- **[U.S. Web Design System](https://designsystem.digital.gov/)**: De Amerikaanse overheid
- **[IBM](https://carbondesignsystem.com/)**: Carbon Design System
- **[Europese Unie](https://op.europa.eu/en/web/webguide/design-system)**: EU Web Guide

<!-- slide 9 -->

## 2. Atomic Design

<!-- slide 10 -->

### Componenten opdelen met Atomic Design

- Deelt een interface op in vijf niveaus, van klein naar groot
- Geen wet: teams discussiëren over waar iets thuishoort
- UX, design en development gebruiken dezelfde namen

atoms

molecules

organisms

templates

pages

[Brad Frost: Atomic Design](https://atomicdesign.bradfrost.com/chapter-2/)

<!-- slide 11 -->

### Atomic Design

![Atomic Design: atoms vormen molecules, molecules vormen organisms, die samenkomen in templates en ingevuld worden als pages](https://slides.mctantwerp.be/decks/nl/web-production/04b-component-based-development/atomic-design-process.png)

*[Brad Frost, Atomic Design](https://atomicdesign.bradfrost.com/chapter-2/)*

<!-- slide 12 -->

### Fundaments

- Kleuren, typografie en afstanden die elk component gebruikt
- Je haalt ze uit je analyse

**Geen zesde niveau**: Brad Frost heeft vijf niveaus. Fundaments staan daarnaast, als de basis waar elk niveau op steunt.

<!-- slide 13 -->

### Atoms

- Het kleinste herbruikbare stuk interface
- Buttons en links, form elementen, het logo
- Met varianten en states, zoals primair of disabled

InschrijvenMeer infoVolzet

<!-- slide 14 -->

### Molecules

- Een groep atoms die samen één taak doen
- Bijvoorbeeld een zoekveld met een button
- Samen herbruikbaar op verschillende pagina’s

Zoek een artikelZoek

input + button

<!-- slide 15 -->

### Organisms

- Een herkenbare sectie met een eigen functie
- Samengesteld uit molecules en atoms
- Bijvoorbeeld een header, een productoverzicht of een footer

**Header**: Logo (atom), navigatie (molecule), zoekveld (molecule)

<!-- slide 16 -->

### Templates en pages

#### Templates

- De indeling van een paginatype
- Bijvoorbeeld: header, artikel en gerelateerde cards
- Nog zonder definitieve titels, foto’s en tekst

#### Pages

- Een template ingevuld met echte inhoud
- Bijvoorbeeld: het artikel over de nieuwe studieruimte
- Daarmee controleer je of de layout ook met die inhoud werkt

<!-- slide 17 -->

### Campus Stories, opgedeeld

Een schets van de Campus Stories-pagina: een header met logo en navigatie, en drie story cards. Stap voor stap komt er een kader rond de atoms (afbeelding, tag, titel, button, logo, links), de molecules (card, navigatie) en de organisms (header, rij cards).

<!-- slide 18 -->

### Een zoekveld met een button ernaast. Wat is het?

- A. Een atom
- B. Een molecule
- C. Een organism
- D. Een template

**Antwoord:** B. Een molecule

Het zoekveld en de button zijn elk een atom. Samen, met een form eromheen, vormen ze een molecule. Zet je het in de header met het logo en de navigatie, dan is die header het organism.

<!-- slide 19 -->

## 3. BEM

<!-- slide 20 -->

### Atomic Design en BEM hebben elk hun taak

**Atomic Design**: Hoe zit de interface in elkaar? De card bundelt een foto, titel en link. In onze indeling is die card een molecule.

**BEM**: Hoe heten de CSS-classes? De card wordt `card`, de titel erin `card__title`.

<!-- slide 21 -->

### Componenten benoemen

- Kies de namen voor je begint te coden
- Simpele namen voor je componenten
- Een naam voor elke variant
- Een map per component
- Styles en scripts van een component in die map

<!-- slide 22 -->

### Naming conventions

- **[BEM](https://getbem.com/)**: Block Element Modifier
- **[SMACSS](https://smacss.com/)**: Scalable and Modular Architecture for CSS
- **[OOCSS](https://www.smashingmagazine.com/2011/12/an-introduction-to-object-oriented-css-oocss/)**: Object Oriented CSS

<!-- slide 23 -->

**Componenten stylen met classes.**

Classes geven componenten en hun onderdelen een eigen naam. IDs blijven bruikbaar voor bijvoorbeeld ankerlinks en de koppeling tussen een label en een invoerveld.

<!-- slide 24 -->

### Block, element, modifier

.block\_\_element--modifier

- **Block**

  De component zelf, de wrapper.

  `card`
- **Element**

  Een onderdeel dat enkel in die block bestaat.

  `card__title`
- **Modifier**

  Een variant: een andere kleur, grootte of volgorde.

  `card--dark`

<!-- slide 25 -->

### Een card in BEM

```html
<article class="card">
  <img class="card__image"
       src="campus.jpg" alt="Campus">
  <h2 class="card__title">
    Studieruimte
  </h2>
  <p class="card__text">Extra plek.</p>
  <a class="card__link"
     href="artikel.html">Lees meer</a>
</article>
```

1. `card` is de block: het zelfstandige component.
2. `card__image` is een onderdeel van de card. De dubbele underscore verbindt de blocknaam met het onderdeel.
3. De titel heet `card__title`, ook als er later een extra HTML-wrapper rond komt.
4. Tekst en link zijn ook onderdelen: `card__text` en `card__link`. Ze krijgen hun eigen class om ze gericht te stylen.

```css
.card__link { color: inherit; }
```

De link neemt de tekstkleur van de card over. Dat werkt straks ook in de donkere variant.

<!-- slide 26 -->

### Een modifier past alleen het verschil aan

```css
.card {
  padding: 24px;
  background-color: white;
  color: black;
}

.card--dark {
  background-color: black;
  color: white;
}
```

```html
<article class="card">...</article>
<article class="card card--dark">
  ...
</article>
```

1. `card` bevat de gedeelde styling. Beide exemplaren krijgen de padding en de gewone kleuren.
2. `card--dark` wijzigt alleen de kleuren. De basisclass blijft nodig voor de rest.

<!-- slide 27 -->

### Een zelfstandig component in de card

```html
<a class="card__link link"
   href="artikel.html">
  <span class="link__icon">→</span>
  <span class="link__label">
    Lees meer
  </span>
</a>
```

`card__link` beschrijft de rol binnen de card, zoals de plaats en buitenmarge.

`link` is een zelfstandig block met een eigen icoon en label. Dat kan ook in de footer terugkomen.

<!-- slide 28 -->

### Wat je niet doet

#### Niet

```html
<h2 class="card__body__title">
  Titel
</h2>
<div class="card--dark">...</div>
```

```css
.card .title { font-size: 2rem; }
```

#### Wel

```html
<div class="card card--dark">
  <h2 class="card__title">Titel</h2>
</div>
```

```css
.card__title { font-size: 2rem; }
```

<!-- slide 29 -->

### Een card met een donkere achtergrond. Welke classes krijgt de wrapper?

- A. card-dark
- B. card--dark
- C. card card--dark
- D. card dark

**Antwoord:** C. card card--dark

De modifier past enkel aan wat verschilt, de kleuren. De rest komt van card, dus die class blijft staan. card dark werkt ook, maar dark zegt niet bij welk component het hoort.

<!-- slide 30 -->

### Opdracht: Een BEM card

*20 minuten, Alleen*

1. Maak een card in een nieuwe pen in CodePen
2. Gebruik card als block en benoem de foto, titel, tekst en link als elementen
3. Geef elk stuk een class volgens BEM
4. Voeg een tweede card toe met card én card--dark: donkere achtergrond, lichte tekst
5. Klaar als beide cards dezelfde basis-CSS delen en alleen de modifier de kleuren verandert

<!-- slide 31 -->

## 4. Utilities en frameworks

<!-- slide 32 -->

### Utility classes

```css
.bold { font-weight: bold; }
.ta--center { text-align: center; }
```

```html
<p class="card__text bold">
  Inschrijven kan tot vrijdag.
</p>
```

`card__text` zegt bij welk component de tekst hoort.

`bold` maakt tekst vet, ook buiten een card. Zo’n class met één taak heet een utility class.

<!-- slide 33 -->

### Bootstrap of Tailwind

**[Bootstrap](https://getbootstrap.com/)**: Kant-en-klare componenten met een aanpasbare standaardstijl: buttons, cards en navigatie

**[Tailwind](https://tailwindcss.com/)**: Utility classes waarmee je zelf componenten opbouwt

<!-- slide 34 -->

### Je eigen systeem

- Volg je systeem consequent, welk je ook kiest
- Spreek het af met je team voor het project start
- Documenteer het in de README
- Gebruik wat al bestaat: BEM, een design system of een framework

<!-- slide 35 -->

### Componenten op echte websites

- **[Belfius Private](https://www.belfiusprivate.be/nl)**

  Cards met een zelfstandig button-component

  `card__content`

  `button--primary`
- **[NHS](https://www.nhs.uk/)**

  Cards met gedeelde onderdelen en varianten

  `nhsuk-card__content`

  `nhsuk-card--secondary`
- **[GOV.UK](https://www.gov.uk/register-to-vote)**

  De basisclass en modifier van de startbutton

  `govuk-button`

  `govuk-button--start`

<!-- slide 36 -->

### Thuisopdracht: Analyse van een website

Kies een website of web app en analyseer ze. Je maakt er een digitale styleguide van in één FigJam-bestand.

1. Kies een website of web app met voldoende verschillende componenten en varianten
2. Verzamel screenshots van verschillende pagina’s of schermen en noteer de URL van de site
3. Werk kleurgebruik, typografie, iconen en componenten uit in je FigJam

<!-- slide 37 -->

### Wat komt in je styleguide?

| Onderdeel | Wat je verzamelt en beschrijft |
| --- | --- |
| Kleurgebruik | Kleurstalen met kleurcodes en hun functie: tekst, achtergrond, acties en states |
| Typografie | Fonts, groottes, gewichten en regelafstand, met voorbeelden van titels, tekst en labels |
| Iconen | Voorbeelden, stijl en grootte, en waarvoor de iconen gebruikt worden |
| Componenten | Welke onderdelen terugkomen, hoe ze opgebouwd zijn en welke varianten je vindt |

<!-- slide 38 -->

### Thuisopdracht: Componenten in FigJam

Gebruik je screenshots om te tonen hoe de interface opgebouwd is.

1. Omkader atoms, molecules en organisms elk in een andere kleur
2. Voeg een legenda toe en gebruik dezelfde kleuren op alle screenshots
3. Beschrijf kort de functie en opbouw van de componenten, en motiveer je indeling
4. Toon en beschrijf hun eventuele varianten naast elkaar
5. Klaar als je FigJam de styleguide, gemarkeerde screenshots en componentbeschrijvingen bevat

<!-- slide 39 -->

### Je analyse maakt de AI-opdracht concreet

#### Een algemene vraag

> “Maak een moderne nieuwspagina met cards.”

Dit zegt weinig over de bestaande componenten, varianten en stijlafspraken.

Als je die herkent en benoemt, kan je hergebruik vragen én nakijken.

#### Een opdracht met componenten

> “Gebruik de meegegeven card-HTML en CSS voor alle nieuwsitems. Behoud `card__image`, `card__title` en `card__link`. Voeg `card--dark` toe voor de donkere variant, met alleen de afwijkende kleuren. Volg de meegegeven styleguide. Geef alleen de gewijzigde code.”

<!-- slide 40 -->

### Hergebruik voorkomt dubbele CSS

#### Dezelfde opmaak per pagina

```css
.home-card {
  padding: 24px;
  border-radius: 8px;
}

.news-card {
  padding: 24px;
  border-radius: 8px;
}
```

#### Eén gedeelde componentstijl

```css
.card {
  padding: 24px;
  border-radius: 8px;
}
```

Beide pagina’s gebruiken `card`. Een aanpassing aan de gedeelde stijl staat op één plek.

Een modifier voegt alleen toe wat verschilt.

<!-- slide 41 -->

### Gericht aanpassen kan tokens besparen

Tokens zijn de stukjes waarin een AI-model onder meer tekst en code verwerkt. Zowel je invoer als de gegenereerde uitvoer tellen mee.

- **Een gerichte wijziging**: De bestaande card aanpassen vraagt minder nieuwe code dan elke pagina opnieuw laten genereren.
- **Wat ook meetelt**: Meegestuurde bestanden, de gespreksgeschiedenis en elke correctieronde. Hoeveel dat is, hangt af van de tool en het model.

Een korte prompt kan toch veel tokens kosten, als de tool er veel context bij stuurt.

## Begrippen

- **Digital styleguide**: Alles wat op een site terugkomt, opgeschreven: kleuren, typografie, iconen, spacing en de regels voor toegankelijkheid. Je maakt hem door een bestaande site te analyseren, of hij komt mee met het design. (slide 6)
- **Design system**: Een styleguide met de componenten erbij, in design en in code, en de afspraken over wanneer je welke gebruikt. Material Design van Google en Carbon van IBM zijn er bekende voorbeelden van. (slide 8)
- **Atomic Design**: Een manier van Brad Frost om een interface op te delen, van klein naar groot: atoms, molecules, organisms, templates en pages. Een afspraak tussen design en development, geen wet. (slide 10)
- **Atom**: Het kleinste component: een button, een link, een invoerveld, het logo. Kan uit één of meer HTML-tags bestaan en varianten hebben. (slide 13)
- **Molecule**: Een groep atoms die samen één taak uitvoeren, zoals een zoekveld met een button. Herbruikbaar op meerdere plekken. (slide 14)
- **Organism**: Een sectie van een pagina, gemaakt uit molecules en atoms: de header, een rij cards, de footer. De functie en samenstelling bepalen het niveau, niet hoe vaak het voorkomt. (slide 15)
- **BEM**: Block Element Modifier, een naming convention voor CSS-classes: .block\_\_element--modifier. Elke class zegt bij welk component ze hoort en wat ze daarin doet. (slide 24)
- **Modifier**: In BEM een variant van een block of element, met twee streepjes: card--dark. Hij komt altijd naast de gewone class, nooit alleen. (slide 24)
- **Utility class**: Een class die één klein stukje CSS doet, zoals .bold of .mt--l. Handig in een CMS en naast BEM. Tailwind is er volledig op gebouwd. (slide 32)

## Links en bronnen

### In de presentatie

- [Apple Human Interface Guidelines: Color](https://developer.apple.com/design/human-interface-guidelines/color) (slide 8)
- [Material Design 3: Color system](https://m3.material.io/styles/color/system/overview) (slide 8)
- [U.S. Web Design System](https://designsystem.digital.gov/) (slide 8)
- [IBM Carbon Design System](https://carbondesignsystem.com/) (slide 8)
- [EU Web Guide: Design system](https://op.europa.eu/en/web/webguide/design-system) (slide 8)
- [Brad Frost: Atomic Design, hoofdstuk 2](https://atomicdesign.bradfrost.com/chapter-2/) (slide 10, slide 11)
- [BEM](https://getbem.com/) (slide 22)
- [SMACSS](https://smacss.com/) (slide 22)
- [Smashing Magazine: An Introduction To Object Oriented CSS](https://www.smashingmagazine.com/2011/12/an-introduction-to-object-oriented-css-oocss/) (slide 22)
- [Bootstrap](https://getbootstrap.com/) (slide 33)
- [Tailwind CSS](https://tailwindcss.com/) (slide 33)
- [Belfius Private](https://www.belfiusprivate.be/nl) (slide 35)
- [NHS](https://www.nhs.uk/) (slide 35)
- [GOV.UK: Register to vote](https://www.gov.uk/register-to-vote) (slide 35)

### Bronnen

- [Web production: Component based CSS](https://mctantwerp.github.io/web-production/component-based-css/): De cursuspagina is voorlopig nog een placeholder
- [BEM: Naming](https://getbem.com/naming/)
- [Google AI: tokens begrijpen en tellen](https://ai.google.dev/gemini-api/docs/tokens): Invoer, uitvoer en gesprekscontext tellen mee in het tokenverbruik
