Advertentie
Wetenschap & Techniek
Waarom websites in andere browsers stilletjes kapotgaan
In de eigen Chrome ziet alles er goed uit, op de iPhone van de klant niet: drie rendering-engines, breakpoints en automatische browserupdates zorgen ervoor dat websites zonder enige foutmelding kapotgaan. De mechaniek erachter — en wat eraan te doen is.

De bugmelding klinkt vertrouwd: „Bij mij ziet de pagina er kapot uit." De ontwikkelaarster opent de pagina, ziet — niets. Alles op zijn plek. Pas het terugbelgesprek brengt duidelijkheid: de klant gebruikt Safari op de iPhone, zij Chrome op de desktop. Daartussen liggen twee rendering-engines, meerdere schermbreedtes en een reeks stille verschillen, waarvan er nooit één een foutmelding heeft opgeleverd.
Dat dezelfde website er per browser anders uit kan zien, is geen bedrijfsongeval maar architectuur. In de kern van elke browser werkt een rendering-engine die HTML en CSS in pixels vertaalt. Drie families delen vandaag praktisch de hele markt: Blink drijft Chrome, Edge en de meeste kleinere Chromium-afgeleiden aan, Gecko Firefox, WebKit Safari — en op de iPhone renderen tot op vandaag praktisch alle verbreide browsers met WebKit, ook al staat er Chrome of Firefox op het icoon.
Deze engines zijn onafhankelijke implementaties van dezelfde webstandaarden. De standaarden beschrijven wat een CSS-eigenschap zou moeten bewerkstelligen — maar ze laten speelruimte, ze worden verschillend snel doorgevoerd, en af en toe begrijpen twee ontwikkelteams dezelfde formulering anders. Het resultaat zijn drie programma's die hetzelfde document lezen en tot licht verschillende beelden komen. Meestal zijn de verschillen onzichtbaar klein. Soms niet.
Het beslissende punt: die verschillen blijven geluidloos. CSS is bewust fouttolerant ontworpen. Een eigenschap die een browser niet kent, wordt eenvoudigweg genegeerd — zonder waarschuwing, zonder crash, zonder vermelding in enig logboek. Wat bij de introductie van nieuwe technieken een zegen is, omdat oude browsers moderne stylesheets niet met een totale uitval afstraffen, wordt in de dagelijkse praktijk een valkuil: de pagina breekt niet, ze ziet er alleen verkeerd uit. En niemand komt het te weten zolang niemand kijkt.
De typische breukvlakken laten zich ordenen. Daar zijn ten eerste jonge CSS-functies die de ene engine al beheerst en de andere nog niet of in details anders. Daar zijn interpretatiekwesties van de lay-out — hoe flexbox en grid omgaan met minimumbreedtes, afbrekingen of geneste containers, waar de specificatie interpretatieruimte laat. En daar zijn de klassiekers: formulierelementen zoals keuzevelden, checkboxen en datumvelden, die elke browser naar eigen smaak tekent en die zich maar beperkt laten hervormen.
Een voorbeeld uit de eerste categorie maakt het patroon tastbaar. De CSS-eigenschap gap, die afstanden tussen elementen regelt, was voor de grid-lay-out vroeg in alle engines beschikbaar — in de flexbox-context ondersteunde Safari haar echter duidelijk later dan Chrome en Firefox. Een navigatie waarvan de menu-items via flexbox en gap op afstand werden gehouden, zag er in twee engines onberispelijk uit; in oudere Safari-versies plakten de items aan elkaar. Geen foutmelding, geen crash, technisch werkte alles — alleen oogde de pagina op een deel van de iPhones gedrongen en onverzorgd. Uitkomst biedt in zulke gevallen een terugvaloplossing met klassieke buitenmarges; maar daarvoor moet je eerst weten dat het verschil bestaat. Precies dat is bij stille breuken de eigenlijke hindernis: ze staan in geen enkele foutenlijst. Ze staan alleen in het beeld.
Daar komen verschillen bij die helemaal niet in het stylesheet staan. Lettertypen worden op elk besturingssysteem anders gerenderd en vallen verschillend breed uit; een kop die in de ene omgeving op één regel blijft, breekt in de andere af en duwt alles eronder omlaag. Schuifbalken nemen afhankelijk van het systeem ruimte weg van de inhoud of leggen zich eroverheen — en veranderen daarmee de beschikbare breedte. Viewport-eenheden gedragen zich op mobiele apparaten verschillend, afhankelijk van hoe de browser in- en uitschuivende adresbalken verrekent.
De tweede grote bron van stille breuken zijn schermbreedtes. Responsive design definieert omschakelpunten — breakpoints — waarop de lay-out zich herbouwt: de navigatie klapt samen tot een menupictogram, kolommen stapelen zich op elkaar, afstanden krimpen. Getest wordt naar ervaring op de standaardbreedtes van de gangbare apparaten. Kapot gaat het ertussenin: bij ongebruikelijke venstergroottes, op tablets in liggende stand, bij gehalveerde vensters op brede desktopmonitoren.
Duitstalige pagina's worden bijzonder hard getroffen door één eigenaardigheid: lange samenstellingen. Waar in het Engels drie korte woorden staan, staat in het Duits de „Datenschutzgrundverordnung", het woord van één stuk voor de AVG — een woord dat weigert af te breken, uit zijn container steekt of een navigatiebalk opblaast zodra de ruimte krap wordt. Vertaalde interfaces die er in het Engelse origineel onberispelijk uitzagen, behoren daarom tot de betrouwbaarste kandidaten voor afbreekproblemen.
Zelfs een pagina die er vandaag overal correct uitziet, blijft dat overigens niet vanzelf. Browsers actualiseren zichzelf in korte ritmes, rendering-engines veranderen details van hun gedrag — en de website verandert van uiterlijk zonder dat iemand iets heeft gedeployd. De zorgvuldige test bij de lancering is daarom een momentopname, geen blijvende toestand. Hetzelfde geldt in de andere richting: elke CMS-update, elke nieuwe plug-in, elke tekstwijziging kan verschuivingen veroorzaken.
Achter dit alles schuilt een psychologisch grondprobleem dat iedereen uit de ontwikkelpraktijk kent: „works on my machine". Wie een pagina bouwt, ziet haar honderd keer in de eigen browser op de eigen monitor — en houdt die aanblik onbewust voor de waarheid. De bezoekers verdelen zich echter over engines, apparaatklassen en venstergroottes, en geen daarvan meldt zichzelf wanneer er iets verschuift. De minste mensen schrijven een e-mail wanneer een menu overlapt. Ze gaan gewoon weg.
Des te waardevoller is het zeldzame geval dat iemand zich tóch meldt — mits die melding methodisch wordt afgehandeld. Een beproefde aanpak heeft vier stappen. Ten eerste de omgeving uitvragen: welke browser, welk apparaat, welke geschatte vensterbreedte? Zonder die gegevens is elke zoektocht giswerk. Ten tweede in de passende engine reproduceren, niet in een simulatie — desnoods via een screenshotdienst, wanneer er even geen apparaat met de juiste engine voorhanden is; hoe zo'n controleronde verloopt, beschrijft ScanU stap voor stap. Ten derde afbakenen welk mechanisme getroffen is: breekt de lay-out op een omschakelpunt, ontbreekt er een CSS-functie, valt een lettertype breder uit? Het antwoord bepaalt de reparatie — breakpointproblemen lost het eigen stylesheet op, ontbrekende functies vragen om een terugvaloplossing, lettertypeproblemen vaak alleen om ruimere containers. En ten vierde, de stap die het vaakst wegvalt: na de correctie alle engines opnieuw bekijken. Wie alleen de gemelde plek controleert, ziet gemakkelijk over het hoofd dat de reparatie elders iets verschoven heeft.
Voor de hand zou hier de tegenwerping liggen dat de ontwikkelaarstools van de browsers het probleem allang hebben opgelost: elke moderne browser brengt een apparaatmodus mee die schermgroottes van telefoons en tablets simuleert. Die tegenwerping ziet over het hoofd wat die modus daadwerkelijk doet. Wie in Chrome de iPhone-weergave kiest, krijgt een smal venster met aangepaste resolutie en mobiele identificatie — gerenderd wordt echter nog steeds met Blink, de engine van Chrome. De WebKit-eigenaardigheden van de echte iPhone-browser laat die simulatie niet zien, en de Gecko-eigenaardigheden van Firefox evenmin. Voor het werk aan breakpoints is de apparaatmodus een uitstekend werktuig; als bewijs voor browsercompatibiliteit deugt hij niet. Een engine laat zich niet simuleren, alleen verwisselen.
Hoe vindt men breuken die zich niet melden? De traditionele weg is handwerk: een kast vol testapparaten of een browserlijst die iemand na elke wijziging doorklikt. Dat werkt, maar het schaalt slecht — alleen al drie browsers maal drie apparaatklassen levert negen weergaven per pagina op, en de zorgvuldigheid daalt naar ervaring met elke herhaling. De systematischere weg zijn screenshotdiensten die deze visuele controle parallelliseren. ScanU bijvoorbeeld maakt na invoer van een URL in ongeveer 30 seconden screenshots in Chrome, Firefox en Safari, telkens in mobiele, tablet- en desktopweergave; welke apparaatcombinaties beschikbaar zijn, somt het functieoverzicht van ScanU op. In plaats van negen vensters na elkaar te openen, ziet men een raster van beelden — en uitschieters springen in het oog.
Echt interessant wordt het bij de herhaling. Diensten van dit type vergelijken de actuele stand met een opgeslagen referentietoestand en markeren afwijkingen in een directe vergelijking naast elkaar. Zo wordt uit de vage vraag „ziet de pagina er overal goed uit?" de veel scherpere vraag „is er sinds de laatst gecontroleerde stand iets veranderd?" — een vraag die ook te beantwoorden is wanneer niemand nog paraat heeft hoe de pagina er vorige week uitzag.
Ook hier hoort eerlijkheid bij: screenshots tonen toestanden, geen processen. Wat er gebeurt bij het overgaan met de muis, of een menu netjes openklapt, hoe de pagina zich bij het scrollen of bij een trage verbinding gedraagt — dat alles beeldt een statisch beeld niet af. Evenmin vervangt een gerenderd browservenster het gevoel van echte hardware: touchbediening, de prestaties van oudere apparaten, eigenaardigheden van afzonderlijke systeemversies. Vóór een belangrijke lancering blijft het grijpen naar de echte telefoon een goed idee, en functionele tests vervangt een screenshot sowieso niet.
Hoeveel inspanning het onderwerp waard is, hoeft daarbij niemand in algemene zin te beslissen — de eigen bezoekstatistieken geven de richting aan. Zij tonen via welke browsers, apparaatklassen en schermbreedtes de werkelijke bezoekers binnenkomen, en daarmee welke combinaties in de controlelijst voorrang verdienen. Twee kanttekeningen horen daar wel bij. Ten eerste meet de statistiek alleen wie er komt — niet wie wegens een kapotte weergave helemaal niet blijft; een zwak vertegenwoordigde engine kan dus ook gevolg van een probleem zijn, niet alleen teken van geringe relevantie. Ten tweede verschillen de aandelen aanzienlijk per doelgroep en gebruikssituatie: een aanbod dat 's avonds op de bank wordt gelezen, heeft een andere apparaatverdeling dan een vakportaal voor de kantoorpraktijk. De eigen controlelijst zou daarom de eigen cijfers moeten volgen, niet algemene marktoverzichten.
Voor de dagelijkse praktijk volstaat vaak een eenvoudige routine: na elke wijziging aan styles of templates de belangrijkste pagina's over alle drie de enginefamilies controleren; na grotere browserreleases eenmaal het bestand nalopen; bij redesigns bewust ook de tussenbreedtes bekijken, niet alleen de standaardformaten. Wie tegen de inspanning opziet, begint klein — de Nederlandse pagina van ScanU introduceert de dienst, waarvan het gratis niveau met één project en 500 credits per maand voor de eerste stappen volstaat.
De kern van het probleem blijft daarbij bestaan, en dat is misschien wel het eigenlijke inzicht: browsers zullen ook in de toekomst onafhankelijke programma's met eigen engines zijn, standaarden zullen speelruimte blijven laten, en CSS zal blijven zwijgen in plaats van te waarschuwen. Stille breuken zijn geen teken van slordig werk, maar een systeemeigenschap van het web. De omgang ermee is daarom vooral een kwestie van zichtbaarheid: wie de eigen pagina regelmatig met de ogen van alle drie de engines bekijkt — met welk werktuig dan ook —, ontneemt het zwijgen zijn werking.