Skip links en inhoudsopgave

charset, tekenset, utf-8, entiteiten, accenten, en dergelijke

Laatst aangepast: .

Als je dit artikel afdrukt, wordt automatisch een printvriendelijke versie afgedrukt.
Dit artikel is van toepassing op alle browsers op alle systemen.
Links in dit artikel, vooral links naar andere sites, kunnen verouderd zijn. Op de pagina met links vind je steeds de meest recente links.
Tekst die tussen << en >> staat, is een link naar internet.
Tekst die omgeven is door een lijn (meestal een stippellijn), verwijst naar een andere plaats binnen het artikel. Op de site zijn dit ankers, maar dat werkt nou eenmaal niet op papier.

charset of tekenset

Nu nauwelijks nog voor te stellen, maar in de begintijd kon een computer maar een zeer beperkt aantal tekens weergeven. Een van de eerste genormaliseerde charsets of tekensets is de ASCII-set, die nog steeds wordt gebruikt.

Deze set kon 127 codes bevatten, waarvan er dan ook nog 'ns 32 waren gereserveerd voor controle-tekens zoals 'n nieuwe regel. Waardoor er dus maar 95 letters en dergelijke konden worden weergegeven. In een wereld waar vele tienduizenden tekens nodig zijn om alle geschreven talen weer te kunnen geven, schiet dat niet echt op.

Al vrij snel werd de set van 127 tekens uitgebreid tot 256 tekens. Dat gaf ruimte voor wat accenten (alleen voor westerse talen) en wat speciale tekens als lijntjes. Het aantal moest tot 256 tekens worden beperkt, omdat de tekens werden weergegeven met behulp van een byte. Een byte bestaat uit 8 bit. En omdat een bit alleen 1 of 0 kan zijn, kan een byte 2 x 2 x 2 x 2 x 2 x 2 x 2 x 2 = 256 verschillende waarden bevatten. Deze ogenschijnlijk vreemde getallen ontstaan, omdat een computer alleen met een 1 of 0 goed overweg kan.

256 tekens zet dus nog steeds niet echt veel zoden aan de dijk. Daarom ontstond een aantal verschillende sets van 256 tekens, die elk waren aangepast aan een andere taal en de in die taal voorkomende speciale tekens. Deze sets werden min of meer gestandaardiseerd door de ISO.

Als het om het afwijken van een standaard gaat, heeft Microsoft een geduchte reputatie hoog te houden. Dus Microsoft maakte zijn eigen charsets. Die lijken wel veel op die van de ISO, maar zijn net niet helemaal hetzelfde. Mede hierdoor hebben we jarenlang opgescheept gezeten met pagina's, waarin vraagtekens of vreemde tekens verschenen op de plaats, waar 'n letter met 'n accent of 'n ander speciaal teken zou moeten staan.

Een byte kan dus maar 256 verschillende tekens weergeven. Met wat kunst- en vliegwerk zou je misschien nog in één pagina verschillende charsets kunnen gebruiken, zodat je 'n aantal verschillende sets van 256 tekens zou kunnen gebruiken, maar op de vele tienduizenden die er nodig zijn, is dat toch niet echt ideaal. En dan hebben we 't nog niet eens over wetenschappelijke tekens, symbolen, noem maar op.

Als je nu 2 bytes zou gebruiken voor elk teken, dan heb je opeens 256 x 256 = 65.536 mogelijkheden. Dat begint er op te lijken. En als dat nog niet genoeg zou zijn, zou je zelfs 3 bytes kunnen gebruiken. Een fantastische oplossing.

Met helaas één gigantisch nadeel: elke tekst wordt opeens twee keer zo groot, omdat voor elk teken opeens niet één, maar twee bytes worden gebruikt. En als je drie bytes gebruikt, wordt de tekst zelfs drie keer zo groot. Voor 'n website is dit dus niet echt ideaal, want alles moet elektronisch worden verzonden.

