Stylesheets: CSS

door Aart Jan Bergshoeff – update 2016

Tip: doorzoek de pagina met Control-F (Command-F op de Mac). 
Kik hier voor nieuwe advanced tips.   

CSS - de visuele opmaak van HTML

CSS staat voor Cascading Style Sheets. Het wordt gebruikt om HTML visueel vorm te geven. De opmaak staat dan in een los bestand (bijvoorbeeld opmaak.css), gescheiden van de content. Een van de voordelen hiervan is dat de vormgeving van de gehele site centraal aanpasbaar is. Een ander voordeel is dat je vormgeving media-afhankelijk kan zijn: dezelfde site kan er op mobiel, tablet, desktop of geprint telkens anders uitzien.

Kijk op de w3schools.com/css/demo. Zet de css uit, en bekijk de pagina met verschillende stylesheets. Bekijk ook de code van de css, er zitten knoppen bij om dat te doen. Bekijk daarna www.csszengarden.com. Doe daar hetzelfde. Versmal ook je venster om te kijken of het responsive is. CSS kan je in Chrome uitzetten met de gratis plugin Pendule. In Safari zet je in de voorkeuren de Developer tools aan, dan kun je via het menu ook de CSS uitzetten.

Kijk voor recente tips op aartjan.nl/css

Een voorbeeld

Alle paragrafen willen we bijvoorbeeld in lettertype Verdana, interlinie 1.6, grijs en 14 pixels groot, zonder witregel vooraf. Dit is dan de css:

p {
   font-family:Verdana; 
   line-height:1.6;
   color:grey;
   font-size:14px;
   margin-top:0; 
   } 

Let op de syntax: het element vooraf, daaarachter alles tussen accolades, elke definitie heeft een dubbele punt voor de waarde, en eindigt met een puntkomma.

Bewaar dit als stijl.css en plaats een link naar deze CSS in de HTML van al je pagina's:

<link href="stijl.css" rel="stylesheet" />

Als je nu iets verandert aan de stijl, bijvoorbeeld de kleur, veranderen alle paragrafen van de hele site. Op dezelfde manier kun je elementen zoals h1, img, a en ul styleren. Ook alle andere onderdelen van de site worden zo vormgegeven, zoals de indeling in kolommen en de plaats en vormgeving van het menu.

Verschillende stylesheets op dezelfde site

Door een ander stylesheet te kiezen kun je dezelfde site visueel totaal anders presenteren. Bijvoorbeeld als de site op een mobiel, tablet, of juist op grote schermen wordt getoond. Of een knop voor grotere letters. Of als de website geprint wordt. Of een versie voor een bepaalde browser.
Die versies gebruiken dus allemaal dezelfde content. Ze tonen allemaal dezelfde HTML, alleen vormgegeven met een andere CSS.

De syntax

Nog een voorbeeld van css-syntax. Voor alle koppen en de list-items in een menu wordt de vormgeving: 24 pixels groot, in hoofdletters, met 3px extra spatie tussen de letters, kleur: rood, en met een 4 pixels dikke rode stippellijn eronder.

De komma betekent hier EN. En een spatie betekent IN.
#menu li betekent: een li maar alleen als-ie in een #menu staat.

Noot: die inspringers (tabs) en returns zijn niet nodig, maar die staan er om het overzichtelijk en leesbaar voor jezelf te maken.

h1, h2, h3, h4, #menu li {
	font-size: 24px;
	text-transform: uppercase;
	letter-spacing: 3px;
	color: red;
	border-bottom: 4px dotted red; 
   }  

h1, h2, h3, h4 en #menu li zijn de selectors, de properties staan erachter tussen accolades { }.
De properties zijn van elkaar gescheiden met een punt-komma ;
Je kunt selectors groeperen door er een komma tussen te zetten: h1, h2 betekent dus h1 EN h2.

Mogelijke selectors

De selector kan elk HTML-element zijn, zoals p, h1, img enzovoort.
De selector kan ook een custom class zijn, je mag de naam dan zelf kiezen. Om aan te geven dat het een class is zet je er een punt voor:

.rood {color:red}
.groot {font-size:300%}

In de HTML moet je dan wel aangeven waar deze custom class gebruikt gaat worden. Dat kan overal, in welk element dan ook, hier in een <p>:

<p class="rood">Een rode paragraaf</p>

Als er geen element staat, maak je een een nieuwe <div> of een <span>:

<p>Er komen nu twee <span class="rood">rode woorden</span></p>

Je kan meerdere classes tegelijk doen, gescheiden door een spatie:

<p>Er komen nu twee <span class="rood groot">rode grote woorden</span></p>

De selector kan ook een id zijn. Verder precies hetzelfde als een classs, alleen een id mag maar 1x voorkomen per pagina. In de css staat er een hekje voor:

#menu {width: 100px}

En in de HTML geef je dat zo aan, bijvoorbeeld bij een div:

<div id="menu">

Een class of id moet minstens 2 karakters lang zijn en mag niet beginnen met een cijfer.

De selector kan een pseudo-class zijn, bijvoorbeeld om bij een link a (of een img etc) aan te geven wat er gebeurt als je er met je muis overheen hangt a:hover (of img:hover)

a {color:red; text-decoration:none;}
a:hover {color:blue; text-decoration:underline}

In dit voorbeeld zijn de links rood zonder onderstreping, maar als je er met je muis over "hovert" zijn ze blauw en underlined.

Een selector kan ook een combinatie zijn. Bekijk de css selectors voor een overzicht van mogelijkheden tot combineren, waarvan dit de belangrijkste drie zijn:

div,p	Deze selecteert alle <div>'s EN alle <p>'s 
div p	Dit selecteert alle <p>'s  binnen een <div> 
div > p  Dit selecteert de <p> die direct volgt na een <div> 

Net als commentaar in HTML <!--zo ging dat--> kan je in de CSS ook commentaar plaatsen:

/* Alles tussen deze tekens is commentaar */

Kleur

Je kan kleur definieren met woorden zoals black, white, red, blue, yellow. Google op "css color codes". Voor specifieke kleuren gebruik je hexadecimale waardes: elk kanaal (Red, Green, Blue) krijgt dan een waarde van 0 tot FF (FF is 256). Na 9 komt A; F is 16.
00 00 00 = zwart (Rood=0 Groen=0 Blauw=0)
FF FF FF = wit (Rood=256 Groen=256 Blauw=256)
FF 00 00 = rood (Rood=256 Groen=0 Blauw=0)
00 kan je afkorten tot 0, 33 tot 3, ff to f, etcetera.

In Photoshop zie je ook altijd de hexadecimela waarde van een kleur staan. Je kan ook een online color picker gebruiken.

Bij een getal moet je er een hekje # voor zetten: Rood is #F00, wit is #FFF, zwart is #000, bij een naam zoals black moet er geen hekje voor.

Je kan kleur ook met een transparantie ofwel met een alfa-kanaal omschrijven. Daarbij wordt de gewone waarde van 0 tot 255 gebruikt, per kleur, in dezelfde RGB-volgorde, gescheiden met komma's, en de vierde waarde is de transparantie. Deze alpha-waarde is een getal tussen 0 en 1. Met een punt ipv een komma (dus 0.3 en niet 0,3) want computercode is altijd US English. Zo'n transparante kleur ziet er bij dropshadows veel beter uit. Google op rgba color picker.
50% zwart is bijvoorbeeld:

rgba(0,0,0,0.5)

Verlooptinten (gradients)

Verlooptinten: bekijk deze link voor alle opties en uitleg. Een voorbeeld van een verticale lineaire gradient, van rood naar blauw:

background: linear-gradient(red, blue);

Of voeg een richting toe, voor een horizontaal verloop:

background: linear-gradient(90deg, red, blue);

