Technisch ontwerp van de website

Introductie

Zorg voor een voldoende breed scherm om deze toelichting te kunnen zien, bijvoorbeeld door je smart≠phone horizontaal te houden.
webtech Deze webpagina beschrijft het technisch ontwerp en realisatie van de website en de problemen en oplossingen die zich tijdens de ontwikkeling voordeden. De lezer wordt verondersteld enige basiskennis van HTML en CSS te hebben. HTML bestanden bevatten de content. Deze wordt gekoppeld met tags* aan opmaakstijlen die in CSS gedefinieerd zijn.


Het doel van het ontwerp is dat de website goed functioneert en goed uit ziet op de volgende platformen: PC, laptop, tablet en smartphone (in horizontale en verticale houding), met verschillende webbrowsers als Firefox, Edge, Google Chrome en Safari. De grootste uitdaging zijn smartphones met hun beperkte schermgroottes, twee zeer verschillende hoogte-breedte verhoudingen en soms afwijkende brow≠sers.
Waar gaat het concreet om? Ten eerste gaat het om een heldere schermindeling, ten tweede om het realiseren van een goed werkend menu systeem om te kunnen navigeren binnen de website, zowel met muis- als aanrakingsbediening. Tenslotte gaat het om flexibele oplossingen voor verschillende schermformaten, zodat schermindeling, tekst, plaatjes en menu's goed zichtbaar of bereikbaar zijn en de eventuele beperkte ruimte goed benut wordt. Met het woord scherm wordt ook venster bedoeld als er meerdere applicaties op een scherm zichtbaar zijn.
Om het resultaat te beoordelen kunnen de webpagina's het beste op een laptop of PC bekeken worden, waarbij het formaat van het venster gevarieerd wordt: smal, breed, hoog, laag, etc. Op deze webpagina is alles al te zien, uitgezonderd de thuispagina. Web≠browsers ondersteunen ook simulatoren voor allerlei tablets en smartphones. De broncode kan via de webbrowser gelezen worden, zet daartoe view-source: voor de url, handmatig, of via het commando control-u.
Als technische informatiebron is gebruik gemaakt van w3schools en de hulpmiddelen voor de web≠ontwikkelaar in Firefox en Chrome. Als context gevoelige broncode editor is Notepad++ gebruikt, en soms BlueGriffin.

*  Een tag is letterlijk vertaalt een label, maar in HTML hebben 'tag' en 'label' ieder een eigen betekenis. Daarom is de vertaling achterwege gelaten. Verderop in de tekst is het HTML begrip 'anchor' ook onvertaald gebleven.

Opzet en indeling

Deze website bestaat uit een twintigtal webpagina's. Er is ťťn HTML bestand per webpagina die gebruik maakt van het gemeenschappelijke CSS bestand, style.css. Er is geen gebruik gemaakt van scripting.
De indeling van een webpagina wordt in de volgende vier figuren getoond, waarbij de lichtblauwe achtergrond het scherm aangeeft.
 

header

zij-
me-
nu




main




footer

Algemene pagina

 icon
headertekst
headertekst
topmenu


main


footer



Welkompagina

icon
headertekst
topmenu



zij-
me-
nu



main


footer

Andere pagina's
breed scherm



icon

Z
header-
tekst
top-
menu

main



footer


zij-
me-
nu




Andere pagina's
smal scherm
 
Een algemene webpagina van deze website bestaat uit een header, het main gedeelte en een kleine footer. Verder is er optioneel een zijmenu links naast het main deel. Een header bestaat uit het icon, headertekst en topmenu. De precieze opbouw van de header is verschillend voor de thuispagina (welkompagina) en andere pagina's. Bij een smal scherm splitst het topmenu (en headertekst) zich op over twee rijen als het niet meer op ťťn rij past. Ook is voor een smal scherm het optionele zijmenu standaard buiten beeld, zodat er meer ruimte voor main overblijft. Als de linkerzijde van het scherm wordt aangeraakt verschuift het zijmenu binnen beeld, over de linkerkant van main heen. Ook kan het kleine zijmenu-icon Z aangeraakt worden. Deze geeft met zijn aanwezigheid aan dat er links buiten beeld een zijmenu is.

De welkompagina

De welkompagina is eenvoudiger van opbouw dan de anderen. Deze heeft geen zijmenu en de header zit gewoon altijd boven main, en beweegt mee met scrollen. Er staat meer tekst in de header dan bij de andere pagina's. De welkompagina is vrij kort en het topmenu staat in het midden, de navigatie is onder handbereik.

