Open Annevd opened 2 months ago
Na aanleiding van mijn ontwerp en de oude code van de web minor (#125 ), heb ik het menu van de toegankelijkheidsfuncties gebouwd. Dit is nu nog met voornamelijk dezelfde code als de web minor, met een paar semantische verbeteringen in de HTML.
Dit menu is een component in de folder lib/organisms/
, namelijk accessibility-menu.svelte
. Deze staat in de +layout.svelte
geïmporteerd, omdat het op elke pagina moet staan.
+layout.svelte
:
<script>
export let data;
import { Menu, AccessibilityMenu, Footer } from '$lib/index.js';
import Viewtransition from '$lib/viewtransition.svelte';
</script>
<Viewtransition />
<Menu />
<AccessibilityMenu />
<slot/>
<Footer {data}/>
Zo ziet de HTML er nu uit:
<form aria-label="Accessibility Options">
<label for="menu" class="accessibilityIcon">
<input type="checkbox" id="menu"> <!-- Dit zorgt voor het openen en sluiten van het menu -->
<Accessibility />
</label>
<div class="accessibilityContent">
<ul>
<li>
<label for="toggle-darkmode">
<div class="label-container">
<Moon/> <!-- Dit is een component voor de SVG -->
<span>Dark mode</span>
</div>
<input type="checkbox" id="toggle-darkmode" role="switch"> <!-- Dit zorgt voor het aan/uit zetten van de feature -->
<span class="state"> <!-- Deze spans maken de switch -->
<span class="container">
<span class="position"> </span>
</span>
</span>
</label>
</li>
<li>
<label for="font-size">
<div class="label-container">
<FontIncrease />
<span>Grotere letters</span>
</div>
<input type="checkbox" id="font-size" role="switch">
<span class="state">
<span class="container">
<span class="position"> </span>
</span>
</span>
</label>
</li>
<li id="google_translate_element">
<div class="label-container">
<Translate />
<span>Vertaal deze website</span>
</div>
</li>
</ul>
</div>
</form>
In onderstaande CSS kan je zien hoe het menu opent en sluit door middel van het veranderen van de waarde van left: ... ;
:
form {
position: fixed;
top: 20vh;
left: -14rem; /* Hidden by default */
z-index: 10000;
display: flex;
flex-direction: row-reverse;
width: calc(13rem + 5rem);
transition: left .3s;
}
/* Menu is shown when checkbox is checked */
form:has(.accessibilityIcon input:checked) {
transition: left .3s;
left: -1rem; /* Slide out to show the menu */
}
/* Hide the content when checkbox is unchecked */
form:not(:has(.accessibilityIcon input:checked)) > .accessibilityContent ul {
display: none;
transition: left .3s;
}
/* Extra's */
/* When the accessibility menu is closed (i.e., the input checkbox inside `.accessibilityIcon` is not checked),
this CSS rule sets a fixed height for `.accessibilityContent`. This ensures that when the menu is hidden,
it shrinks to a specific height instead of expanding to fit its full content. */
form:not(:has(.accessibilityIcon input:checked)) > .accessibilityContent {
height: 117.781px;
}
/* This hides the checkbox with `id^="menu"`, which is the checkbox controlling the visibility of the menu.
It is positioned off-screen (`left: -50%`) so it remains functional (it can still be checked/unchecked)
but invisible to users. The visibility is handled entirely by the image or label, not the checkbox itself. */
input[type="checkbox"][id^="menu"] {
position: absolute;
left: -50%;
}
De switches heb ik gemaakt aan de hand van deze bron van W3, om goede toegankelijkheid te behouden.
Omdat :has()
in een aantal oude browserversies niet ondersteund word, wil ik mij nog gaan verdiepen in hoe ik de functionaliteit van het menu zoals het openen, sluiten, en de features anders kan aanpakken volgens het principe PE.
Ook probeerde ik van de switch een component te maken, wat ook gelukt was. Echter leverde dat mij beperkingen op bij het stylen van specifieke elementen en labels hier binnen. Hierdoor heb ik het voor nu toch niet als component gebruikt. Ik ben benieuwd of hier nog een andere oplossing voor is.
Andere dingen waar ik nog tegen aan loop/wat ik nog moet doen:
input
is focusbaar op dit moment, waarom?Hoe het er uit ziet op dit moment:
Na het sparren over de functionaliteit en de features van het toegankelijkheidsmenu ben ik nog over een aantal dingen na gaan denken.
:has()
? :has()
](https://www.bram.us/2023/01/04/css-has-feature-detection-with-supportsselector-you-want-has-not-has/#:~:text=%23%20Feature%20detecting%20%3Ahas(),used%20in%20a%20feature%20query%20.)form
Na de her analyse ben ik begonnen met het herbouwen van het menu, dit keer zonder :has()
.
Ook heb ik de code netter en overzichtelijker gemaakt.
Om te beginnen heb ik van de switch een component gemaakt. Dit scheelt namelijk veel regels code in het hoofdcomponent van het menu en maakt alles een stuk overzichtelijker.
Om dit te doen heb ik in de lib/atoms/buttons/
folder een file genaamd switch.svelte
aangemaakt. Hierin staat de HTML en CSS voor de switch, en de dynamische variabele voor id
, zodat je in je hoofdcomponent daar dynamisch een id naam aan kan geven. De "toggle" waarde is een default, en word overschreven wanneer je dit in je hoofdcomponent veranderd.
lib/atoms/buttons/switch.svelte
:
<script>
export let id = "toggle";
</script>
<input type="checkbox" id={id} role="switch">
<span class="state">
<span class="container">
<span class="position"> </span>
</span>
</span>
Om dit component te kunnen gebruiken moet ik hem nog exporteren in de index.js
:
export { default as Switch } from '$lib/atoms/buttons/switch.svelte'
Om hem vervolgens in het hoofdcomponent te gebruiken moet je je component hier ook importeren. Vervolgens kan je in de script
tag je custom id
's aanmaken en toevoegen aan de switch:
<script>
import {Accessibility, Moon, Translate, FontIncrease, Switch} from '$lib/index.js';
let darkModeId = "toggle-darkmode";
let fontSizeId = "toggle-font-size";
</script>
<label for="toggle-darkmode">
<Switch id={darkModeId}/>
</label>
<label for="toggle-font-size">
<Switch id={fontSizeId}/>
</label>
Het menu kan nu geopend en gesloten worden met alleen CSS en zonder :has()
. Ik werk nu met de :checked
pseudo-class waarmee ik een open en closed state kan meegeven aan de hand van of de checkbox geklikt wordt of niet. Dit is dus eigenlijk hetzelfde als de vorige code maar nu zonder :has()
.
Doordat je zonder :has()
niet het form
kan aanspreken op basis van de checkbox, is het ontwerp wel iets veranderd. De button schuift niet meer mee uit maar heeft een vaste positie waaruit het menu komt.
HTML:
<form aria-label="Accessibility Options"> <!-- Het menu zit in een form, met daarin de features -->
<!-- Deze input controlleert het openen/sluiten van het menu en is gelinkt met het label-->
<input type="checkbox" class="toggle-menu" id="menu" aria-expanded={isExpanded ? "true" : "false"} aria-controls="accessibility-options" on:change={toggleMenu}>
<label title="Accessibility Options" for="menu" class="icon">
<Accessibility /> <!-- Dit is een component van de SVG -->
</label>
<div class="content" id="accessibility-options" aria-hidden={!isExpanded}>
<ul>
<li>
<label for="toggle-darkmode"> <!-- Dit label is gelinkt aan de switch via het id en for-->
<span class="label-container">
<Moon/>Dark mode <!-- Dit is een component van de SVG-->
</span>
<Switch id={darkModeId}/> <!-- Dit is het component voor de switch met het id-->
</label>
</li>
<li>
<label for="toggle-font-size">
<span class="label-container">
<FontIncrease/>Increase Text <!-- Dit is een component van de SVG -->
</span>
<Switch id={fontSizeId}/> <!-- Dit is het component voor de switch met het id -->
</label>
</li>
<li id="google_translate_element">
<span class="label-container">
<Translate/>Translate this website <!-- Dit is een component van de SVG-->
</span>
</li>
</ul>
</div>
</form>
CSS:
/* Het form staat vast gepositioneerd rechts onderaan de pagina*/
form {
position: fixed;
bottom: 2rem;
right: 0;
z-index: 10000;
display: flex;
flex-direction: column-reverse;
align-items: flex-end;
transition: right 0.3s;
}
/* De content (de ul met daarin de features) staat absoluut gepositioneerd bovenaan het randje van de open menu knop.
Deze staat standaard -15rem naar rechts, zodat het menu by default niet zichtbaar is*/
.content {
position: absolute;
bottom: 4rem;
right: -15rem;
background: #fff;
height: 9rem;
width: 15rem;
border-radius: 0.6rem 0 0 0.6rem;
transition: right 0.5s ease-in-out;
}
/* Wanneer de checkbox van het menu aangeklikt wordt schuift de content in beeld*/
.toggle-menu:checked ~ .content{
right: 0;
transition: right 0.5s ease-in-out;
}
/* By default is de ul niet te zien, zodat er geen interactie mee kan worden gedaan als het menu dicht is */
.toggle-menu:not(:checked) ~ .content ul {
display: none;
}
/* Om hierbij wel de slide out animatie te houden heeft de content een vaste hoogte, dit is zodat wanneer de ul op display:none gaat, de content niet gelijk verdwijnt */
.toggle-menu:not(:checked) ~ .content {
height: 9rem;
}
/* Dit zorgt ervoor dat het menu te openen/sluiten is, zonder dat de default input te zien is*/
input[type="checkbox"][id^="menu"] {
position: absolute;
right: -50%;
}
In de HTML gebruik ik verschillende ARIA attributen om ervoor te zorgen dat het menu toegankelijk is voor mensen met keyboard navigation en screenreaders.
aria-label="Accessibility Options"
op het element: <form>
aria-expanded={isExpanded ? "true" : "false"}
op het element <input type="checkbox" class="toggle-menu">
aria-controls="accessibility-options"
op het element <input type="checkbox" class="toggle-menu">
id="accessibility-options"
element, de div
waarin het menu zit.aria-hidden={!isExpanded}
op het element: <div class="content" id="accessibility-options">
aria-expanded
op de checkbox om een compleet beeld te geven van de status van de inhoud.aria-controls="toggle-darkmode"
and aria-controls="toggle-font-size"
op het element <label for="toggle-darkmode">
and <label for="toggle-font-size">
Wow je bent echt goed in documenteren Anne! echt nettjes!
User story: Als bezoeker wil ik toegankelijkheid features zien en kunnen aanpassen
Taak: Button popup maken met daarin de accessibility tools (html/css)