fix: update readme and arias

This commit is contained in:
Tim Rijkse
2026-01-16 11:26:39 +01:00
parent 4e650899c8
commit 7367127b50
9 changed files with 178 additions and 36 deletions

147
README.md
View File

@@ -28,6 +28,131 @@ We hebben gekozen voor een **Web Components-architectuur** om de volgende redene
---
## 🎯 UX Onderbouwing
### Paginastructuur
De pagina's zijn opgebouwd volgens een bewuste hiërarchie die de gebruiker begeleidt van oriëntatie naar actie:
```
┌─────────────────────────────────┐
│ Header (sticky) │ ← Altijd toegankelijk
│ ├── Logo + Menu + Acties │
│ ├── Categorie navigatie │
│ └── Zoekbalk │
├─────────────────────────────────┤
│ Hoofdinhoud │ ← Scrollbare content
│ ├── Promotieblok (push-box) │
│ ├── Boekensecties │
│ ├── Categorieën │
│ └── Nieuwsbrief │
├─────────────────────────────────┤
│ Footer │ ← Service informatie
│ └── Accordion navigatie │
└─────────────────────────────────┘
```
### Ontwerpkeuzes per element
#### 🔍 Zoekbalk (prominent in header)
**Waarom:** De zoekfunctie staat bovenaan omdat:
- **Directe toegang** — Terugkerende klanten weten vaak al wat ze zoeken
- **Tijdsbesparing** — Sneller dan door categorieën navigeren
- **Spraakherkenning** — Extra toegankelijkheid voor gebruikers met beperkingen of onderweg
- **Verwachting** — Gebruikers verwachten een zoekfunctie bij een webshop
#### 📱 Mobile Drawer (slide-in navigatie)
**Waarom een drawer in plaats van dropdown:**
- **Meer ruimte** — Volledige schermhoogte voor uitgebreide navigatie
- **Touch-vriendelijk** — Grote klikgebieden, swipe om te sluiten
- **Focus** — Backdrop voorkomt interactie met achterliggende content
- **Overzicht** — Alle categorieën en imprints in één overzicht
- **Authenticatie** — Plek voor inlog/registratie knoppen
#### 📚 Boekkaarten (horizontale layout)
**Waarom horizontale kaarten:**
- **Scanbaarheid** — Cover links trekt de aandacht, tekst rechts geeft context
- **Efficiënt** — Meer informatie zichtbaar per kaart dan bij verticale layout
- **Touch targets** — Grote klikbare gebieden voor mobiel gebruik
- **Consistentie** — Herkenbare structuur door hele site
**Informatiehiërarchie:**
1. **Titel** (vetgedrukt, onderstreept) — Primair identificatie
2. **Beschrijving** — Context over de inhoud
3. **Auteur** (paars, onderstreept) — Secundair, maar klikbaar
4. **Prijs** (vetgedrukt) — Koopbeslissing informatie
5. **Winkelwagen knop** — Directe actie
#### 📦 Push Boxes (promotieblokken)
**Waarom push boxes:**
- **Visuele onderbreking** — Doorbreekt de lijst met boeken
- **Merkidentiteit** — Ruimte voor imprint logos (Asoka)
- **Call-to-action** — Stuurt naar belangrijke pagina's
- **Flexibiliteit** — Twee varianten (default/paars) voor verschillende contexten
**Plaatsing:**
- **Bovenaan homepage** — Introductie van het merk/imprint
- **Onder boekdetails** — Klantenservice toegang na productinfo
- **Strategisch** — Voorkomt "scroll fatigue" bij lange pagina's
#### 🏷️ Categoriekaarten (grid layout)
**Waarom visuele categorieën:**
- **Herkenning** — Iconen zijn sneller te verwerken dan tekst
- **Uitnodigend** — Visuele elementen nodigen uit tot verkennen
- **Oriëntatie** — Helpt nieuwe bezoekers het aanbod te begrijpen
- **Twee kolommen** — Optimaal voor mobiele weergave
#### 📑 Tabbladen (boekdetailpagina)
**Waarom tabs voor Beschrijving/Inzage/Recensies:**
- **Ruimtebesparing** — Voorkomt zeer lange pagina's
- **Gebruikerskeuze** — Laat gebruiker kiezen wat relevant is
- **Focus** — Toont één type informatie tegelijk
- **Verwachting** — Bekend patroon van andere webshops
#### 📰 Nieuwsbrief sectie
**Waarom onderaan (maar boven footer):**
- **Niet opdringerig** — Staat niet in de weg van productinhoud
- **Logische plek** — Na het bekijken van content, uitnodiging om verbonden te blijven
- **Visueel onderscheid** — Border maakt het herkenbaar als apart element
#### 🦶 Footer met accordions
**Waarom accordions:**
- **Ruimtebesparing** — Veel links zonder lange scrolllijsten
- **Georganiseerd** — Duidelijke categorisering van footer content
- **Touch-vriendelijk** — Grote tap targets voor mobiel
- **Verwachting** — Standaard patroon voor mobiele footers
### Visuele hiërarchie
De kleurkeuzes ondersteunen de gebruikerservaring:
| Element | Kleur | Reden |
|---------|-------|-------|
| Primaire acties | Paars (#951D51) | Opvallend, merkidentiteit |
| Links | Paars + onderstreept | Herkenbaar als klikbaar |
| Titels | Zwart + vetgedrukt | Maximaal contrast, hiërarchie |
| Secundaire tekst | Grijs | Ondersteunend, niet afleidend |
| Achtergronden | Lichtgrijs varianten | Subtiel onderscheid tussen secties |
### Scroll-gedrag header
**Smart header die inklapt bij scrollen:**
- **Naar beneden** — Header klapt deels in, meer ruimte voor content
- **Naar boven** — Header verschijnt weer, navigatie altijd bereikbaar
- **Drempel van 100px** — Voorkomt "flikkeren" bij kleine scrollbewegingen
Dit patroon maximaliseert schermruimte terwijl navigatie toegankelijk blijft.
---
## 🚀 Project starten
### Vereisten
@@ -255,6 +380,7 @@ Dit project is gebouwd met toegankelijkheid als prioriteit en volgt de WCAG 2.1
- Verborgen link die verschijnt bij keyboard focus
- Stelt gebruikers in staat direct naar de hoofdinhoud te navigeren
- Slaat herhalende navigatie-elementen over
- Geplaatst binnen de header landmark voor correcte WCAG compliance
#### Semantische HTML
- Correcte gebruik van `<header>`, `<nav>`, `<main>`, `<footer>`, `<section>`, `<article>`
@@ -289,6 +415,7 @@ Dit project is gebouwd met toegankelijkheid als prioriteit en volgt de WCAG 2.1
#### Taal
- `lang="nl"` attribuut op HTML element
- Correcte taalinstelling voor screenreaders
- Alle ARIA labels zijn in het Nederlands
### Focus Stijlen
@@ -306,14 +433,24 @@ element:focus {
## 📱 Responsive Design
Het ontwerp is mobile-first gebouwd met een maximale breedte van **430px** voor de mobiele container. Op grotere schermen wordt de mobiele weergave gecentreerd weergegeven met een schaduw.
> **Let op:** De huidige implementatie toont een gefixeerde mobiele container (430px) puur ter demonstratie voor deze pitch. Bij de daadwerkelijke ontwikkeling wordt de website volledig responsive gebouwd voor alle schermformaten.
### Breakpoints
### Pitch weergave
| Breakpoint | Gedrag |
|------------|--------|
| < 431px | Volledige breedte, mobiele ervaring |
| ≥ 431px | Gecentreerde container met afgeronde hoeken en schaduw |
| ≥ 431px | Gecentreerde container met afgeronde hoeken en schaduw (pitch preview) |
### Geplande responsive implementatie
Bij de definitieve ontwikkeling worden de volgende breakpoints toegevoegd:
| Breakpoint | Apparaat | Aanpassingen |
|------------|----------|--------------|
| < 640px | Mobiel | Huidige ontwerp, enkele kolom |
| 640px - 1024px | Tablet | Twee-koloms grid voor boeken, aangepaste navigatie |
| > 1024px | Desktop | Volledige sidebar navigatie, drie-koloms grid, uitgebreide header |
---
@@ -353,7 +490,3 @@ Front-end Developer
## 📄 Licentie
Dit project is gemaakt als onderdeel van een pitch voor Milinda Uitgevers en mag uitsluitend worden gebruikt indien de opdracht wordt gegund.
---
*Gemaakt met ❤️ voor boeken en boeddhisme*

View File

@@ -5,9 +5,9 @@
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<meta
name="description"
content="Milinda - Discover and buy your next favorite book"
content="Zen is opendoen - Dick Verstegen | Milinda Uitgevers"
/>
<title>Milinda - Home</title>
<title>Zen is opendoen - Milinda Uitgevers</title>
<!-- Fonts are loaded via @font-face in styles.css -->
<link rel="preconnect" href="https://fonts.googleapis.com" />
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin />
@@ -18,10 +18,12 @@
<link rel="stylesheet" href="css/styles.css" />
</head>
<body>
<a href="#main-content" class="skip-to-content">Ga naar inhoud</a>
<mobile-drawer></mobile-drawer>
<div class="mobile-container">
<site-header>
<a href="#main-content" class="skip-to-content" slot="skip-link"
>Ga naar inhoud</a
>
<top-bar slot="top-bar">
<button
slot="menu-button"
@@ -33,10 +35,10 @@
</button>
<a slot="logo" href="index.html" class="logo">Milinda</a>
<div slot="actions" class="actions">
<button class="icon-button" aria-label="Profile">
<button class="icon-button" aria-label="Profiel">
<user-icon></user-icon>
</button>
<button class="icon-button" aria-label="Shopping basket">
<button class="icon-button" aria-label="Winkelwagen">
<shopping-bag-icon></shopping-bag-icon>
</button>
</div>
@@ -45,8 +47,8 @@
<search-bar slot="search"></search-bar>
</site-header>
<site-content>
<main id="main-content">
<site-content>
<section class="section">
<book-details
title="Zen is opendoen"
@@ -162,8 +164,8 @@
placeholder="Je e-mailadres"
></newsletter-signup>
</div>
</main>
</site-content>
</main>
<site-footer>
<span slot="logo">MILINDA uitgevers</span>

View File

@@ -5,7 +5,7 @@
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<meta
name="description"
content="Milinda - Discover and buy your next favorite book"
content="Milinda Uitgevers - Boeken over boeddhisme, meditatie en mindfulness"
/>
<title>Milinda - Home</title>
<!-- Fonts are loaded via @font-face in styles.css -->
@@ -18,10 +18,12 @@
<link rel="stylesheet" href="css/styles.css" />
</head>
<body>
<a href="#main-content" class="skip-to-content">Ga naar inhoud</a>
<mobile-drawer></mobile-drawer>
<div class="mobile-container">
<site-header>
<a href="#main-content" class="skip-to-content" slot="skip-link"
>Ga naar inhoud</a
>
<top-bar slot="top-bar">
<button
slot="menu-button"
@@ -33,10 +35,10 @@
</button>
<a slot="logo" href="index.html" class="logo">Milinda</a>
<div slot="actions" class="actions">
<button class="icon-button" aria-label="Profile">
<button class="icon-button" aria-label="Profiel">
<user-icon></user-icon>
</button>
<button class="icon-button" aria-label="Shopping basket">
<button class="icon-button" aria-label="Winkelwagen">
<shopping-bag-icon></shopping-bag-icon>
</button>
</div>
@@ -45,8 +47,8 @@
<search-bar slot="search"></search-bar>
</site-header>
<site-content>
<main id="main-content">
<site-content>
<div class="content-padding">
<push-box>
<img slot="logo" src="images/logo-asoka.png" alt="Asoka Logo" />
@@ -220,8 +222,8 @@
placeholder="Je e-mailadres"
></newsletter-signup>
</div>
</main>
</site-content>
</main>
<site-footer>
<span slot="logo">MILINDA uitgevers</span>

View File

@@ -331,7 +331,7 @@ class BookDetails extends HTMLElement {
<div class="header">
<div class="title-row">
<h1 class="title">${this.bookTitle}</h1>
<button class="favorite-btn" aria-label="Add to favorites">
<button class="favorite-btn" aria-label="Toevoegen aan favorieten">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="#f59e0b" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
<polygon points="12 2 15.09 8.26 22 9.27 17 14.14 18.18 21.02 12 17.77 5.82 21.02 7 14.14 2 9.27 8.91 8.26 12 2"/>
</svg>

View File

@@ -110,7 +110,7 @@ class HorizontalScrollNav extends HTMLElement {
background-color: #7a1843;
}
</style>
<nav class="nav-container" role="navigation" aria-label="Book categories">
<nav class="nav-container" role="navigation" aria-label="Boekcategorieën">
${this.categories
.map(
(cat) => `

View File

@@ -373,8 +373,8 @@ class ImageGallery extends HTMLElement {
const imagesHtml = this.images
.map(
(img, index) => `
<button class="gallery-item" type="button" aria-label="View image ${index + 1}">
<img src="${img}" alt="Book preview ${index + 1}" class="gallery-image" />
<button class="gallery-item" type="button" aria-label="Bekijk afbeelding ${index + 1}">
<img src="${img}" alt="Boek voorvertoning ${index + 1}" class="gallery-image" />
</button>
`
)
@@ -512,11 +512,11 @@ class ImageGallery extends HTMLElement {
<div class="modal-overlay">
<div class="modal-header">
<div class="zoom-controls">
<button class="zoom-btn zoom-out" type="button" aria-label="Zoom out"></button>
<button class="zoom-btn zoom-reset" type="button" aria-label="Reset zoom">⟲</button>
<button class="zoom-btn zoom-in" type="button" aria-label="Zoom in">+</button>
<button class="zoom-btn zoom-out" type="button" aria-label="Uitzoomen"></button>
<button class="zoom-btn zoom-reset" type="button" aria-label="Zoom resetten">⟲</button>
<button class="zoom-btn zoom-in" type="button" aria-label="Inzoomen">+</button>
</div>
<button class="modal-close" type="button" aria-label="Close">
<button class="modal-close" type="button" aria-label="Sluiten">
<svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
<line x1="18" y1="6" x2="6" y2="18"></line>
<line x1="6" y1="6" x2="18" y2="18"></line>
@@ -524,7 +524,7 @@ class ImageGallery extends HTMLElement {
</button>
</div>
<div class="modal-content">
<img class="modal-image" src="" alt="Full size preview" />
<img class="modal-image" src="" alt="Volledige afbeelding" />
</div>
</div>
`;

View File

@@ -14,6 +14,8 @@ class MobileDrawer extends HTMLElement {
connectedCallback() {
this.render();
this.setupEventListeners();
// Set initial aria-hidden state
this.setAttribute("aria-hidden", "true");
}
disconnectedCallback() {
@@ -51,6 +53,7 @@ class MobileDrawer extends HTMLElement {
open() {
this.isOpen = true;
this.shadowRoot.querySelector(".drawer-container").classList.add("open");
this.setAttribute("aria-hidden", "false");
document.body.style.overflow = "hidden";
// Focus trap - focus first focusable element
@@ -63,6 +66,7 @@ class MobileDrawer extends HTMLElement {
close() {
this.isOpen = false;
this.shadowRoot.querySelector(".drawer-container").classList.remove("open");
this.setAttribute("aria-hidden", "true");
document.body.style.overflow = "";
}
@@ -316,7 +320,7 @@ class MobileDrawer extends HTMLElement {
<div class="drawer-container">
<div class="backdrop"></div>
<nav class="drawer" aria-label="Main navigation">
<nav class="drawer" aria-label="Hoofdnavigatie">
<div class="drawer-header">
<a href="index.html" class="drawer-logo">Milinda</a>
<button class="close-button" aria-label="Sluit menu">

View File

@@ -41,9 +41,9 @@ class SiteContent extends HTMLElement {
padding-bottom: var(--spacing-md, 16px);
}
</style>
<main class="content">
<div class="content">
<slot></slot>
</main>
</div>
`;
}
}

View File

@@ -96,6 +96,7 @@ class SiteHeader extends HTMLElement {
}
</style>
<header class="header">
<slot name="skip-link"></slot>
<slot name="top-bar"></slot>
<div class="collapsible">
<slot name="nav"></slot>