Cascading Style Sheets

(Voor gevorderden!)

Fraaie kreet, maar waar gaat het nou om? Beschouwt u het als een methode om terugkerend tikwerk uit te sparen (hoewel, je krijgt er ook weer werk voor terug), maar vooral om een meer "eenvormige" stijl in uw pagina's te bevorderen.

Formeel gesproken gaat het om een scheiding tussen de structuur van een tekst en de vormgeving. Tekst bestaat uit alinea's en kopteksten, zo ongeveer, en in dat geheel zit, volgens puristen, een soort hiërarchie. Wat er direct na een H1-kop komt is het belangrijkste, enzovoorts. Dat zien we in HTML hierin terug in dat een H1-kop groter is dan een H2-kop, etcetera. Dat is de structuur, maar verder is er nog weinig onderscheid tussen typen alinea's. CSS beoogt u hier mee vrijheid in te bieden.

Nog niet duidelijk? Kan ik me voorstellen. OK, volgende poging. U zult voor uw tekstverwerking wellicht Mocrosoft Word gebruiken. In dat geval zal ik me van sarcastische opmerkingen onthouden. Maar u ziet dan rechtsboven in de werkbalk van Word staan wat de eigenschappen van dat stuk tekst zijn. Een standaard-alinea heeft als eigenschappen Times New Roman, 12 punt. Dat kunt u veranderen, en als het een beetje meezit heeft Word de volgende keer onthouden dat u een standaard-alinea niet met Times New Roman maar met Arial wilt hebben. Of zo.

Cascading Style Sheets, in de wandeling afgekort tot CSS, is net zoiets, maar dan wat meer "onder de motorkap".

Waar gebruikt u CSS voor?

Stellen wij ons voor dat u aan het begin staat van het maken van een website, die er qua vormgeving best een beetje professioneel uit mag zien. U hebt zich voorgenomen dat alle H3-koppen van uw site de volgende opmaak hebben: donkerblauw, arial, 1.5 cm hoog, cursief. Verder constateert u dat er twee soorten tekstblokjes zijn: "gewone" alinea's en alinea's waarin voorbeelden van het zojuist besprokene gegeven worden. De gewone alinea's moeten Times New Roman hebben en 12 punt hoog zijn. De voorbeeld-alinea's moeten Courier hebben, 10 punt hoog zijn, en links en rechts 3 centimeter inspringen. (Misschien is dit al de plek om er op te wijzen dat u hiermee een paar trucs kunt uithalen die anders niet mogelijk zijn, zoals dat inspringen. Ook kunt u afstanden tussen regels precies instellen, en zo nog wat zaken.1)

U hebt dus 3 keer een setje opmaakkenmerken, die aan elke H3-kop, elke gewone alinea en elke voorbeeld-alinea moeten worden meegegeven. Nu zou u dat elke keer apart kunnen invoeren, maar dat wordt een hele hoop tikwerk. Met Cascading Style Sheets kunt u dat in hoge mate terugbrengen. het komt er op neer dat "ergens" (waar precies, vertel ik zometeen) opgeeft dat zo'n H3-kop, en zulke alinea's zo behandeld moeten worden, en dat daarna de browser, elke keer als hij zo'n ding aantreft, hem op die manier ook weergeeft.

CSS is in feite dus niets anders dan een methode om complexere opmaak-instructies niet steeds te hoeven herhalen.

Hoe doet u het?

CSS houdt dus in dat u als het ware een lijstje maakt van gewenste opmaakkenmerken. Dat lijstje kunt u op twee plekken neerzetten. Ofwel, u doet dit met een apart tekstbestandje, waarnaar u dan in iedere pagina die zo behandeld moet worden verwijst. Ofwel, u neemt dat lijstje op in de header-sectie van elke aparte pagina, waarmee die instructies vanzelf met betrekking tot die pagina worden meegenomen. In beide gevallen wordt het resultaat aangeduid als "style sheet".

Even tussendoor: en wat betekent dat "cascading" dan?

