Direct naar de inhoud

Handboek HTML5 en CSS3HTML en CSS van <a> tot z-index

Maak zelf een HSL-kleurkiezer (4)

Met de kleurkiezer kun je sinds de vorige aflevering een kleur instellen en de CSS-code daarvan kopiëren en plakken in je editor. Een ding ontbreekt nog: de helpfunctie. Leer hoe je een overlay en een dialoogvenster maakt met HTML, CSS en Javascript.

Begin gemist? Lees dan eerst deel 1.

Een venster met aanwijzingen voor de gebruiker

Hieronder staat de voltooide versie van de kleurkiezer en daarmee kun je zien wat klikken op de helpknop zou moeten doen:

  • het hele venster wordt afgedekt door een overlay, een halfdoorzichtige lichtgrijze laag;
  • de regelaars en knoppen kunnen niet meer worden bediend;
  • er wordt een venster getoond met uitleg over de bediening.

We maken dit in drie stappen:

  • de overlay;
  • het helpvenster;
  • de JavaScript-code voor het openen en sluiten van het helpvenster.

De overlay

Je kent vast die grijze waas over een webpagina waardoor je nergens meer op kunt klikken. Dat wordt een overlay genoemd. De meeste overlays zijn onschuldig en nuttig. Sommige zijn het kwaad zelf.

Een overlay is gewoon een box met meestal een halftransparante (zwarte) achtergrondkleur die het venster bedekt. De box heeft geen speciale betekenis en dan is het in HTML een <div>. Het enige wat echt belangrijk is, is dat de box boven op de andere inhoud ligt.

In de HTML van de kleurkiezer is de overlay niet meer dan:

<div id="overlay"></div>
<form>
<!-- rest van de code -->

De plaats van de <div> in de HTML is onbelangrijk, want met CSS zorgen we voor de juiste positie:

.overlay {
  width: 100%;
  height: 100%;
  position: absolute;
  top: 0;
  left: 0;
  background-color: hsla(0, 0%, 50%, .6);
  z-index: 5;
}

De overlay is met 100% breedte en hoogte altijd net zo breed en hoog als zijn ouderelement, wat hier neerkomt op het venster. Je zou ook 100vw en 100vh kunnen gebruiken, dan heb je zeker altijd de breedte en hoogte van het venster.

Met position: absolute wordt de overlay geplaatst ten opzichte van de body. De regel is dat absoluut gepositioneerde elementen worden geplaatst ten opzichte van de eerste relatief gepositioneerde voorouder of de body. Omdat er geen relatieve voorouders zijn, wordt het de body. Het startpunt is de hoek linksboven. De kleur is halftransparant zwart.

De z-index bepaalt de stapelvolgorde. Standaard is de waarde auto. Elk volgend element in de HTML komt boven op het voorgaande element te liggen. Je kunt de volgorde aanpassen door een of meer elementen een z-index te geven met een positief of negatief getal. Een hoger getal betekent hoger op de stapel. In de kleurkiezer heeft alleen de overlay een z-index en daardoor komt die boven op de stapel te liggen.

De div heeft geen klasse, alleen een id?

De overlay is bij het laden van de pagina onzichtbaar, want de <div> heeft op dat moment geen enkel opmaakkenmerk. Pas als het helpvenster wordt geopend, wordt met JavaScript de klasse .overlay toegevoegd aan de <div id="overlay">. Met de id maken we een variabele voor het element:

const overlay = document.getElementById('overlay');

De logica voor het toevoegen van de klasse zit in de gebeurtenisverwerker van het dialoogvenster. Die wordt hierna besproken.

Het dialoogvenster

De overlay helpt om alle aandacht op het venster met helpinformatie te vestigen. Het wordt een modaal venster genoemd, een modal, omdat het zolang het open is alle communicatie met de app blokkeert. In deze zelfgebouwde versie doet het modale venster dat echter niet zelf. De overlay dekt alles af wat eronder ligt en daardoor werken de knoppen niet.

HTML heeft een element voor (dialoog)vensters: <dialog>. Dat is een ‘echt’ modaal venster met een ingebouwde overlay (het pseudo-element ::backdrop). Het probleem is dat alleen Chrome dit element ondersteunt. Met een polyfill is dat op te lossen, maar in dit geval is het net zo makkelijk om zelf iets te bouwen. Dit is de HTML:

<div class="dialog" id="modal-box">
  <header>
    <h2>Hulp voor de HSL-kleurkiezer</h2>
    <button class="close" id="btn-close-modal">X</button>
  </header>
  <ol>
    <li>Kies een kleur met de eerste slider (hue).</li>
    <li>Bepaal de verzadiging met de tweede slider (saturation).</li>
    <li>Bepaal de helderheid met de derde slider (lightness).</li>
    <li>Beoordeel de kleur in het grote kleurvak.</li>
    <li>Kopieer de kleurdeclaratie met de knop Kopieer en plak die in je CSS.</li>
    <li>Zet alles terug naar de beginwaarden met de knop Herstel.</li>
  </ol>
</div>

Veel bijzonders is het niet:

  • een <div> is de container voor het venster;
  • in de header staan een titel en een knop voor het sluiten van het venster;
  • de inhoud bestaat uit een geordende lijst <ol> met instructies. Het is geen ongeordende lijst <ul> omdat de instructies een (min of meer) vaste volgorde hebben.

De CSS is wat uitgebreider:

.dialog {
  background-color: white;
  border: 1px solid black;
  margin: 0;
  padding: 1em;
  position: absolute;
  left: 1em;
  top: 1em;
  width: calc(100vw - 2em);
  max-width: 500px;
  transform: translateX(-600px);
  z-index: 10;
  transition: transform 500ms ease-out;
}

Het venster wordt absoluut gepositioneerd, net als de overlay. De breedte wordt berekend door van de vensterbreedte 2em af te trekken, met een maximumbreedte van 500px. Het venster staat bij het laden van de pagina buiten beeld (600px naar links verschoven). Het schuift na het klikken op de helpknop vloeiend in beeld met een overgang:

.open {
  transform: translateX(0);
}

De header van het venster is een flexbox. Zo kunnen de titel en de knop eenvoudig elk aan een kant worden uitgelijnd:

.dialog header {
  display: flex;
  justify-content: space-between;
}
.close {
  align-self: center;
}

JavaScript voor de actie

De laatste stap is toevoegen van de JavaScript-code.

Het blok met variabelen wordt aangevuld met:

const btnShowModal = document.getElementById('btn-help');
const btnCloseModal = document.getElementById('btn-close-modal');
const modalBox = document.getElementById('modal-box');

Klikken op de helpknop (<button id="btn-help">) doet twee dingen:

  • de CSS-klasse .open wordt toegevoegd aan de <div id="modal-box">;
  • de CSS-klasse .overlay wordt toegevoegd aan de <div id="overlay">.
btnShowModal.addEventListener('click', () => {
  modalBox.classList.add('open');
  overlay.classList.add('overlay')
});

Klikken op de sluitknop van het helpvenster doet het omgekeerde, beide klassen worden verwijderd:

btnCloseModal.addEventListener('click', () => {
  modalBox.classList.remove('open');
  overlay.classList.remove('overlay')
});

Dat was het

Het project is voltooid. We kunnen een kleur kiezen en de declaratie ervan kopiëren en plakken in een stylesheet. Ook bieden we in een dialoogvenster informatie aan over het gebruik van de app.

HTML is de basis, maar over het geheel is dat de kleinste hoeveelheid code. De CSS bestaat uit veel meer regels. Het opmaken van schuifregelaars (<input type="range">) kost wat meer moeite dan de opmaak van een gewoon HTML-element. Met de basiskennis van het schaduw-DOM kun je nu ook de opbouw en opmaak van andere complexe elementen uitvogelen. De DevTools/Hulpmiddelen voor ontwikkelaars (F12) zijn daarbij een geweldig hulpmiddel.

De JavaScript-code kan er bij een eerste kennismaking intimiderend uitzien. Kijk je er wat langer naar, dan blijkt dat veel regels ongeveer hetzelfde doen. Het komt altijd neer op het maken van een verwijzing (variabele) naar een element. Vervolgens ‘luister’ je of een bepaalde gebeurtenis optreedt en laat je als reactie daarop acties uitvoeren. Je kunt CSS-klassen of inline stijlen toevoegen en verwijderen, maar je voegt net zo makkelijk hele blokken HTML-code toe. Door het manipuleren van onderdelen van de pagina (DOM-manipulatie) kun je pagina’s echt interactief maken.

De JavaScript-code kan wel efficiënter worden opgezet. Juist omdat veel regels ongeveer hetzelfde doen. Daar kijken we naar in de volgende aflevering.

Tags: html css javascript


Reageer op dit artikel

* Vul a.u.b. alle velden in.