Je kan CSS op drie plekken aangeven

  1. Extern, in een apart css-bestand, voor alle pagina's van de website tegelijk. Er staat in elke pagina een link naar de css in de <head>:
    <link href=stijl.css rel=stylesheet />
  2. Inline, direct in de HTML-code, toegevoegd aan een tag, met het attribuut style. De opmaak geldt dan alleen voor dat element, dus alleen op die plek:
    <p style="margin-top:-10px">
  3. In de <head>, met het element <style>, nu geldt de opmaak alleen voor die hele pagina:
<style> p {margin-top:-10px} </style>

Wat is Cascading?

Cascading betekent dat wat de browser als laatste inleest de vorige instructies overruled. Hij leest van boven naar beneden, en alleen de laatste instructie telt. Het is een belangijk en handig principe. Je kan koppen h1,h2,h3,h4 in 1x uitgebreid vormgeven en dan daarna voor de h1 aangeven dat alleen maar de font-size groter is. Of je geeft onderaan aan dat een bepaalde kolom alleen op kleine schermen minder breed is, of dat de knoppen in het menu op een mobiel er totaal anders uitzien. Bekijk deze pagina in een smaller venster, dan zie je o.a. het menu veranderen. Bekijk de css van deze pagina. Daar staan onderaan opmaakinstructies die eerdere instructies overrulen.

CSS positioning, div en span

CSS kun je gebruiken om de pagina in te delen in blokken, ofwel divisies, met <div></div>.
Voeg daar CSS aan toe met id of class:
<div id="menu"> Een id komt maar 1x per pagina voor.
<div class="rood"> Een class kan vaker voorkomen.
Gebruik een <span> in plaats van <div> als het vorm te geven stukje inline moet zijn, bijvoorbeeld een woordje dat rood moet zijn:

Nu komt er een <span class="rood">rood</span> woord.

Je kan blokken positioneren met position:absolute. Je breekt dan de positie los van de relatieve plek. Een voorbeeld: Relatief staat het menu onderaan in de code, maar met position:absloute kun je het menu neerzetten waar je maar wil. Je kan die positie dan zo aangeven:

#menu {  position:absolute;
	top:0;
	left:0;
	width:200px;	}

Er is ook position:relative. Die laat de div weer gewoon op z'n plek in het document staan. Met top en left kun je de div dan verplaatsen ten opzichte van zijn normale plek. Negatieve waardes kunnen ook: in dit voorbeeld wordt het menu iets omhoog en iets naar links verplaatst.

#menu {  position:relative; 	
		top:-100px; 	
		left:-100px;  }

Het op deze relatieve manier verplaatsen van elementen kan ook met margin, hier met 4 getallen: top, right, bottom, left (de volgorde is kloksgewijs):

#menu {  margin: -100px 0 0 -100px 	 }

Als er maar 1 getal staat, margin:0, geldt dat voor alle vier de margins. Staan er 2 getallen margin: 0 auto dan is het eerste getal voor top en bottom, het tweede getal voor left en right. Met margin: 0 auto wordt het element horizontaal gecentreerd, want de marges links en rechts worden dan automatisch berekend en gedeeld door 2.

Met position:fixed blijft het element permanent in beeld, ook als er gescrolld wordt. Zie als voorbeeld de footer onderaan deze pagina.

#foot {	width:100%;
	position:fixed;
	bottom:0; left:0;  }

Margin en padding

Hierboven stonden voorbeelden van margin. Padding is bijna hetzelfde, alleen dan de ruimte rondom aan de binnenkant. Alleen de inhoud wordt zo opgeschoven, het element zelf niet. In dit voorbeeld schuift de inhoud overal 20px op, behalve bovenaan, daar schuift het 5px naar boven:

#menu {padding: -5px 20px 20px 20px}

Borders

Ook bij borders kun je 1, 2 of 4 getallen gebruiken. Een border heeft bovendien 3 eigenschappen: width, style (solid, dotted of ridge) en color. Je kan dat allemaal apart vermelden, maar het kan ook in 1x, hier bijvoorbeeld rondom alle plaatjes:

img  {border: 1px solid red}