Goeie vraag. Volgens mij is het in de gedachtengang van de bedenker (Bert Bos, voorheen Rijksuniversiteit Groningen, thans verbonden aan het World Wide Web Consortium) zo gegaan dat hij vond dat er een "overkoepelende" style sheet moest zijn, die in beginsel op alle pagina's van toepassing was. Dat doe je dan moet zo'n extern bestandje. Mocht een auteur voor deze ene pagina, ten aanzien van een of meer objecten, iets anders willen, dan kon hij voor die pagina iets anders opgeven. Dat doe je dan met de style sheet bovenaan die pagina. En mocht dan voor één stukje op die pagina het nog weer anders moeten, dan is er nog een mogelijkheid bedacht om -als het een beetje meezit- voor dat ene stukje een uitzondering te maken, met de "<DIV>"-tag. De term "cascading" zou dan iets betekenen als "opeenvolgend". (Hoewel ik de associatie met een waterval niet zo erg duidelijk vind.)

Voorbeeld external style sheet

U zet de gewenste zaken in een tekstbestandje, dat u opslaat (wederom: "Opslaan als: alle bestanden") met de extensie ".css". (Moet zo, anders herkent de browser het verhaal niet.) En dat bestand moet dus in dezelfde directory staan als de pagina die dat bestand zometeen gaat aanroepen.

In casu zou het verhaal er aldus uitzien:
H3 {color: darkblue; font-family: Arial; font-size: 1.5cm; font-style: italic}
P.normaal {font-family: "Times New Roman"; font-size: 12pt}
P.voorbeeld {font-family: courier; font-size: 10pt; margin-left: 3cm; margin-right: 3cm}

Het luistert hier erg nauw. De opmaakkenmerken staan dus tussen accolades. U geeft alle kenmerken van het betreffende ding achter elkaar op, gescheiden door puntkomma's. Eenheden als punten en centimeters worden zonder spaties geschreven. Bij "Times New Roman" moet u, omdat dit fenomeen uit meerdere woorden bestaat, dit tussen aanhalingstekens zetten. Nog een opvallend punt: u hebt hier twee "modellen" van het fenomeen "alinea" gecreeërd: eentje met de naam "normaal" en eentje geheten "voorbeeld". In programmeursjargon: u hebt meerdere classes van het object alinea gecreeërd.

Nu moet u dit bestand nog "aanroepen". Dat doet u door in de header-sectie van uw pagina de volgende instructie te zetten: <LINK REL=STYLESHEET HREF="naam_van_bestand.css" TYPE="text/css">.

Dat werkt dus voor alle pagina's die er naar gelinkt zijn

Het effect van dat external style sheet is dat de opmaak van alle pagina's die er naar toe gelinkt zijn erdoor bepaald wordt. (Voorzover er dus in die pagina zelf niet met een internal style sheet van wordt afgeweken, volledigheidshalve.) Dat betekent vooral dat u, als u een opmaak-detail wilt wijzigen, u niet x pagina's hoeft door te lopen. U verandert gewoon één keer de betreffende passage in de external style sheet.

Als ik overal in deze cursus de H2-kop van "darkred" in "darkblue" wil veranderen, kan ik volstaan met die ene regel in de style sheet aan te passen. En dat is zeker een voordeel.

Voorbeeld internal style sheet

Dat ziet er vrijwel hetzelfde uit, maar dan neemt u die instructies op direct in de header-sectie van uw document, en kunt u die "LINK"-instructie uiteraard achterwege laten. In plaats daarvan zet u de zaak tussen de tag "<STYLE TYPE="text/css">" ... "</STYLE>. Waar u dat neerzet mag u zelf weten, als het maar tussen "<HEAD>" en "</HEAD>" is.

De totale code zou er hier dan zo uitzien:
<STYLE TYPE="text/css">
H3 {color: darkblue; font-family: Arial; font-size: 1cm; font-style: italic}
P.normaal {font-family: "Times New Roman"; font-size: 12pt}
P.voorbeeld {font-family: courier; font-size: 10pt; margin-left: 3cm; margin-right: 3cm}
</STYLE>

Maar als u van plan bent om meerdere pagina's dezelfde stijl te geven, is het wel zo handig om dat met een externe style sheet te doen. Mocht u voor een bepaalde pagina het aners willen hebben, dan maakt u voor die pagina een interne style sheet waarin dat ene gegeven op die afwijkende manier wordt opgegeven. De opmaakkenmerken die niet afwijkend zijn opgegeven, worden automatisch van dat externe style sheet -dat u dus even goed linkt!- overgenomen.

