30 april 2015

Techie Tip: Gewichtigheid CSS Selectors.

development

Verschillende onderdelen binnen één website. Je ziet het steeds vaker. Om verschillende publieksgroepen aan te spreken worden vaak meerdere designvariaties per website gebruikt. Maar hoe ga je daar technisch op een goede manier mee om? Jeffrey helpt ons door het doolhof.

Een voorbeeld:
Vastgoedorganisatie X heeft één website, waarop twee activiteiten centraal staan, namelijk huizen verkopen en huizen verhuren. Klinkt logisch, maar in de praktijk gaat het om twee totaal verschillende doelgroepen.

De design oplossing

Vanuit design wordt meestal gebruik gemaakt van één algemene uitstraling/huisstijl voor de hele website. Differentiatie richting verschillende doelgroepen vindt vaak plaats door te werken met verschillende kleuren en/of symbolen. Tenminste dat is in de praktijk vaak de meest effectieve designoplossing.

En dan naar de front-end…

In dit voorbeeld gebeurt dat door alle informatie (nieuwsartikelen, productinformatie etc.) over huurwoningen in het rood weer te geven en alle koopwoningen in het blauw. Dit werkt vaak visueel gezien heel goed, maar technisch is het al snel een uitdaging.

Hoe meer kleuren er worden gebruik, des te ingewikkelder het is om deze designoplossing op een efficiënte manier in de front-end op te lossen. Datzelfde geldt voor crosslinken tussen de verschillende categorieën. Als je bij een koopwoning zit te kijken en je krijgt een blokje informatie te zien over een huurwoning wil je dat het in één oogopslag duidelijk is dat het om een huurwoning gaat en niet om een koopwoning.  Dat kan technisch nog weleens een uitdaging zijn.

Voorbeeld:
In dit voorbeeld gaan we één stapje verder en nemen we een informatieve website met drie focus categorieën. Iedere categorie heeft één huisstijlaanpassing, namelijk een specifiek kleurenschema per categorie: Blauw, roze en groen.

Dit kleurenschema zorgt ervoor dat op iedere pagina binnen de blauwe categorie alle tekstlinks en titels/kopteksten blauw moeten zijn. Op deze pagina’s is het echter ook mogelijk om sub-blokjes  toe te voegen. Deze refereren op hun beurt naar één van de twee andere categorieën. Deze sub-blokjes moeten de kleur van de bijbehorende categorie hebben. Gaat de tekst om een roze categorie? Dan moeten de links en kopteksten in dit blok ook roze zijn.

In HTML en CSS ziet dat er als volgt uit. 

Uitleg:

Je ziet hier drie fieldsets met een basis kleur gedefinieerd en één fieldset zonder. De eerste en de laatste fieldset vertonen het gewenste resultaat. Hier worden de sub-blokjes namelijk aangevuld met de andere kleur.  Bij de tweede fieldset wordt de tweede h2 overschreven met de basis kleur (groen). Bij de derde fieldset wordt zowel de tweede als de derde overschreven. Niet het resultaat dat je wilt hebben natuurlijk…
 

Wat gebeurt hier nu precies?

In de CSS hebben we de volgende regels staan:

.color-1 h2{
    color: cyan;
}

.color-2 h2{
    color: lime;
}
(...)

In de html heeft iedere fieldset een basis kleur gedefinieerd (.color-1, .color-2, .color-3) met daarbinnen drie kolommen die ook een kleur gedefinieerd hebben. Neem bijvoorbeeld de derde fieldset, tweede kolom.

<fieldset class="color-2">
          (...)
<div class="column color-1">  
<h2>Title</h2>
          </div>
          (...)
</fieldset>

Op basis van deze informatie kun je vaststellen dat de volgende selectors van toepassing zijn:

  • .color-1 h2
  • .color-2 h2

Omdat CSS niet inhoudelijk kijkt naar de afstand tussen de twee selector onderdelen ( .color-x & h2 ) weet CSS niet dat .color-1 specifieker en meer gewenst is. De afstand tussen de classnaam en het h2 element is immers kleiner dan tussen de .color-2 class en het h2 element. Dus beide styles worden gekoppeld. Omdat de .color-1 definitie in het CSS bestand hoger staat dan de .color-2 definitie wordt eerst de .color-1 definitie toegepast. Daarna past CSS de volgende stijl toe aan het element: de .color-2 definitie. De eerste .color-1 definitie wordt dus overschreven:

  1. Zoek .color-1 h2
  2. Maak alle met .color-1 h2 matchende elementen blauw
  3. Zoek .color-2 h2
  4. Maak alle met .color-2 h2 matchende elementen groen

De oplossing

De gemakkelijkste manier om dit probleem op te lossen is door er een selector tussen te plaatsen, zodat de bovenliggende parent (.color-2) niet zomaar alles meer kan overschrijven. Voeg deze style toe om het goed te krijgen:
.color-2 .color-1 h2

Nu gaat het proces als volgt:

  1. Zoek .color-1 h2
  2. Maak alle met .color-1 h2matchende elementen blauw
  3. Zoek .color-2 h2
  4. Maak alle met .color-2 h2 matchende elementen groen
  5. Zoek .color-2 .color-1 h2
  6. Maak alle met .color-2 .color-1 h2 matchende elementen blauw

Kan het niet gemakkelijker?

Waarom zo omslachtig? Kan je niet gewoon alle h2 elementen een class .colorx-title meegeven of iets deregelijks? Dan krijg je dit probleem helemaal niet.

Dat is waar inderdaad! Voor jou als front-ender in ieder geval… Je verlegt het probleem namelijk naar de back-end. De meeste content komt namelijk meestal uit een CMS systeem middels een WYSIWYG-editor. Dus de oplossing zou dan zijn om de door de WYSIWYG-editor gegenereerde teksten (automatisch) aan te passen, zodat de h2 elementen een class mee krijgen met een .colorx-title. Omdat je hierdoor styling elementen (een classnaam) verplaats naar de back-end code geeft dit meerdere complicaties:

  1. Je moet in back-end code zoeken naar de definitie van de .colorx-title class.
  2. Het ‘even’ toevoegen van een stylingsregel kan niet meer in de CSS, maar moet via deze extra class in de back-end code.
  3. Hierdoor wordt de styling verspreid over 3 locaties (HTML, CSS & C#) en wordt onderhoud onoverzichtelijker -> moeilijker te onderhouden -> kosten aanpassingen meer tijd -> kost het meer geld om hetzelfde te fiksen.

Maar is het copy-pasten van de CSS code, zoals ik hierboven beschreven heb, dan niet zo ingewikkeld? Omdat ik alle CSS drie keer definieer? Ja... Maar... Dat is vrij eenvoudig op te lossen door deze code in een apart LESS, SCSS of PostCSS bestand/functie te zetten. Dus is niet écht een probleem.

Vragen?

Wil je meer weten over bovenstaande oplossing of kunnen we je helpen met andere front-end uitdagingen? Neem dan nu contact met ons op!

Geschreven door: Jeffrey Arts
Cookies?

We gebruiken cookies om het functioneren van onze website te verbeteren. De gegevens worden volledig anoniem verzameld.