Probleem: Op een smal scherm zoals een smartphone in verticale houding is het icon te klein en de headertekst rommelig door ruimtegebrek.
Oplossing: Laat het icon en het tekstvak gedeeltelijk overlappen in de welkomheader, zoals de figuur ook laat zien. De tekst vouwt zich nu om het figuur van de icon. Dit overlappen is gedaan met een negatieve margin-left.
Detail: dit werkt niet in een td tag maar wel in een div tag, vandaar dat het tekstvak in de td in een div blok is ingepakt.

De andere pagina's

Om ruimte te sparen heeft de header van de andere pagina's een kleinere hoogte dan in de welkompagina, minder headertekst en het topmenu zit bovenin. Als al genoemd kan het zijmenu links buiten beeld geplaatst worden om main meer ruimte in de breedte te geven.

Probleem: Bij het naar beneden scrollen verdwijnt het topmenu snel uit beeld en is navigatie buiten bereik.
Oplossing: De header krijgt position: fixed. Zo blijft de header met het topmenu altijd zichtbaar bovenin het scherm vastgepind. Bij verticaal scrollen beweegt main er als het ware onderdoor. Daarom is de header hierboven getekend met dikke rand, en is de bovenste rand van main weggelaten. Ook het zijmenu krijgt position: fixed zodat je deze altijd kunt gebruiken om te navigeren binnen de pagina. Wel moet deze bij een smal scherm soms eerst vanaf links tevoorschijn gehaald worden.

Probleem: Op een ondiep scherm, zoals bij een smartphone in horizontale houding, valt het zijmenu gedeeltelijk onder het beeld. Er kan ook niet naar gescrold worden, want deze is 'fixed', vastgepind aan de positie buiten beeld.
Oplossing: Schuif op een ondiep scherm het zijmenu omhoog dichtbij het icon. Verklein de tussenruimte tussen de knoppen zodat maximaal 4 knoppen passen. Als er meer dan 4 knoppen in het menu zijn, dan worden deze gedeeltelijk in submenu's ondergebracht. Op een breed scherm strekt dit submenu zich uit naar rechts, op een smal scherm (zoals smartphone in verticale houding) naast het zijmenu naar beneden. Deze scherm breedte/hoogte afhankelijkheden zijn gerealiseerd met @media only screen declaraties in CSS.

Menu's