Daar staan dus 4x3=12 eigenschappen in 1 kort regeltje. In het volgende voorbeeld heeft het plaatje ook nog wat extra padding:

img  {
	border: 1px solid red;
	padding: 10px;
	background:white;
}

Afgeronde hoeken zijn ook simpel met border-radius. Je kan zelfs zo een cirkel maken:

border-radius:25px;
height:50px; width:50px;

Een border kan ook alleen aan de onderkant van een element:

h1 {border-bottom: 1px dotted yellow }

Display: block of inline

<div>, <p>, <h1>, <ul> en <li> zijn voorbeelden van block-elementen: ze vullen de volle breedte van het venster: een volgend element komt eronder, en niet ernaast.
<span>, <i> en <b> zijn voorbeelden van inline elementen: die kunnen naast elkaar staan, ze kunnen een stukje van een regel afbakenen (omspannen). Dit standaard gedrag kun je in de css aanpassen met display:

#menu li {display:inline} 

Dit voorbeeld betekent dat list-items IN een menu niet onder elkaar, maar naast elkaar staan; zo kan je een horizontaal menu maken. Een andere veel gebruikte is #menu a {display:block} om links in het menu tot een block te maken, zodat je op de hele knop kan klikken, en niet alleen maar precies op het woordje hoeft te klikken, en zodat de hover ook veel beter werkt.

Kolommen met float

Met float kun je kolommen maken. Block-elementen kunnen normaliter niet naast elkaar staan, maar met float wel. Zo kan je ook een plaatje naast een blok tekst laten "drijven". Je kan float ook gebruiken om knoppen die display:block zijn naast elkaar te zetten, om zo bijvoorbeeld een horizontaal menu te maken. Float kun je weer opheffen in de css van het element dat erna komt, met clear:both. Dat kan ook inline in de HTML, bijvoorbeeld zo: <br style="clear:both">.

Een voorbeeld van 3 kolommen, in de HTML:

<div class="kol3"> Inhoud van Kolom 1 
</div>
<div class="kol3"> Inhoud van Kolom 2 
</div>
<div class="kol3"> Inhoud van Kolom 3 
</div>

En in de CSS:

.kol3 {float:left; width:33%}

Dit kun je responsive maken, zodat op kleine schermen de kolommen onder elkaar komen:

@media only screen and (max-width: 680px) 
   {
.kol3 {float:none; width:100%}    
}

Een tekstblok naast een plaatje:

.leftimg {float:left; margin 0px 20px 5px 0px}

En in de HTML staat dan bij het plaatje:

<img class="leftimg" src="bla.jpg">   
<p>Deze lange paragraaf komt geheel naast het plaatje ... </p>    
<br style="clear:both">
<p>Dit komt eronder en niet meer ernaast...

Horizontale knoppen in een menu:

#menu a {display:block; float:left;}

Kolommen met columns

In moderne browsers kan je ook kolommen met CSS3 columns maken. Je zet al je kolommen (divs) tesamen in een container-div. Met colums geef je het aantal kolommen aan, en eventueel de minimale breedte voor de kolommen, in pixels. Als het venster kleiner wordt komen de kolommen onder elkaar. Het is meteen al responsive, zonder extra css.

.kol3 {
	columns: 3 200px;   	/* 3 kolommen van minstens 200px breed */
	column-gap: 2em;		/* optioneel, default is 1em */
   }

De ruimte tussen de kolommen is die column-gap, maar die kun je ook weglaten. In de HTML staat er simpelweg dit:

<div class="kol3">
	<div> Inhoud van Kolom 1 </div>
	<div> Inhoud van Kolom 2 </div>
	<div> Inhoud van Kolom 3 </div>
</div>

Helaas heeft Chrome nog de vendor prefix nodig, zie info hieronder.

Kolommen met flexbox

Een andere manier om moderne responsive kolommen met CSS3 te maken is Flexbox. Hier een goed voorbeeld daarvan. Resize de browser (of tik Cmd+) om het responsive gedeelte te zien.

Vendor prefix