Tegenwoordig zou dit in bepaalde delen van de wereld niet echt een probleem zijn, omdat de toegang tot internet enorm is verbeterd. Maar dat geldt niet voor de hele wereld. En ook in landen met een goede toegang zijn vaak nog plekken, waar dat niet het geval is. Als je moet betalen voor de hoeveelheid data die je gebruikt, is een verdubbeling van die hoeveelheid ook geen reden om in gejubel uit te barsten. Ten slotte: hoe meer data, hoe slechter voor het milieu, want het vervoer van al die data kost stroom. Weliswaar veel minder dan afbeeldingen of video, maar waarom zou je onnodig bijdragen aan de klimaatcatastrofe?

Er zijn twee mogelijke oplossingen voor dit probleem.

Je kunt 'n beperkte charset gebruiken, die alleen maar 'n beperkt aantal tekens bevat. Zoals alle westerse letters, cijfers en de meest gebruikte accenten. Dan heb je maar 1 byte per teken nodig. Maar dan moet elke bezoeker ook precies diezelfde charset op z'n computer hebben staan, en je zit nog steeds met het maximum van 256 tekens. De tweede oplossing is beter.

utf-8

Deze betere oplossing heet utf-8. Deze charset heeft codes die variëren in grootte. Voor de meest gebruikte westerse letters en dergelijke wordt slechts 1 byte gebruikt. Voor talen als Chinees worden twee bytes gebruikt. Voor weinig gebruikte tekens kunnen nog meer bytes worden gebruikt. Het voert te ver om hier uit te leggen, hoe die codering verder precies werkt. Links naar pagina's met meer technische informatie kun je vinden op de pagina met links. onder het kopje HTML → Charsets, unicode, entiteiten.

Door deze geniale truc heb je de beschikking over 'n gigantisch aantal tekens, terwijl het document toch niet groter worden dan nodig is. Er is op die manier in de utf-8 ook voldoende ruimte voor allerlei wetenschappelijke tekens, symbolen, pictogrammen, en dergelijke, en zelfs voor dingen als runen, spijkerschrift en dominostenen.

Er zitten echter wel wat haken en ogen aan. Een computer slaat een pagina van 'n site op als 'n serie codes. Er zitten geen 'letters' in de computer, alleen bits. De browser zet die codes weer om naar voor mensen begrijpelijke letters en dergelijke. Maar om dat te kunnen doen, moet die letter, moet dat font, wel in de computer zijn geïnstalleerd. Als je geen font met runen hebt geïnstalleerd, weet de computer niet, hoe de utf-8-code voor een runenteken moet worden omgezet naar een runenteken.

utf-8 geeft in potentie echter wel de mogelijkheid om dit soort dingen weer te geven. Als mensen bijvoorbeeld in runen zijn geïnteresseerd en daarvoor 'n forum bezoeken, mag je aannemen dat ze ook zo'n font met runen hebben geïnstalleerd, of dat in ieder geval willen doen. En op dat moment kunnen de forumbezoekers dus via runentekens met elkaar communiceren.

Het gebruik van utf-8 heeft 'n hele reeks voordelen boven het gebruik van andere tekensets.

utf-8 wordt over de hele wereld gebruikt, dus ook in China wordt jouw pagina op de goede manier weergegeven: in westerse letters (tenzij je natuurlijk Chinees schrijft). Mogelijk wordt er niets van begrepen, maar 't wordt in ieder geval goed weergegeven. En nog mooier: als je het juiste font hebt geïnstalleerd, kun jij ook 'n Chinese pagina in het Chinees bekijken!

Elke niet volstrekt prehistorische browser kan met utf-8 overweg, zelfs het vreselijke Internet Explorer 6. Problemen met 'n verschillende weergave tussen bijvoorbeeld 'n Mac of 'n Windows-computer zijn dus verleden tijd bij het gebruik van utf-8. In feite is utf-8 zo bruikbaar, dat het dé standaard is geworden voor gewone tekst.