Voorbeeld inline style sheet

De derde soort (bedoeld voor "even tussendoor") is "inline style sheet" gedoopt. Hiertoe gebruikt u de tag "<DIV STYLE="{...}">" ... "</DIV>" (van "division"). Ik heb de indruk dat er nogal eens verwarring optreedt: de diverse style sheets krijgen ruzie met elkaar over wie er nu voorrang heeft.

En dan?

Vervolgens gaat u de tekst van uw pagina invoeren als gebruikelijk. Elke keer als er een H3-tag voorkomt, zal hij weergegeven worden zoals door u opgegeven. Ten aanzien van alinea's werkt het anders. U hebt twee soorten "bijzondere" alinea's gedefinieerd, maar er is ook nog een derde soort in omloop: de standaard-alinea. Dat is dus de alinea met tekst zoals de browser van de gebruiker hem weergeeft, en in veel gevallen zult u daar heel goed mee uit de voeten kunnen. U weet echter nooit precies hoe die browser is ingesteld, dus u moet zich even afvragen of er redenen zijn om de "omhaal" van een style sheet uit te halen. Ik ga er hier van uit, dat u vindt dat de door u als "normaal" gedefinieerde alinea ook zo behandeld moet worden.

Dat betekent dus dat u moet opgeven dat u die "bijzondere behandeling" wenst!. Dat doet u door de alinea tag als volgt uit te breiden: "<P class="normaal"> ... </P>". Met dat attribuut "class="naam van de class"" verwijst u naar de elders opgegeven kenmerken van die klasse. Let op: u moet hier aan het eind van die alinea de sluittag "</P>" gebruiken, om aan te geven dat hier die aldus behandelde alinea ophoudt. Inderdaad, een uitzondering op de normale situatie waarbij "<P>" gewoon gebruikt wordt om alinea's van elkaar te scheiden.

Dat geeft tevens een bezwaar van CSS aan: je hoeft niet voor elke bijzondere alinea een klont kenmerken op te geven, maar je zit wel steeds "P class="hoedieheet"" te tikken, wat ook extra werk is. Anyway, als u de hier omschreven trucendoos opentrekt, krijgt u het volgende:

Zo zou de H3-kop dan moeten worden
De "normale" alinea wordt dan zo. Eigenlijk niet zoveel verschil met de rest, maar never mind.
En zo zou de als "voorbeeld" omschreven alinea er uit moeten zien. Hij begint op 3 cm uit de kant (plus de paar millimeter marge die je sowieso hebt) en eindigt daar ook.

Bijzondere toepassingen

Eigenlijk kun je best veel met CSS, als je je fantasie even laat werken. Maar het is wel een hoop gepruts. Het meest aansprekende is misschien nog wel dat u er teksten heel precies mee kunt positioneren, met de opdrachten "margin-top", "margin-left" en "margin-right". Om een voorbeeld te geven: U kunt teksten over elkaar heen zetten, en daarmee "schaduwen" suggereren. U kunt tekst over een plaatje heenzetten, en daarmee zowel een visueel aantrekkelijk effect scheppen als schermruimte winnen. Voor voorbeelden: zie de beginpagina van deze site.

Bij die index-pagina zat ik met het probleem dat ik wel een plaatje wilde opnemen, maar zoveel mogelijk inhoud op het eerste scherm wilde krijgen. Ik heb dus de kreet "Van Dalen Homepage" over het plaatje heen gezet, met een negatieve margin-top. De precieze positionering van het plaatje heb ik gedaan door het in een aparte division te zetten.

