3. Bouwfase - JalalToufik/Bieb-In-Bloei GitHub Wiki

1. Nav-component

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>

2. Mobile first

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 Scherm­afbeelding 2024-06-07 om 15 58 44

3. Semantische HTML

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.

3.1 Feedback om html

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.

4. Custom properties

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 Scherm­afbeelding 2024-06-07 om 17 25 09

5. Formulier

  • 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.

  • 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.

  • Focus op de actie:* Ik heb gebruik gemaakt van de pseudo-klassen form:valid, form:invalid en form:focus om de styling van de inputvelden dynamisch aan te passen op basis van de invoerstatus en focus."

image

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.

image

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.

6. View transitions

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;
            });
        });
    });

7. Atom buttons

  • 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

Scherm­afbeelding 2024-06-12 om 13 01 45 Scherm­afbeelding 2024-06-12 om 13 01 52

8. Responsive Menu

Omdat de transitie-API niet werkte, heb ik het navigatiemenu volledig gerefactored. Het bevatte nog enkele "ts-ignore" statements, wat natuurlijk geen schone code oplevert. Bovendien ontdekte ik dat Svelte een eigen methode heeft voor het bouwen van een navigatiebalk. Ik heb de documentatie geraadpleegd om te begrijpen hoe dit werkt en heb daar inspiratie opgedaan voor een verbeterde navigatie.

//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:
    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);
        };
    });

Samenvatting:

Deze code maakt een responsieve navigatiebalk die zich aanpast aan verschillende schermformaten. Op desktopschermen is het een horizontale balk met altijd zichtbare links. Op kleinere schermen verandert het in een hamburgermenu dat geopend en gesloten kan worden. Bovendien verbergt de header zich wanneer de gebruiker naar beneden scrolt en verschijnt weer wanneer de gebruiker naar boven scrolt.

⚠️ **GitHub.com Fallback** ⚠️