Omdat html, css en JavaScript - de talen waaruit een website bestaat - alle drie eigenlijk gewone tekst zijn, kan utf-8 hier prima mee uit de voeten. Die talen zien er misschien niet uit als gewone tekst, maar ze zijn volledig opgebouwd uit min of meer gewone letters, symbolen en cijfers. Hierdoor kan ook een browser hiermee uitstekend overweg.

Elke goede editor, tekstverwerker, enzovoort kan tekst opslaan als utf-8. Dat wil zeggen dat accenten en dergelijke door de editor automatisch worden omgezet naar de juiste utf-8-code. Als het programma dat je gebruikt om 'n site mee te maken geen utf-8 op kan slaan, zou alleen dat al 'n reden moeten zijn om het acuut niet meer te gebruiken. Het is dan óf volstrekt verouderd, óf absolute bagger.

Dit laatste betekent ook dat je de meest gebruikte accenten en dergelijke kunt invoeren met de sneltoetsen, die gebruikelijk zijn voor het programma of het besturingssysteem. Het programma 'vertaalt' de accenten en dergelijke automatisch naar de juiste utf-8-code. Je kunt dus gewoon de sneltoetsen gebruiken, waar je mogelijk al aan gewend bent.

Zo kun je op Linux overal de € invoeren door simpelweg rechter-control gevolgd door C gevolgd door = in te typen. Op Linux heb je zo enkele honderden simpel te onthouden combinaties. Op 'n Mac en op Windows heb je soortgelijke mogelijkheden.

Als je opslaat als utf-8, is het in ieder geval onmogelijk dat je 'n sneltoets gebruikt voor 'n teken dat niet in de charset zit. Simpelweg omdat álle tekens erin zetten. Bij een beperktere charset kan dat wel gebeuren.

Als je een teken opslaat dat niet in de gebruikte charset zit, wordt het teken niet volgens de standaard opgeslagen. Bij het weergeven van de pagina in je browser krijg je dan mogelijk zo'n vreemd vierkant vraagteken of 'n vreemde reeks tekens. Of nog erger: jij ziet het wel goed, omdat jouw browser (toevallig) de goede charset gebruikt. Maar bezoekers van je site zien 'n raadsel, omdat de browser van je bezoeker niet de door jou gebruikte charset heeft. Wat dus, tot de komst van utf-8, schering en inslag was.

Niet voor elk accent en dergelijke bestaat in elk programma 'n sneltoets. Om het nog maar niet over Chinees en zo te hebben. Daarom is er een tweede manier om tekens in te voeren.

Elk teken uit de utf-8 tekenset kan met behulp van een speciale code worden ingevoerd. Een utf-8-code begint altijd met &#x of &#, en eindigt altijd met ;.

Het teken & geeft het begin van een entiteit aan. Het teken # wordt vaak gebruikt in computertalen om een getal aan te geven. De letter x wordt vaak gebruikt om aan te geven, dat het om een hexadecimaal getal gaat: een getal dat bestaat uit cijfers en letters. Het volledige begin &#x geeft dus aan dat het hier om een hexadecimale entiteit gaat. Na de &#x komen vier letters en/of cijfers.

Als de x aan het begin mist, is de code een gewoon getal, alleen gevormd uit 1 of meer gewone cijfers. Voor de rest werkt het precies hetzelfde als een hexadecimale code.

De ; geeft het einde van de entiteit aan.

Op de theorie van hexadecimale getallen ga ik hier verder niet in, op internet is er genoeg over te vinden. Als je hexadecimale getallen niet begrijpt, maakt dat niets uit. Je neemt gewoon de vier letters en/of cijfers over, zoals je ook met 'n gewoon getal zou doen. Zo geeft &#x215b; de breuk ⅛. (Als je me niet gelooft, kun je even in de broncode van deze pagina kijken. Daarin is geen breuk te vinden, maar wel de utf-8-code voor een-achtste.)