Een menu is in wezen een rij knoppen met in elke knop een link. Door op een knop te klikken (met de muis) of tikken (bij aanraakbediening) navigeert de webbrowser naar een andere plek binnen de website. Ook verandert het uiterlijk van de knop bij klikken/tikken, idem bij aanraking.
Het topmenu dient om tussen webpagina's te navigeren. Elke knop van het topmenu heeft naast een link ook een submenu dat normaal onzichtbaar is. Het submenu bestaat uit een rij knoppen met directe toegang binnen de andere pagina's (of een ruimere keuze van webpagina's). Het submenu van een knop verschijnt bij aanraking van de menuknop (met muis of vinger).
Het zijmenu dient om binnen de pagina direct naar bepaalde plekken (de zogenaamde anchors) te springen. Een zijmenuknop heeft ook een submenu als er veel anchors zijn, b.v. in Uitgebreid.html. Dit zou anders een te lang zijmenu geven met te veel knoppen onder elkaar.
De realisatie van een menu of submenu is als volgt. Elk menu is een rij knoppen. Een rij is in HTML een lijst ul, waarin elk lijstitem li een knop (een link a) bevat en optioneel een submenu. De knop van een submenu heeft geen sub-submenu. De opmaak van het menu en de knoppen, en het effect na aanraking van een knop, wordt bepaald door de gebruikte CSS klasse. Het topmenu gebruikt de klasse navigation. Het zijmenu gebruikt de klasse linavigation. De locatie van het zijmenu wordt door id leftsidemenu bepaald. Deze is ook in CSS gedefinieerd.
Bij aanraking, hover, van een top- of zijmenuknop met submenu verandert de display eigenschap van de submenulijst van none (onzichtbaar) in block (zichtbaar). Tegelijk wordt hiermee het aanraakgevoelige gebied uitgebreid met de submenulijst omdat deze nu zichtbaar is geworden. Hierdoor kan de muis of vinger vervolgens een submenu knop aanklikken. Als het aanraakgevoelige gebied verlaten wordt, ofwel hover stopt, verandert de display eigenschap van de submenulijst weer in de standaard waarde, none (onzichtbaar). Ook krijgt de aangeraakte menuknop weer de standaard opmaak.
Het naar een anchor toe springen in een pagina is verfraaid door een animatie van een gladde verticale scroll beweging. Dit wordt gerealiseerd door in CSS de tag html de declaratie scroll-behavior: smooth te geven, mits ondersteund (zo niet: zie de details in CSS).

Menu's in een smal scherm

Als het scherm niet breed genoeg is breekt het topmenu af en komen de rest van de knoppen in een tweede rij (zie figuur 'Andere pagina's smal scherm'). De header wordt dan hoger. Het zijmenu staat voor smallere schermen links buiten het beeld, zodat main meer ruimte heeft door schermbreed te kunnen zijn. Het zijmenu verschijnt op de normale plek (bovenop de verbrede main) door het scherm aan de linker kant aan te raken, of door het zijmenu-icon Z aan te raken. Deze laatste bevindt zich op de grens van main en header aan de linker zijde. Een @media only screen declaratie in CSS herkent een breed scherm en maakt de ruimte voor een permanent zichtbaar zijmenu in main.
De vanaf buiten beeld links inschuivende variant van het zijmenu wordt in CSS gerealiseerd met de klassen popup-zijmenutop, popup-zijmenu, en ids leftsidemenu en leftsidemenutop. Het werkt op een vergelijkbare manier als dat een submenu verschijnt na aanraking van een menuknop. Alleen wordt nu door de aanraking niet display: none vervangen door display: block, maar margin-left: -8.5em (links ver buiten beeld) door margin-left: 10px (normale positie, bovenop main). Ook is het aanraakgevoelige gebied groter gekozen dan bij menuknoppen: de hele linkerkant van main is aanraakgevoelig. De verschuiving van buiten beeld naar binnen beeld kan geleidelijk verlopen als een animatie, door gebruik te maken van transition: margin-left 0.4s. Dit verduidelijkt waar het zijmenu vandaan komt, in plaats van een verschijning ogenschijnlijk uit het niets.
Ter vermaak maakt de kleine sidebarbutton Z dan een halve rotatie, alsof deze het zijmenu al draaiende binnen sleept. Dit is gerealiseerd met een transform: rotate die met een transition: transform 0.6s geanimeerd is.
Detail: na een halve rotatie is het schaduweffect van Z naar de tegenovergestelde kant meeverhuisd. Dat ziet er heel vreemd uit. Daarom is een aanvullende actie nodig om het schaduweffect box-shadow naar de gewone kant terug te brengen. Deze overgang van het schaduweffect (transition box-shadow) heeft bovendien een timing nodig die past bij de rotatie (namelijk de halve rotatietijd) om geen rare tijdelijke effecten te krijgen, zoals plotseling even een tegenovergestelde schaduw aan het begin of einde van de rotatie.

Main: problemen door de 'fixed' header

De header van de andere pagina's heeft position: fixed, ofwel het topmenu ligt vast boven in het scherm boven op main. Om main helemaal zichtbaar te laten zijn, moet dus het bovenste stuk (waar de header zit) overgeslagen worden. Dit kan in principe door margin-top te gebruiken in main, zo kan main onder de header uit geschoven worden. Daarnaast is de hoogte van de header variabel, omdat het topmenu en de headertekst uit 1 of 2 rijen kan bestaan, afhankelijk van de breedte van het scherm.

Probleem: Main heeft twee verschillende waarden van margin-top nodig, afhankelijk van de breedte van het scherm.
Oplossing: Dit is dynamisch instelbaar door gebruik te maken van @media only screen declaraties in CSS.
De main van de welkompagina heeft dit probleem niet. Daarom overschrijft deze de margin-top met een kleine vaste waarde.

Probleem: Bij het springen naar een anchor (vanuit het zijmenu of topsubmenu) scrolt de webbrowser het anchor bovenin het scherm, ofwel, verborgen onder de fixed header.
Oplossing: De oplossing bestaat uit twee elementen: de browser wijs maken dat de anchor hoger zit dan dat hij zit, en deze hoogte dynamisch instelbaar maken afhankelijk van de schermbreedte. Het eerste doen we door elke anchor vooraf te laten gaan door een lege span van klasse anchored. Door de details van deze klasse wordt de browser wijs gemaakt dat hij naar een hogere positie moet scrollen, zodat de anchor lager belandt, onder de header uit. De precieze werking staat als commentaar in CSS. De grootte van de aanpassing wordt dynamisch door @media only screen declaraties in CSS gerealiseerd.
(Mogelijk zou ditzelfde gerealiseerd kunnen worden door de eigenschap scroll-margin-top, al zegt w3schools er niets over en staat op diverse plekken dat deze eigenschap niet altijd werkt.)

Main: interne schaalbaarheid

Het main gedeelte is onderverdeeld in hoofdstukjes, met h2 opmaak voor de hoofdstuktitel. Een hoofdstuktitel heeft ook een anchor, zodat er naartoe gesprongen kan worden vanuit de menu's. De externe schaalbaarheid van het main gedeelte wordt bepaald door het zijmenu en de header: welke ruimte laten zij over voor main. Als hierboven beschreven krijgt het main deel meer ruimte in de breedte door het uit beeld schuivende zijmenu, en minder ruimte bovenin als het topmenu zich opsplitst over twee rijen.
Het main gedeelte kan verder intern op verschillende manieren omgaan met variabele breedtes/hoogtes van het scherm als volgt.
Woorden kunnen worden afgebroken aan het einde van een regel en op de volgende regel verder gaan, m.a.w., hyphenation is ingesteld voor Nederlands, in tag html met lang="nl". Als dit niet goed werkt in een woord kan met het zogenaamde soft-hyphen ­ de afbreekplek aangegeven worden.
Voor sommige bezoekers kan meer informatie interessant zijn op specifieke punten. Dit kan je op de huidige webpagina optioneel tonen als popup of dropdown. Na aanraking zweeft de content van de popup boven de tekst met klassencombinatie popup, popup-content, zie in het Voorbeeld van HTML bovenaan deze pagina. De content van de dropdown wordt tijdelijk aan de tekst toegevoegd met klassencombinatie dropdown, dropdown-content.
Probleem: Hoe plaatjes te tonen als er weinig ruimte beschikbaar is.
Oplossing 1: Plaatjes kunnen groeien en krimpen met de schermbreedte door de breedte een percentage te laten zijn van de achtergrond, b.v. width: 15%. Ook moeten plaatjes niet te groot of te klein worden, dit kan als volgt in een style of klasse worden opgenomen: max-width:30% en min-width: 30px. Een handige combinatie is in de klasse righttopkwart vastgelegd. Deze positioneert een plaatje aan de rechterzijde, en geeft het een maximale breedte van een kwart.
Oplossing 2: Bij afnemende breedte kunnen plaatjes verhuizen van naast de tekst naar onder de tekst. Dit kan met 'wrap around', met behulp van de style display: flex; flex-wrap: wrap; flex-direction: row;. Alleen als details van het plaatje inhoudelijk belangrijk zijn, heeft oplossing 2 de voorkeur.

Soms wordt er voor gekozen om content pas zichtbaar te maken als de schermbreedte voldoende is. Dit wordt gerealiseerd met lokale style definities in HTML, door display: none of juist display: inline in te stellen, afhankelijk van de breedte met @media only screen declaraties. Om dit in actie te zien: bekijk deze pagina met een smartphone in verticale houding, en dan horizontaal.

Tenslotte

Het is aardig om een website te maken alleen uitgaande van de HTML en CSS, en dat die dan toch werkt op zoveel systemen en webbrowsers. Het voordeel van de aanpak is dat alles onder eigen controle is, alles is aanpasbaar. Daarnaast is HTML en CSS goed gedocumenteerd en niet echt moeilijk. Accumulatie van meer technologieŽn, zoals het toevoegen van sjablonen en scripting, vergroot de complexiteit aanzienlijk.
Het ontwikkelproces is iteratief met elke keer voortschrijdende inzichten na een geconstateerd probleem, vaak na feedback van anderen. Het resultaat voldoet. Natuurlijk kan het altijd beter, daarom blijven suggesties welkom.
Mocht de website ook gegevensinvoer van de gebruiker gaan gebruiken, dan zou scripting (b.v. JavaScript of php) niet meer te vermijden zijn. Nu gaat interactie met de gebruiker via mail, telefoon of een ontmoeting.

Het belangrijkste van een website is hierboven onbenoemd gebleven. Dat zijn goede teksten, plaatjes, kortom, content. Hoe leg je kort de essentie van je boodschap uit op een prettige manier aan de doelgroep. Ook wat dat betreft blijven suggesties welkom.

© Ton Kostelijk, Veldhoven 2022.