Er zijn nog steeds verschillen tussen browsers, vooral met nieuwe CSS3. In die gevallen kun je er per browser een vendor prefix voorzetten. Bijvoorbeeld als je iets wil roteren:

div {
 	-ms-transform:rotate(7deg); 		/* IE */
 	-webkit-transform:rotate(7deg); 	/* Chrome and Safari */	
	 -moz-transform:rotate(7deg); 	   /* Firefox */
	transform:rotate(7deg);			  /* CSS standaard */
   }

CSS Box model

De width van een element is exclusief borders en padding. Dat maakt het berekenen van de breedte lastig en soms onmogelijk: je kan % en pixels bijvoorbeeld niet bij elkaar optellen. Als je box-sizing toevoegt, dan is de width weer INCLUSIEF borders en padding:

box-sizing:border-box;

Shorthand (steno)

Typografie, margin, padding, background en borders kun je compact in shorthand omschrijven:

font: bold italic 28px/1.5 Arial, "Lucida Console";
background: url(bg.jpg) no-repeat center center;
   
margin: 0, 10%, 0, 10px		/* Volgorde: Top Right Bottom Left */ 
padding: 0, 10%			/* Top+Bottom, Right+Left gegroepeerd */
border-top: 2px solid red	/* dikte, stijl, kleur */
 

Geavanceerde trucs worden vaak in de css uitgelegd met comments, hier bijvoorbeeld:

h1{ visibility: hidden} 	/* heading1 wordt vervangen door een plaatje*/
#top {			        /* er staat een div met id=top om de h1 */
background-image: url(../ima/top.jpg)  /* h1 wordt door dit plaatje vervangen*/

Text-shadow of glow, box-shadow

Dat is allemaal kipsimpel. Probeer het zelf maar uit. Een glow bijvoorbeeld: gebruik dan een lichte tekst op een donkere achtergrond en zet de eerste 2 waarden (horizontale en verticale afstand) op 0. De derde waarde is de zachtheid van de schaduw, de 4e waarde is de kleur van de glow:

text-shadow: 0px 0px 5px #fff;	/* dit is een glow */

Als het geen text is maar een box gebruik je box-shadow. Werkt verder precies hetzelfde. Als je geen glow maar een shadow wil, dan is een transparante kleur mooier, bijvoorbeeld rgba(0,0,0,0.5). Zie het stukje over kleur, of Google naar rgba color picker.

box-shadow: 10px 10px 10px rgba(0,0,0,0.5);

Background images

Achtergrondplaatjes zijn erg handig in css. In het hoofdstuk Beeld meer daarover.

Lagen over elkaar, z-index

Je kan lagen (div's of andere elementen) in de diepte op elkaar stapelen, over de Z-as, met z-index. Hoe hoger het getal, hoe hoger de laag: z-index:1 valt onder z-index:2. En z-index:-1 komt helemaal ONDERop. Maar het werkt alleen als beide elementen OOK een position hebben, bijvoorbeeld position:absolute, position:relative of position:fixed.

Lettertypes

Je kan normaliter alleen letterypes gebruiken die bij je bezoekers op hun computer geïnstalleerd zijn. Dat zijn er niet veel; ze heten websafe fonts. Als je andere letterypes wil gebruiken dan kan dat bijvoorbeeld via Google fonts. Dat systeem is heel goed en ook eenvoudig als je de handleiding bekijkt die er bijstaat.

Afbreken en <pre>

Bij <pre> kunnen de regels niet meer afbreken. Dat is lastig op kleine schermen. Gelukkig is dat op te lossen met css, als je dit toevoegt aan de vormgeving van pre:

white-space: -moz-pre-wrap;  /* Mozilla */
white-space: -pre-wrap;      /* Opera 4-6 */
white-space: -o-pre-wrap;    /* Opera 7 */
white-space: pre-wrap;       /* CSS3 */
  word-wrap: break-word;       /* Internet Explorer 5.5+ */

Meer css-tips

Kijk voor geavanceerde tips op aartjan.nl/css

Extra bonus: css-humor