-
Notifications
You must be signed in to change notification settings - Fork 0
3. Bouwfase
Mijn eerste taak die ik op me nam was het bouwen van een nieuwe navigatie menu. Deze ben ik gaan opzetten op basis van onze nieuwe sitemap die goedgekeurd was door de opdrachtgever.
Dit heb ik gedaan doormiddel de principe atomic-design te hanteren:
<ul role="menu">
<li>
<Navlink href="/stekjes" title="Stekjes"> </Navlink>
</li>
<li>
<Navlink href="/zaden" title="Zaden"> </Navlink>
</li>
<li>
<Navlink href="/geveltuin" title="Geveltuin"> </Navlink>
</li>
<li>
<Navlink href="/agenda" title="Agenda"> </Navlink>
</li>
<li>
<Navlink href="/partners" title="Partners"> </Navlink>
</li>
<li>
<Navlink href="/contact" title="Contact"> </Navlink>
</li>
</ul>
Deze refactor richt zich op het verbeteren van de navigatie-ervaring door gebruik te maken van de ingebouwde mogelijkheden van Svelte. De oude implementatie, die afhankelijk was van directe DOM-manipulatie en "ts-ignore" statements, is vervangen door een schonere en meer onderhoudbare Svelte-gebaseerde oplossing.
Belangrijkste voordelen van deze refactor:
- Verbeterde toegankelijkheid: De nieuwe navigatie maakt gebruik van semantische HTML-elementen om ervoor te zorgen dat deze goed toegankelijk is voor gebruikers met een handicap.
- Verhoogde prestaties: Door gebruik te maken van Svelte's reactieve systeem en het vermijden van directe DOM-manipulatie, biedt de nieuwe navigatie een soepelere en snellere gebruikerservaring.
- Progressive Enhancement: De navigatie is ontworpen met progressive enhancement in gedachten, dit heb ik toegepast doormiddel van een onscroll animatie, waarbij de menu verdwijnt en ook te voorschijn komt op scroll.
- Onderhoudbare code: De nieuwe code is schoner, beter gestructureerd en gemakkelijker te begrijpen en te onderhouden dan de oude implementatie.
Deze refactor laat zien hoe Svelte kan worden gebruikt om een moderne, toegankelijke en een goed presenterende navigatie te bouwen die de gebruikerservaring aanzienlijk verbetert.
//Oude nav
onMount(() => {
// @ts-ignore
document
.querySelector("a .menu-icon")
.addEventListener("click", function (ev) {
// @ts-ignore
document.querySelector("nav a").classList.add("active");
// @ts-ignore
document.querySelector("nav a").focus();
ev.preventDefault();
});
// @ts-ignore
document
.querySelector("nav .close-icon")
.addEventListener("click", function (ev) {
// @ts-ignore
document.querySelector("nav a").classList.remove("active");
document.body.focus();
ev.preventDefault();
});
});
<nav id="menu">
<ul role="menu">
<li>
<Navlink href="/stekjes" title="Stekjes"> </Navlink>
</li>
<li>
<Navlink href="/zaden" title="Zaden"> </Navlink>
</li>
<li>
<Navlink href="/geveltuin" title="Geveltuin"> </Navlink>
</li>
<li>
<Navlink href="/agenda" title="Agenda"> </Navlink>
</li>
<li>
<Navlink href="/partners" title="Partners"> </Navlink>
</li>
<li>
<Navlink href="/contact" title="Contact"> </Navlink>
</li>
</ul>
<a class="close-icon" href="/">
<CloseIcon />
</a>
</nav>
- Verbeterde nav:
const handleNav = () => {
if (window.innerWidth < 900) {
navOpen = !navOpen;
}
};
</script>
<header class:hidden={headerHidden} class:mobile-header={navOpen}>
<div class:container-active={navOpen} class:container-unactive={!navOpen} class="container">
<a href="/" class="logo" class:logo2={navOpen}> </a>
<button class:change={navOpen} on:click={handleNav}></button>
</div>
<nav class:active={navOpen}>
<ul role="menu">
<li><Navlink {handleNav} href="/stekjes" title="Stekjes"/></li>
<li><Navlink {handleNav} href="/zaden" title="Zaden"/></li>
<li><Navlink {handleNav} href="/geveltuin" title="Geveltuin" /></li>
<li><Navlink {handleNav} href="/agenda" title="Agenda"/></li>
<li><Navlink {handleNav} href="/partners" title="Partners"/></li>
<li><Navlink {handleNav} href="/contact" title="Contact"/></li>
</ul>
</nav>
- OnScroll Menu script: Hier heb ik de Nav ook enhanced met een onscroll animatie, waarbij de navigatie op beeld komt en weer verdwijnd op scroll.
let navOpen = false;
let lastScrollY = 0;
let headerHidden = false;
onMount(() => {
const handleResize = () => {
if (window.innerWidth >= 900) {
navOpen = false;
}
};
const handleScroll = () => {
const currentScrollY = window.scrollY;
headerHidden = currentScrollY > lastScrollY && currentScrollY > 80; // Verberg bij scrollen naar beneden en voorbij 80px
lastScrollY = currentScrollY;
};
window.addEventListener('resize', handleResize);
window.addEventListener('scroll', handleScroll);
return () => {
window.removeEventListener('resize', handleResize);
window.removeEventListener('scroll', handleScroll);
};
});
Voor dit project heb ik bewust gekozen voor een "mobile-first"-aanpak. Dit betekent dat ik de website eerst heb ontworpen voor mobiele apparaten, omdat ik weet dat steeds meer mensen hun telefoon gebruiken om websites te bekijken. Dit zorgt voor een betere gebruikerservaring op alle apparaten, wat natuurlijk een belangrijk principe is.
/* MEDIA QUERY MOBILE = 400px */
@media (min-width: 25rem) {}
/* MEDIA QUERY TABLET = 768px */
@media (min-width: 48rem) {}
/* MEDIA QUERY DESKTOP = 1700px */
@media (min-width: 106.25rem) {}
mediaquery - Hero component
Daarnaast heb ik veel aandacht besteed aan semantische HTML. Dit betekent dat ik HTML-elementen heb gebruikt die de betekenis van de content duidelijk maken (bijvoorbeeld <header>
, <nav>
, <article>
). Dit is niet alleen belangrijk voor zoekmachines, maar ook voor mensen die een screenreader gebruiken. Zo zorg ik ervoor dat mijn website voor iedereen toegankelijk is.
Bij het bouwen van de slider-card kreeg ik feedback van Justus om bijvoorbeeld rekening te houden om HTML-elementen niet zomaar te gebruiken. Ik kreeg advies om voor elementen niet zomaar te gebruiken, voor design redenen bijvoorbeeld (::before of ::after): Link naar PR-review. Dit heb ik ook gelijk toegepast en ben ik er ook op gaan letten bij de rest van mijn code.
Ook heb ik custom properties gebruikt voor de styling. Dit zijn variabelen in CSS waarmee ik de stijl van de website makkelijk kan aanpassen en onderhouden. Dit is een moderne techniek die laat zien dat ik op de hoogte ben van de laatste ontwikkelingen.
Properties - Bieb in Bloei
-
Voo Bieb in bloei ben ik de contactpagina gaan refactoren en daarbij heb ik ook de formulier Responsive/PE en Toegankelijk gemaakt.
-
Responsive: Ik heb ervoor gezorgd dat het formulier zich aanpast aan verschillende schermformaten. Hoewel ik geen expliciete media queries in mijn CSS heb gebruikt, heb ik het formulier zo ontworpen dat het er goed uitziet en functioneel blijft op zowel desktops als mobiele apparaten. Ik heb flexbox gebruikt om de elementen flexibel te maken en ervoor te zorgen dat ze zich goed aanpassen aan verschillende schermformaten.
-
Toegankelijk: Toegankelijkheid is voor mij erg belangrijk. Ik heb
<label>
elementen gebruikt die correct zijn gekoppeld aan hun bijbehorende inputvelden met behulp van for en id attributen. Dit is cruciaal voor schermlezers en andere ondersteunende technologieën. Daarnaast heb ik semantische HTML-elementen gebruikt zoals<form>
,<input>
en<textarea>
om de structuur en betekenis van de inhoud duidelijk te maken. Ik ben van plan om in de toekomst ARIA-attributen toe te voegen voor nog meer context en om het kleurcontrast te verbeteren voor mensen met een visuele beperking. -
Progressive Enhancement: Ik heb het formulier zo gebouwd dat het functioneel is zonder JavaScript, wat de basisfunctionaliteit biedt voor oudere browsers. Verder ben ik met CSS de formulier verder gaan Enhancen door: Gebruik te maken van de pseudo-klassen
form:valid
,form:invalid
enform:focus
om de styling van de inputvelden dynamisch aan te passen op basis van de invoerstatus en focus." -
Performant: Ik heb ervoor gezorgd dat er geen overdreven grote afbeeldingen of onnodige scripts in mijn code staan. Ik zal eventuele afbeeldingen die ik later toevoeg optimaliseren en mijn CSS-code minificeren om de bestandsgrootte te verminderen.
Extra opmerkingen: Ik heb Web3Forms gebruikt om het formulier af te handelen. Ik ben me bewust van hoe dit werkt en welke gegevens worden verzameld. Ik ben ook trots op mijn overzichtelijke en goed gestructureerde CSS.
Ik ben ervan overtuigd dat mijn formulier een solide basis heeft voor een responsive, toegankelijke en performante gebruikerservaring. Ik zal blijven werken aan verbeteringen om het nog toegankelijker en gebruiksvriendelijker te maken voor iedereen.
Hier heb ik View transitions - API gebruikt voor onze pagina's. Aan de hand van de workshop van Jad heb hiervoor inspiratie gehaald uit de officiële documentatie van de View Transitions API en een artikel over het gebruik ervan in SvelteKit.
Ik ondervond uitdagingen bij het implementeren van de API in ons project vanwege een bug die deze blokkeerde. Aanvankelijk vermoedde ik dat het probleem lag bij mijn navigatiecomponent, dat nog enkele fouten bevatte. Na een volledige refactoring van de navigatie bleef de API echter onbruikbaar.
Vervolgens heb ik Eslint verwijderd, wat leidde tot een vermindering van het aantal foutmeldingen. Na uitgebreid onderzoek ontdekte ik een bug in de console, gerelateerd aan het agendacomponent. Nadat ik deze bug had opgelost, functioneerde de API eindelijk zoals verwacht.
Om dit te bereiken, heb ik de volgende code toegevoegd aan mijn +layout.svelte
bestand:
import { onNavigate } from '$app/navigation';
onNavigate(function(navigation) {
if (!document.startViewTransition) return;
return new Promise(function(resolve) {
document.startViewTransition(function() {
resolve();
navigation.complete;
});
});
});
- Wij hebben voor de link-buttons een atom-component gemaakt, zodat we deze vaker kunnen hergebruiken in verband met DRY. Dit hebben we momenteel op deze manier gedaan. Alleen hadden we moeite om deze een hover mee te geven. Dus heb ik aan de hand van Svelte.docs even onderzoek gedaan hoe dit kon en ben ik dit gaan refactoren naar een betere methode voor dit component.
Before:
export let href, buttonText, buttonBackground, svgFill, buttonColor;
<a href={href} style="background-color: {buttonBackground}; color: {buttonColor};">
{buttonText}
</a>
-------------------
<Button
href="/stekjes"
buttonText="Bekijk de Bieb"
buttonBackground="var(--main-color-green)"
svgFill="var(--main-color-beige)"
buttonColor="var(--main-color-beige)"
/>
After:
Heb de SVG component verwijderd en deze direct in de button-component geplaatst, zo kon ik beter de (:hover) aanroepen, verder ben ik met CSS-variables de kleuren gegeven, op deze manier kan je ze makkelijker aanpassen.
<a href={href} class={btnClass}>
{buttonText}
<span>
<svg class={svgFill} xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 44 47">
<path d="M40.492 18.788 8.942 1.034C4.944-1.218 0 1.673 0 6.262v34.704c0 4.537 4.842 7.433 8.84 5.285l31.549-16.948c4.167-2.239 4.225-8.195.103-10.515Z"
fill={svgFill} />
</svg>
</span>
</a>
-------------------------------------
/* button style */
a{
--color-accent: var(--accent, --main-color-green);
--color-text: var(--text, --main-color-beige);
background: var(--color-accent);
color: var(--color-text);
- Nu heb ik na lang vechten met Svelte eindelijk een Button-component met een hover effect. Zie mijn PR of mijn Isssue