Op de pagina met links staan onder het kopje HTML → Charsets, unicode, entiteiten → Lijsten met karakters en/of opzoeken van entiteit, utf-8-code, codepoint, en dergelijke links naar pagina's, waarin je de juist utf-8-code kunt opzoeken.

Entiteit

De meest gebruikte accenten en dergelijke kun je in veel programma's met sneltoetsen invoeren. Als zo'n toets er is, kun je die gebruiken. Dat is veel makkelijker dan zo'n lastige utf-8-code invoeren. Maar niet voor elk vaak gebruikt accent en dergelijke bestaat 'n sneltoets, omdat er veel meer accenten, leestekens, breuken, enzovoor zijn dan sneltoetsen. Daarom is er nog een andere manier om veel gebruikte tekens in te voeren, die voor mensen makkelijker te onthouden is dan utf-8: entiteiten.

Een entiteit begint altijd met & en eindigt altijd met ;. Daartussen staat 'n voor mensen relatief makkelijk te onthouden naam, in ieder geval makkelijker te onthouden dan 'n viercijferig hexadecimaal getal. Zo wordt bijvoorbeeld het copyright-teken © ingevoerd als &copy;.

Entiteiten kun je altijd gebruiken, onafhankelijk van welke charset je gebruikt. Maar als je utf-8 gebruikt, heb je zelfs geen entiteiten nodig voor veel gebruikte accenten en dergelijke. En 'n ä is natuurlijk veel makkelijker te onthouden en in te voeren als (op Linux) Shift+" gevolgd door a, dan als &auml;, vooral omdat dit op Linux desgewenst voor elk programma exact hetzelfde is voor honderden bijzondere toetsen (wie riep hier dat Windows gebruiksvriendelijker is dan Linux?).

In html is het aantal entiteiten enorm uitgebreid. Lang niet alle browsers ondersteunen echter alle entiteiten. Als je 'n entiteit uit html gebruikt, is het daarom echt belangrijk te testen, of die wel goed wordt weergegeven. Of gewoon voor de zekerheid de utf-8-code gebruiken, die werkt altijd. Entiteiten uit eerdere versies van html worden inmiddels goed ondersteund.

&, < en >

Er zijn twee tekens die altijd als entiteit moeten worden ingevoerd: de ampersand & en het kleiner-dan teken <. Dat is ook vrij logisch. De & geeft het begin van een entiteit aan. Als je dit gewoon als & in zou voeren, denkt de browser dus dat er een entiteit gaat volgen, en dat kan problemen geven. Het <-teken is het begin van een html-tag, dus de browser gaat ervan uit dat hierna de rest van een tag volgt, en ook dat kan problemen opleveren.

De & wordt ingevoerd als &amp; (ampersand) en de < als &lt; (less than, kleiner dan).

Het teken > kan ook het best als entiteit worden ingevoerd. Dit teken geeft het einde van een tag aan. Als je dit teken gewoon als > in zou voeren, kan dit in sommige gevallen problemen geven, omdat de browser denkt dat het om het einde van een tag gaat. Dit teken wordt ingevoerd als &gt; (greater than, groter dan).

Schermlezers

Schermlezers kunnen woorden die bestaan uit gewone letters en getallen prima voorlezen. Ook letters met accenten (diakritische tekens) leveren geen probleem op. (Uiteraard op voorwaarde dat bij <html> de juiste taal is opgegeven, en dat dat ook is gedaan bij zinnen en woorden met een van de pagina afwijkende taal.) Zodra het echter om min of meer bijzondere tekens gaat, gaat het (heel erg) vaak mis. Er zijn zelfs schermlezers die moeite hebben met een gewoon teken als '+', een doodgewone plus.

Het maakt hierbij niet uit, op wat voor manier het teken is ingevoerd: met een entiteit of een utf-8-code. Dit is niet goed op te lossen door de maker van een site. Alleen makers van schermlezers kunnen dit oplossen door (eindelijk) in ieder geval de meest gebruikelijke 'vreemde' tekens te gaan ondersteunen. Je kunt toch moeilijk elke doodgewone '+' voluit als 'plus' gaan uitschrijven.

