css vragen
Ik heb 2 CSS vraagjes. Wie weet een antwoord op een van deze vragen?
VRAAG 1:
Stel we hebben op onze html pagina een paragraaf <p> en in die paragraaf komen <strong>'s voor die je op een bepaalde manier wil stylen. We gebruiken <strong> niet in andere tags binnen de paragraaf, maar uitsluitend op het "eerste" niveau.
Wat is nu de juiste css code? Beide voorbeelden hieronde zullen werken, maar ik vraag me af of het een sneller is dan het ander.
Optie 1:
p strong { color: red; }
Optie 2:
p > strong { color: red; }
Optie 1 maakt ALLE <strong>'s rood en optie 2 alleen de child elementen van <p>. Nu vraag ik me af of in theorie de ene optie sneller is dan de andere. Is optie 2 bijvoorbeeld sneller, omdat alleen gekeken wordt naar child elementen, of is het wellicht daardoor trager omdat er een extra controle plaatsvindt?
VRAAG 2:
Stel we hebben 2 <div>'s met daarin een aantal sub-div's. (Symantisch klopt het niet, maar daar moet je even doorheen prikken. Het is puur een voorbeeld).
Optie 1:
Code (php)
1
2
3
4
5
6
7
8
2
3
4
5
6
7
8
<div id="header">
<div class="menu">square</div>
<div class="special-text">square</div>
</div>
<div id="footer">
<div class="menu">square</div>
<div class="special-text">square</div>
</div>
<div class="menu">square</div>
<div class="special-text">square</div>
</div>
<div id="footer">
<div class="menu">square</div>
<div class="special-text">square</div>
</div>
Nu wil ik de special-text van de header rood maken:
#header .special-text { color: red; }
Bovenstaande zou een goede optie kunnen zijn. Echter, we zouden het ook als volgt kunnen doen.
Optie 2:
Code (php)
1
2
3
4
5
6
7
8
2
3
4
5
6
7
8
<div id="header">
<div id="header-menu">square</div>
<div id="header-special-text">square</div>
</div>
<div id="footer">
<div id="footer-menu">square</div>
<div id="footer-special-text">square</div>
</div>
<div id="header-menu">square</div>
<div id="header-special-text">square</div>
</div>
<div id="footer">
<div id="footer-menu">square</div>
<div id="footer-special-text">square</div>
</div>
Nu wil ik de special-text van de header weer rood maken:
#header-special-text { color: red; }
Welke van deze 2 manieren is de beste? Bij manier 1 maak je gebruik van classes met een korte naam die je aanspreekt via hun parent element. Bij optie 2 spreek je de elementen rechtstreeks aan via een id, maar moet je wel alles "prefixen" met "header-" of "footer-". Wat heeft jullie voorkeur?
Deze manier p strong { color: red; }
maakt echt niet alle strongs rood, alleen alle strongs die in de <p> tags staan zullen rood worden.
Als je een komma plaats worden wel alle strongs over de hele pagina rood, dus p, strong { color: red; }
Maar dan worden ook alle <p> tags rood.
Bij vraag 2:
Hier moet je doen wat je uitkomt. Als je alleen tekst wilt kleuren, en er dus geeen padding of rand omheen wil zetten, zou ik geen <div> gebruiken maar een <span>
Verder zou ik kijken of ik dit stukje HTML vaker wil gebruiken. Als je het vaker wil zetten op 1 pagina, maak er dan een CSS class van, anders gewoon een id.
En hou het vooral simpel. Als je alles in CSS gaat afhangen van andere id's en classes dan kan het soms mis gaan als je 1 id verandert, omdat alles daar vanaf hangt.
Doe dus de class van het element zelf gebruiken en niet de class van het element waar het in staat, en vervolgens een bepaalde tag of id daar weer uit zoeken.
Gewijzigd op 25/03/2013 15:19:49 door Mark Hogeveen
Wat betreft vraag 2. Ik had al gezegd dat dit een voorbeeld was. Het gaat dus niet erom of het een div, een span of wat dan ook is. Maar stel nu in die header div komt een class meerdere keren voor, zou jij dan dit doen:
Code (php)
1
2
3
4
5
6
7
2
3
4
5
6
7
<div id="header">
<div class="header-special">bla die bla</div>
<div class="header-special">nog meer bla die bla bla</div>
</div>
// css
.header-special { color: red; }
<div class="header-special">bla die bla</div>
<div class="header-special">nog meer bla die bla bla</div>
</div>
// css
.header-special { color: red; }
in plaats van dit?
Code (php)
1
2
3
4
5
6
7
2
3
4
5
6
7
<div id="header">
<div class="special">bla die bla</div>
<div class="special">nog meer bla die bla bla</div>
</div>
// css
#header > .special { color: red; }
<div class="special">bla die bla</div>
<div class="special">nog meer bla die bla bla</div>
</div>
// css
#header > .special { color: red; }
Gewijzigd op 25/03/2013 16:32:09 door Ozzie PHP
Ozzie je bent volgens mij echt een snelheidsfreak!
Volgens mij maakt het voor de snelheid niet veel uit. Het enige wat misschien uit kan maken is dat je zoveel regeltjes in je css hebt dat alles ingelezen moet worden. maar in principe is css geen programmeertaal waardoor je niets hoeft te berekenen. alles is als het ware static rules dus een
p wordt rood en klaar.
Bijvoorbeeld... stel we zeggen dit:
#header > .special { color: red; }
in plaats van dit:
.header-special { color: red; }
Dan zou het zomaar kunnen zijn dat de 1e variant sneller is, omdat ie dan alleen binnen het element met id "header" kijkt, en niet in de rest van het document. Snap je?
Om het je wat duidelijker te maken geef ik je wat achtergrond informatie hoe browsers werken:
Het maken van een DOM tree/styles struct
Het browser leest bij het binnenkomen de HTML code en genereert een DOM tree daaruit:
Code (php)
1
2
3
4
5
6
7
8
9
10
11
12
13
2
3
4
5
6
7
8
9
10
11
12
13
<div id="header">
<div class="special">bla die bla</div>
<div class="special">nog meer bla die bla bla</div>
</div>
=====>
DIV id="header"
DIV class="special"
#text: bla die bla
DIV class="special"
#text: nog meer bla die bla bla
<div class="special">bla die bla</div>
<div class="special">nog meer bla die bla bla</div>
</div>
=====>
DIV id="header"
DIV class="special"
#text: bla die bla
DIV class="special"
#text: nog meer bla die bla bla
De styles worden ook helemaal gelezen en daarvan wordt een style struct gemaakt.
Het renderen
Dan komt de 2e stap in de browser, hierbij gaat hij de DOM tree en de Styles struct samenvoegen. Elke DOM element krijgt dus zijn styles.
Dit werkt heel simpel door gewoon de elementen af te gaan en te kijken of daarvoor iets in de styles struct staat:
1) DIV -> Staat er iets over een div style in de struct? Nee => doorgaan
1.2) #header -> Staat er iets over een #header style in de struct? Nee => doorgaan
2) DIV -> Staat er iets over een div style in de struct? Nee => doorgaan
2.1) .special -> Staat er iets over een .special style in de struct? Ja, maar wel met #header als parent => Kijken of header ook echt de parent is:
2.1.1) #header => ja, header is de parent => styles meegeven en doorgaan
3) DIV -> Staat er iets over een div style in de struct? Nee => doorgaan
3.1) .special -> Staat er iets over een .special style in de struct? Ja, maar wel met #header als parent => Kijken of header ook echt de parent is:
3.1.1) #header => ja, header is de parent => styles meegeven en doorgaan
Je ziet, de styles worden van rechts naar links gelezen en niet van links naar rechts. Nog een ander fabel over deze selectoren is dat CSS opzoek gaat naar elementen die een selector hebben. Zo werkt JavaScript, zo werkt het browser renderen niet. Een browser gaat elk element af en kijkt of hij een selector kan vinden.
Offtopic:
Om het verhaal af te maken:
Painten
De HTML elementen en de gekoppelde CSS styles worden 1 voor 1 'gepaint' en je krijgt je resultaat
Uit het verhaal hierboven kun je wel afleiden dat het gebruik van een generieke selector dus sneller is dan het gebruik van dit soort parent/child selectors. (nog een plus puntje voor BEM CSS!)
Om de eerste vraag te beantwoorden: Uit het verhaal hierboven kan je concluderen dat het gebruik van > sneller is, dat is het echter totaal niet. > en * zijn de traagste selectors en moeten ten alle tijden worden vermeden.
Wat ik alleen wel raar vind... bij 1) 2) en 3) wordt telkens gekeken of er iets over een div style in de style struct staat. Echter, is de browser niet zo slim dat ie dat de 1e keer onthoudt? Bij stap 1) weet ie al dat er geen div style is. Waarom dan bij stap 2) en 3) nogmaals controleren?
Die * moet je dus nooit gebruiken? Maar hoe kun je dan het beste de margin en padding van alle elementen resetten? Ik doe dat vaak zo:
Quote:
Echter, is de browser niet zo slim dat ie dat de 1e keer onthoudt? Bij stap 1) weet ie al dat er geen div style is. Waarom dan bij stap 2) en 3) nogmaals controleren?
Dat zou best al kunnen gebeuren. Merk op dat mijn verhaaltje natuurlijk zeer globaal is en slechts om je even idee te geven over wat er nu gebeurd en waarom een browser de selectors van rechts naar links leest.
Quote:
Die * moet je dus nooit gebruiken? Maar hoe kun je dan het beste de margin en padding van alle elementen resetten? Ik doe dat vaak zo:
Goed, dat kan wel. Maar in een selector niet. Als je gebruikt wat jij nu gebruikt dan heeft het browser door dat het op alle elementen wordt toegevoegd en zal hij dus al deze elementen al de style geven.
Als je echter selectors als #header * gebruikt zal het browser dus bij alle elementen denken: Hé, de * matched dit element, eens kijken of hij in de #header zit. En dan is hij dus bij elk elementen helemaal aan het terugrekenen naar het root elementen (<html>) en je kan wel begrijpen dat dat erg traag is.
Wouter J op 25/03/2013 17:13:47:
Als je echter selectors als #header * gebruikt zal het browser dus bij alle elementen denken: Hé, de * matched dit element, eens kijken of hij in de #header zit.
Serieus? Da's raar!! Dus hij kijkt niet eerst of het element überhaupt in header staat???
Toevoeging op 25/03/2013 17:44:08:
Wouter J op 25/03/2013 16:55:45:
Kun je dit nog uitleggen? Ik geloof dat ik het niet helemaal begrijp nog.Je ziet, de styles worden van rechts naar links gelezen en niet van links naar rechts.
Dus bijvoorbeeld bij deze code doet hij het volgende:
Hij vindt de class rode-tekst en kijkt of deze in het element zit met het id in-span. (Als dat niet zo is, houdt het dus op omdat er niks mee hoeft worden gedaan.) Daarna kijkt hij of dit element weer in een <span> element staat en dan kijkt hij weer of dat <span> element in een <p> element staat.
Gewijzigd op 25/03/2013 18:13:15 door Mark Hogeveen
Quote:
Serieus? Da's raar!! Dus hij kijkt niet eerst of het element überhaupt in header staat???
Nee, want hij leest van links naar rechts. Hij kijkt dus eerst of het element de * matched, en dat doet ie, daarna gaat hij 1 selector naar links en dan moet hij de hele DOM tree gaan uitpluizen.
Wouter J op 25/03/2013 16:55:45:
Je ziet, de styles worden van rechts naar links gelezen en niet van links naar rechts.
Wouter J op 25/03/2013 19:00:21:
Nee, want hij leest van links naar rechts.
Zeg, zit je me nu voor het lapje te houden :D
Hij leest dus van rechts naar links... maar als ik het verhaal van Wouter begrijp doet ie het per element uit de dom... dus hij komt een element in de dom tegen en gaat kijken of ie daar een stijl bij kan vinden, maar als ik het verhaal van Harry lees, kijkt ie naar de struct en zoekt ie er een element bij. Ik ben even in de war nu.
Stel we hebben dit hele kleine voorbeeldje:
Code (php)
1
2
3
4
5
6
2
3
4
5
6
<p id="foo">
Bla die bla <span class="bar">blablabla</span>.
</p>
#foo { color: red; }
.bar { font-weight: bold; }
Bla die bla <span class="bar">blablabla</span>.
</p>
#foo { color: red; }
.bar { font-weight: bold; }
Wat doet de browser dan precies?
1. <p> -> nee geen selector
1.2 #foo -> ja selector => styles toepassen
2. <span> -> nee geen selector
2.1. .bar -> ja selector => styles toepassen
Offtopic:
Quote:
Zeg, zit je me nu voor het lapje te houden :D
Jup, sorry :)
Waar leest ie dan van rechts naar links? :-s
#foo div .bar
Is niet: ik zoek een #foo element, kijk of die een div element heeft en of die een .bar child heeft.
In plaats daarvan is het: ik heb een .bar element, kijk of hij een child van een div element is en die een child van #foo is.
Gewijzigd op 25/03/2013 20:19:56 door Wouter J
Code (php)
1
2
3
4
5
6
2
3
4
5
6
<p id="foo">
Ik ben <span class="special">speciaal</span>.
</p>
#foo { color: red; }
#foo .special { color: green; }
Ik ben <span class="special">speciaal</span>.
</p>
#foo { color: red; }
#foo .special { color: green; }
... komt ie eerst het element <p> tegen. Daar vindt ie geen opmaak bij. Dan komt ie de id foo tegen. Daar vindt ie wel een style bij een maakt ie rood. Dan komt ie <span> tegen. Daar vindt ie niks bij. Dan komt ie de class special tegen. Special daar vindt ie een stijl bij. Vervolgens gaat ie controleren of de parent de id foo heeft en hij kleurt het groen. Correct?
Wouter J op 25/03/2013 16:55:45:
Dit werkt heel simpel door gewoon de elementen af te gaan en te kijken of daarvoor iets in de styles struct staat:
Stel, deze HTML:
Met deze CSS:
Geeft dus een ander resultaat dan dit:
http://codepen.io/anon/pen/snlFy
Toevoeging op 25/03/2013 20:27:47:
Samenvattend: beide geel.
ID gaat boven de element-soort (<p> of <span>), ongeacht volgorde.
Quote:
Correct?
Ja, en daarom kun je nu ook uitleggen waarom #header * zo'n slecht idee is :)
Eddy E op 25/03/2013 20:26:31:
Euh, juist ja... een ander resultaat... beide geel. Mis ik iets??? :-)
Wouter J op 25/03/2013 20:32:20:
Ja, en daarom kun je nu ook uitleggen waarom #header * zo'n slecht idee is :)
Quote:
Correct?
Ja, en daarom kun je nu ook uitleggen waarom #header * zo'n slecht idee is :)
Ik snap 'm ;) Thanks :)
Stel ik heb een h1 en ik wil een bepaald stukje van die h1 extra opvallend (rood) maken.
Dan kan ik dus beter dit doen:
<h1>Een mooi <span class="h1-emphasize">rood</span> stukje</h1>
.h1-emphasize { color: red; }
in plaats van dit:
<h1>Een mooi <span>rood</span> stukje</h1>
h1 span { color: red; }
Correct?
Nog mooier is het om te gaan werken met BEM: Block Element Modifier. Bijv. class="emphasize--red" en class="emphasize--blue".
En om het mooi te maken moet die span natuurlijk een em element worden :)