Misschien is het leerzaam om de lay-out van een pagina een boek eens te bekijken, en zich af te vragen hoe dat met behulp van CSS nagebootst zou kunnen worden. (Niet zozeer een roman, maar studieboeken werken vaak met best wel verschillende typografische grappen, boxjes met voorbeelden, etcereta. Hoe zou u zo'n effect kunnen bewerkstelligen?) Nog een laatste opmerking: u zult hier merken dat u er niet aan ontkomt om uit te gaan van een bepaalde venstergrootte. Maar ik heb elders al gezegd dat het niet ongebruikelijk is om ergens te vermelden dat u van een bepaald venster bent uitgegaan.

Wat u er mee kunt doen:

Een opsomming van de in omloop zijnde tags, zonder aanspraak op volledigheid. De term "xx" betekent uiteraard dat u daar zelf iets moet invullen. Ik realiseer me dat ik hier een hele collectie dingen op uw bord gooi; haalt u er dus vooral ook een ander werkje bij.

Bij font:
{font-size: xxpt c.q. xxcm}
{font-family: "naam font"}
{font-style: italic c.q. normal}
{font-weight: light c.q. medium c.q. bold}

Toelichting:
Bij die font-szie hebt u flink wat keus in maateenheden. Ik heb hier pt (punt) en cm (centimeters) gebruikt, omdat u die waarschijnklijk vertrouwd zijn. Theoretisch zijn ze minder wenselijk, omdat u niet zeker weet hoe ze op een bepaalde maats beeldscherm zullen overkomen. Puristen geven de voorkeur aan "em" of "px".

Bij font-family is het wenselijk om meerdere lettertype achter elkaar op te geven, gescheiden door komma's. In elk geval is het handig om in elk geval het lettertype "serif" als alternatief op te geven voor Times New Roman, en het lettertype "sans-serif" als lettertype voor Arial. Die kluizenaars die geen Times New Roman c.q. Arial op hun pc hebben, krijgen dan in elk geval iets te zien dat er een heel eind op lijkt.

Bij paragrafen:
{line-height: xxpt} (dit gaat over de ruimte tussen regels)
{text-align: left c.q. center c.q. right c.q. justify} (uitlijnen, links, rechts, centreren danwel links en rechts uitvullen)
{text-decoration: none c.q. underline c.q. italic c.q. line-through}
{text-indent: xxpt c.q. xxcm} (inspringen van eerste regel van een alinea)
{margin-top: xxpt c.q. xxcm c.q. xx%} (ruimte met vorige paragraaf)
{margin-left: xxpt c.q. xxcm c.q. xx%}
{margin-right: xxpt c.q. xxcm c.q. xx%}
(width: xx%}
{padding: xxpt c.q. xxpx}

Toelichting:
Wat hiervoor gezegd is over maateenheden is ook hier van toepassing. Met die percentages bij mareges kunt u de zaak zo indelen dat een al te breden marge bij een kleiner browservenster vanzelf wat smaller wordt. U kunt ook de tekstbreedte van een alinea instellen op een percentage. (Wat er gebeurt als alle percentage uitkomen op meer dan 100%, weet ik niet. Misschien loopt dan het hele Internet in de soep.)

De term "padding" behoeft wellicht enige toelichting. We zijn er aangewend dat er altijd een hoeveelheid wit om een tekst heen zit. Is in een boek zo, in een normaal tekstdocument zoals dat uit uw printer komt. Maar stelt u zich voor dat u een alinea een ander achtergrondkleurtje geeft, hoe u dat doet staat hier vlak onder. Dan zult u zien dat de tekst helemaal tot aan de randen van dat gekleurde stuk gaat. Wat eigenlijk ook logisch is. Maar het leest niet lekker. Met "padding" kunt u zo'n "leeg te laten rand" construeren.

Nog een trucje bij "margin": u kunt ook met één opdracht marges opgeven voor alle vier de kanten van een element (meestal dus een paragraaf of een kop), en zelfs verschillende marges. Het werkt in de volgrode boven - rechts - onder - links. Voorbeeld dat leidt tot een marge van een halve centimeter tussen dit element en het vorige, 1 cm ruimte aan de rechterkant, geen extra ruimte tussen dit element en het volgende, en 2 cm aan de linkerkant: {margin: 0.5cm 1cm 0cm 2cm}. NB: daar zitten dus spaties tussen, geen komma's of puntkomma's.

En u kunt ook de attributen van de BODY-tag op deze manier standaardiseren, en aangezien het fenomeen "body" op een soort super-niveau functioneert hebt u daarmee ook het fenomeen "p" meegenomen -om het maar even op een niet-techneuterige manier te zeggen. Dus in de kop "body.normaal" en daaronder BODY class="normaal". (Tip van de heer A.V., en met dank aan u doorgegeven.)

U kunt ook achtergrondkleuren opgeven voor alle verschillende elementen (wat meestal paragrafen en koppen, in diverse smaken, zullen zijn). U hebt elders gezien hoe u een achtergrondkleur kunt opgeven voor de hele body, in gewone HTML, met BGCOLOR="kleur". Dat kan ook in CSS. De syntax is {background: kleur}. NB: dus niet BGCOLOR. Waarom dat afwijkt moet u maar aan de mensen van de WWW Consortium vragen...

U kunt hiermee best wel leuke effecten bereiken. Wat dacht u van overal zwart op wit, maar bij H1-koppen wit op zwart? Dat gaat dan met eerst een regel voor de body: BODY {color: black; background: white}. En dan een regel voor de H1-kop: H1 {color: white; background: black}. Met enige terughoudendheid te gebruiken wegens anders al te kakelbont worden.

Bij links kunt u de onderstreping "uitzetten" met
A:link {text-decoration: none}
A:visited {text-decoration: none}
En het wordt heel grappig als u de achtergrond van dat stukje tekst van kleur laat veranderen, als de muis er overheen komt, met:
A:hover {background:pink}

NB 1: let er even op dat u hier niet A-punt-link typt, maar A-dubbelepunt-link. (C.q. -visited en -hover.) Er zit een technisch verhaal achter dat ik u zal besparen, maar het is gewoon zo dat als u A-punt-link tikt, het beoogde effect niet bereikt wordt. En dan zit u zich de blubber te zoeken naar de oorzaak. NB 2: dat "A:hover" moet als laatste van die drie opdrachten komen, anders werkt het niet goed. (Dank aan de Desiger-afdeling van Tucows voor deze tip!)

Een andere kleur mag natuurlijk ook... Overigens kun je ook heel goed verdedigen dat, nu het eenmaal gebruikelijk is om links te onderstrepen, je de bezoeker een dienst bewijst door die conventie te volgen. Ik bedoel, verkeersborden zijn toch ook internationaal redelijk gestandaardiseerd. Maar kijkt u zelf maar. Let er wel op dat u de onderstreping uitzet zowel bij de A:link als de A:visited-situatie.

Problemen met lijsten en tabellen

Ik heb gemerkt dat lijsten een probleem vormen bij het werken met stylesheets. We zouden verwachten dat we, als we binnen een paragraaf, een lijst opnemen, de vormgeving van die lijst conform de stijl van die paragraaf zou zijn. Niet dus. Die lijst heeft de default-opmaak, zo zult u merken. Al uw wensen ten aanzien van lettertype, marge etcetera, worden genegeerd. Bij tabellen is het hetzelfde gedonder.

De oplossing bij lijsten: geef in de stylesheet aparte opmaakkenmerken op voor de OL-, UL- of LI-tag. Dus, OL {margin-left: 1cm; font-family: arial; font-size: 12pt}. En daarvan zijn dan ook weer klassen aan te maken voor verschillende soorten lijsten, OL.type_1 of zo, en dan dus te gebruiken met OL class="type_1". (Dank aan de heer F.H., die me een elegantere oplossing aan de hand deed als vervanger van de hier tot dusver gepresenteerde methode.)

De oplossing bij tabellen is, als je hem eenmaal bedacht hebt, eigenlijk vrij simpel. In de style sheet geeft u de gewenste opmaakkenmerken voor de cellen van die tabel ook op. Stel, u wilt bereiken dat de inhoud van elke cel wordt weergegeven in 10-punts arial. Dat doet u door toe te voegen "TD {font-size: 10pt; font-family: arial}". Desgewenst kunt u ook diverse klassen aanmaken (bijvoorbeeld TD.cursief {font-style: italic}). Maar dan moet u wel de tabel zelf aangeven dat u die klasse wilt gebruiken, met <TD class="cursief">, dus dat is dan wel extra werk.

Ik snap dus niet waarom dit zo moet; ik zou verwacht hebben dat die instructie die u binnen de DIV-tag hebt opgegeven het gehele tussenliggende gebied bestrijkt, maar kennelijk denkt HTML daar anders over. Afijn, zo lukt het ook.

En nog een probleempje...

Ik heb gemerkt dat CSS erg nauw luistert en dat typefouten onmiddellijk afgestraft worden. Stel, u hebt aan een tag 4 opmaakkenmerken meegegeven, en in eentje zit een typefout, dan pakt -ie de andere 3 ook niet. Mijn eigen aanpak is dat ik ze stuk voor stuk opgeef, steeds tussendoor save, en het resultaat steeds bekijk.

Borders

Ook voor gevorderden, maar misschien toch wel leuk, is de mogelijkheid om randjes rond een stuk tekst te maken. U zoudt dit kunnen gebruiken om een tekst extra nadruk te geven. ("Let op! De vergadering van de Technische Commissie is vervroegd van 20.0 naar 19.30!") Het is nogal een gedoe, maar vooruit. En ik moet zeggen dat ik het soms niet aan de praat krijg.

U maakt een DIV-omschrijving met daarin tenminste de volgende specificaties: wat voor soort border het moet zijn (border.style: groove, solid, double, inset of outset); hoe dik de border moet zijn (border-width: thin, medium of thick); welke kleur hij moet hebben (border-color: kleur).

Verder kunt u opgeven welke kleur het omlijnde gebied moet hebben (background-color: pink), en zijn alle grappen ten aanzien van de opmaak van de tekst mogelijk.

Ik vind zelf dat de leukste effecten bereikt worden met "groove", en dan een niet al te donkere kleur. Het effect is zo'n verdiept randje, alsof u met een beitel het beeldscherm bewerkt hebt. De style sheet zou er dan zo uit kunnen zien:

DIV.randje {border-style: groove; border-width: medium; border-color: grey; background-color: lightblue}

En dat roept u op de gewenste plaats aan met <DIV CLASS="randje">...volgt tekst...</DIV>.

Standaard strekt die box zich dan over de gehele breedte van het beeldscherm uit. Als u dat ander wilt hebben, kunt u dat met WIDTH="zoveel pixels of procent" opgeven. In veel gevallen zult u tevens de tekst binnen de border willen centreren (lijkt mij zo): dat doet u met "text-align: center".

Experimenteert u hier eens wat mee, wellicht vindt u het een nuttige toevoeging aan uw site.

Is CSS nou de moeite waard?

Ik neem aan dat het u inmiddels duizelt. Vraag dus: is dit sop de kool waard? Op basis van m'n eigen ervaringen zeg ik: ja, ik vind van wel. Mijn ervaring is dat je, naarmate je verder bezig bent, toch wat mee aandacht gaat geven aan de indeling van je pagina's, kleurgebruik, wat verschillende letertypen en -groottes, etcetera. Het werken met "vrijwel platte tekst" bevalt steeds minder. En dan is het best een hoop werk om elke keer die tags en attributen apart op te geven, en dan werkt een style sheet toch wel makkelijk. Wat in elk geval z'n vruchten afwerpt, is het in één keer kunnen doorveranderen van de opmaakkenmerken van een hele site.

Opdracht

Ik geef u een wat algemene opdracht: neemt u een stuk tekst (of verzint u er zelf een) en maak daar een smakelijke HTML-pagina van met Cascading Style Sheets. U mag zelf weten of u de style sheet apart zet of op de pagina (in de uitwerking heb ik de style sheet in de pagina gezet). Maakt u gebruik van de volgende opmaak-grappen: H1-kop 0.7cm, arial, 1cm inspringend, groen; H2-kop 0.4cm, arial, 2cm inspringend, rood; paragraaf klasse "samenvatting": 12pt, Times New Roman, 3cm inspringend, cursief; paragraaf klasse "standaard": 10pt, Times New Roman, 3cm inspringend. Mijn uitwerking vindt u hier.

U kunt nu -ook weer voor gevorderden!- naar JavaScript.


1 Volledigheidshalve: u houdt toch een zekere kans dat de browser van uw bezoeker het toch weer net even anders weergeeft dan u hem hebt opgedragen. Dat soort problemen blijf je toch houden bij HTML.