Op deze site is soms voor meer exotische tekens wel een aanpassing gemaakt. Ergens wordt bijvoorbeeld in een inhoudsopgave het Romeinse cijfer 'XXIII' (23) gebruikt. Ook voor Romeinse cijfers bestaan utf-8-codes. Als je die gebruikt, negeert schermlezer TalkBack op Android de cijfers doodleuk helemaal. VoiceOver op iOS en iPadOS leest iets voor dat klinkt als 'X X ai ai ai'. Een leuke aanhef voor een tango, maar geen Romeins cijfer. Andere schermlezers zijn maar niet eens meer geprobeerd.

In dit specifieke geval is dat opgelost met:

<span aria-hidden="true">XXIII</span><span class="sr">bladzijde romeins 23</span>

De eerste <span> met 'XXIII' wordt met behulp van aria-hidden="true" voor schermlezers verborgen, maar staat gewoon op het scherm. De tweede <span> met class="sr" wordt onzichtbaar buiten het scherm gepositioneerd. Maar de tekst 'bladzijde romeins 23' wordt door schermlezers toch gewoon voorgelezen. Nu staat op het scherm 'XXIII', maar schermlezers lezen 'bladzijde romeins 23' voor.

Dit werkt prima, maar zoals gezegd: dit is natuurlijk niet te doen voor élk maar iets afwijkend teken.

Over schermlezers en de problemen met bijzondere tekens is meer te vinden op de pagina met links onder het kopje Toegankelijkheid → Schermlezers, tekstbrowsers, en dergelijke → Algemeen.

Het opgeven van de charset

Omdat een computer niet zo vreselijk slim is, moet je opgeven welke charset je gebruikt. Dat doe je met behulp van een speciale opdracht in de <head> van je pagina. Het kan ook worden opgegeven via de server, maar de meeste mensen zullen geen server hebben die ze kunnen instellen.

Als je geen charset opgeeft, moet de browser gaan raden welke charset er is gebruikt, en regelmatig gaat dat mis.

Tot een paar jaar geleden rookte je twee joints en/of dronk je twee borrels, waarna je in staat was om foutloos de volgende gruwelijkheid in te typen:

<meta http-equiv="Content-Type" content="text/html; charset=utf-8">

Er staat meer in dan alleen de charset, omdat zo'n regel ook aan de algemene eisen voor een meta-tag moet voldoen. Deze regel eindigt op '>' Dit hoort bij een doctype voor html 4.01 en eerder. Bij een doctype voor xhtml moet de regel eindigen op ' />' (spatie plus />).

Sinds een aantal jaren kunnen alle browsers kunnen ook overweg met de regel voor html5, die met voorsprong het makkelijkste is:

<meta charset="utf-8">

Zelfs Internet Explorer 6 begrijpt deze regel, dus er is geen enkele reden om deze veel simpeler regel niet te gebruiken.

Deze regel moet zo hoog mogelijk komen te staan, als eerste regel binnen de <head>, omdat hij anders door sommige browsers niet wordt gelezen.

De code moet door de editor worden opgeslagen in hetzelfde formaat als dat van de opgegeven charset. Als je dat niet doet, krijg je van die vreemde vraagtekens of andere tekens in je pagina.

Soms wordt een charset van een bestaande pagina omgezet naar een andere, bijvoorbeeld van windows-1252 naar het gestandaardiseerde utf-8. Je moet dan de code opnieuw opslaan in het formaat van de nieuwe charset. Als je dat niet doet, is de kans groot dat je bij weergave van de pagina vierkante vraagtekens en andere ongein ziet.

De tekst is dan nog opgeslagen volgens de codering van charset windows-1252, maar bovenin je pagina staat dat hij moet worden weergegeven volgens de codering van utf-8. Tja. Het is ook wat lastig een Franse tekst naar het Nederlands te vertalen, als je alleen een Duits woordenboek hebt.