WebDev-FR

Archive de avril 2009

CSS Orienté Objet

par Loïc le Mercredi 29/04/2009 à 12:42, dans CSS, HTML, POO

Via un billet posté sur le blog de Rebecca Murphey (découverte grâce au lancement de JSMag), je suis tombé sur une présentation de Nicole Sullivan concernant les bonnes pratiques à adopter lors du développement de la couche CSS d’un site, pratiques qu’on pourrait plus ou moins assimiler à de la conception orientée objet appliquée aux CSS.

Ce qu’il faut en retenir (ce que j’en ai retenu)

L’un des principaux problèmes des feuilles de styles est leur tendance à gonfler, gonfler, gonfler ce qui les rend plus coûteuse en bande passante mais aussi en maintenabilité (sans compter les risques liés aux styles s’écrasant mutuellement).

La raison est relativement simple : il n’est pas forcément évident de réutiliser des styles déjà existants. On a tendance à concevoir les règles CSS par rapport au contenu d’une page, éventuellement à réutiliser ce qui a été fait sur une page similaire si les similitudes sont flagrantes.

Nicole recommande une approche bien plus pérenne : séparer la structure et le design (ce qui ne veut pas uniquement dire avoir une feuille de style externe mais se baser sur des classes CSS et non sur des balises particulières) et séparer le contenu du contenant.

En fait, il vaut voir une bonne conception CSS comme un assemblage de Legos : commencez par créer votre collection de briques. Une fois que la collection de brique est prête, vous pouvez commencer à créer vos pages, autrement dit vous pouvez commencer à assembler vos briques ensemble pour aboutir au résultat graphique attendu.

Les 10 best practices qu’elle cite :

  1. Créez une bibliothèque de composants
  2. Utilisez des styles en accord avec la sémantique
  3. Concevez des modules avec un fond transparent
  4. Soyez flexible
  5. Apprenez à aimer les grilles
  6. Minimisez l’emploi des sélecteurs
  7. Séparez la structure et le design
  8. Séparer le contenu et le contenant
  9. Etendez les objets en appliquant plusieurs classes sur un élément HTML
  10. Utilisez des feuilles de style de reset et de gestion des polices

Et les 9 choses à éviter :

  1. Evitez les styles dépendants de l’endroit où vous vous trouvez sur le site
  2. Evitez de créer des styles qui dépendent des balises utilisées
  3. Limitez l’utilisation d’IDs : ils doivent se limiter aux zones principales, pour le reste utilisez des classes
  4. Fuyez les coins arrondis ou les ombres appliqués par-dessus des fonds non-unis (image de fond ou dégradé).
  5. Evitez de faire un sprite contenant toutes vos images, à moins que vous ayez qu’un faible nombre de pages
  6. Tentez d’éviter les alignements sur la hauteur
  7. Le texte c’est du texte, pas une image contenant du texte
  8. Evitez la redondance
  9. Evitez l’optimisation prématurée

Maintenant si on va un peu plus dans les détails pour certaines parties…

Séparez le contenu du contenant

Ca veut dire qu’un module est composé :

  • d’une brique pour la gestion de la bordure (coin arrondis ou carrés, couleur, ombre)
  • d’une brique pour le fond (fond uni, image de fond en filigrane, dégradé)
  • d’un ensemble de briques pour le contenu

Autrement dit, un module devrait avoir 3 classes afin de définir à quoi doit ressembler sa bordure, quel est le fond à appliquer et comment le contenu doit être organisé.

Séparez la structure et le design

Prévoyez à l’avance la structure basique d’un bloc : faut-il un header dans un bloc ? faut-il un footer ?

De cette manière, créer un bloc se limitera à appliquer les bonnes classes (”block”, “hd”, “ft”, “bd”) au contenu du block.

Une fois que cette structure est définie, vous pouvez alors concevoir les différents design qui s’appliqueront sur cette structure : une brique avec des coins arrondis, une brique pour gérer le fond en dégradé, etc.

Faites des modules transparents

Si vous voulez des coins arrondis, préférez une solution où le coin est créé par l’extérieur et non par l’intérieur, autrement dit une solution où l’image du coin est transparente à l’intérieur et unie à l’extérieur. Cette solution vous permettra d’appliquer n’importe quel fond à l’intérieur de votre bloc, que ce soit une couleur unie ou une image en arrière-plan.

Bémol : le bloc ne pourra être placé que sur un fond correspond à la couleur extérieure de vos coins arrondis (typiquement le fond de votre page).

Soyez flexible

Faites de la gym. Faites en sorte que vos briques puissent s’adapter en largeur et en hauteur. En hauteur pour pouvoir s’adapter à la hauteur du contenu, en largeur pour pouvoir réutiliser votre brique dans n’importe quelle zone de votre grille même si la largeur varie.

C’est la grille qui doit gérer la largeur, les blocs doivent ignorer pour quelle partie de la grille ils ont été conçus.

Tentez une approche UML

Tentez de mettre en place un système d’héritage à vos briques.  Certaines briques seront compatibles ensemble (par exemple certaines briques de gestion de bordure ne pourront pas forcément être appliquées à n’importe quel brique d’arrière plan ou même de mise en forme du contenu).

Ces relations entre vos briques peuvent donner lieu à un schéma plus ou moins UML pour faciliter la compréhension des briques existantes.

Un exemple d’approche UML conçue par Nicole :

Approche UML pour la couche CSS dun projet

Approche UML pour la couche CSS d'un projet

Bref, plein de bonnes suggestions à tenter de mettre en pratique…

1 Commentaire :, , plus...

Quand IE6 ne sera plus…

par Loïc le Lundi 27/04/2009 à 16:34, dans CSS

Sur Ajaxian, on peut trouver une petite liste des 10 choses les plus cool que nous serons capables d’appliquer lorsque IE6 ne sera plus.

Essayons de notre côté d’aller un peu plus loin que cette liste. Lorsque IE6 aura disparu, la nouvelle barrière sera IE7 mais l’abandon d’IE6 débloquera un tas de fonctionnalités CSS actuellement délaissées car incompatibles.

En vrac :

  • l’utilisation du sélecteur CSS fils (>) afin de sélectionner les noeuds immédiatement en-dessous d’un noeud et non toute sa descendance.
  • j’aurais bien dit le sélecteur de noeuds adjacents (+) mais il est un poil buggé sur IE7
  • le sélecteur par attribut ([attr]) pour sélectionner des noeuds en fonction de la présence d’un attribut et de sa valeur, idéal pour différencier les éléments INPUT d’un formulaire (bouton, champs texte, bouton radio, case à cocher, bouton d’envoi, etc).
  • la bonne gestion des classes multiples, actuellement un tantinet foireuse sur IE6
  • le :hover sur n’importe quoi et pas uniquement sur les liens
  • :first-child, pour sélectionner le premier fils d’un noeud
  • le display:inline-block pour les éléments initialement avec un display:inline
  • display:list-item
  • min-width, max-width, min-height, max-height
  • utilisation correcte du overflow:visible
  • position:fixed
  • le sélecteur de précédence (~) permettant de sélectionner un noeud en fonction d’un noeud qui le précéde. Le sélecteur d’adjacence (+) implique que le noeud adjacent précéde immédiatement le noeud ciblé alors que le sélecteur de précédence (~) permet d’avoir des noeuds entre le noeud ciblé et le noeud qui précéde.

Bref, plein de nouvelles choses qui nous permettront de nous arracher un peu moins les cheveux. Mais bon, en attendant, vous allez continuer à vous les arracher par poignées, IE6 est encore coriace…

Laissez un commentaire :, , , plus...

Optimisation de la couche CSS

par Loïc le Lundi 06/04/2009 à 12:43, dans CSS

Il existe une quantité considérable de règles de bon usage, de trucs, de bidouilles voir même d’outils professionnels pour optimiser la couche CSS d’un site.

Néanmoins, une branche de ce domaine qui a été assez peu analysée est l’impact de l’utilisation des sélecteurs CSS et surtout la nécessité, ou pas, d’avoir des règles avec un grand nombre de sélecteurs.

En fait tout a démarré lorsque Dave Hyatt (le Lead Developer de l’équipe WebKit) a fait remarquer dans un commentaire du blog de Shaun Inman que les sélecteurs CSS enfant (comme le caractère espace) étaient à utiliser à la légère car s’appliquent de droite à gauche et non de gauche à droite.

The sad truth about CSS3 selectors is that they really shouldn’t be used at all if you care about page performance. Decorating your markup with classes and ids and matching purely on those while avoiding all uses of sibling, descendant and child selectors will actually make a page perform significantly better in all browsers. - Dave Hyatt

Ce qui fait que, comme le résume Jon Sykes, la règle suivante :

body table tr td.myTestClass{
  background-color: red;
}

…est moins efficace que sa version courte :

.myTestClass{
  background-color: red;
}

Pourquoi ? Tout simplement parce qu’avec la première règle, si vous modifiez le DOM cette règle devra probablement être ré-appliquée sur tout le document afin de l’appliquer à de nouveaux noeuds ou au contraire à ne plus l’appliquer sur certains noeuds. Alors qu’avec la seconde règle, la modification du DOM n’aura un impact que si cette modification consiste à ajouter ou à retirer la classe “myTestClass”.

Bref, vouloir faire des règles avec une longue série d’accesseurs enfant pour cibler exactement l’élément qui nous intéresse peut s’avérer couteux sur les performances, il est préférable de donner une classe précise à notre ou nos éléments et de créer une règle qui se base sur cette classe et sur rien d’autre.

Pour montrer ce coût en performances, Jon Sykes a réalisé plusieurs tests. Son dernier test consiste à créer une page contenant trois niveaux de DIV imbriqués, le niveau le plus profond contient un paragraphe contenant lui-même un lien. Le lien a un ID et une classe générée. Au total, il y a 20.000 liens dans la page.
Il a ensuite cherché à comparer le temps mis pour afficher la page avec les conditions suivantes :

  • aucun style appliqué
  • un fond rouge pour chaque cellule avec une unique règle qui s’applique sur la balise A
  • un fond rouge pour chaque cellule avec des règles ayant uniquement le nom de la classe du lien (20.000 règles)
  • un fond rouge pour chaque cellule avec des règles utilisant le sélecteur fils (20.000 règles)
  • un fond rouge pour chaque cellule avec des règles utilisant le sélecteur descendant (20.000 règles)

Il obtient les résultats suivants (les pourcentages affichés sont par rapport à l’affichage sans aucun style) :

  FF2 FF3 Safari3 IE6 IE7
Aucun style 2734 4059 465 916 884
A {} 2860 (+4%) 4228 (+4%) 480 (+3%) 1037 (+13%) 961 (+8%)
.classXX 3330 (+21%) 4467 (+10%) 1814 (+298%) 1878 (+104%) 2103 (+137%)
div div div p a.classXX 3417 (+24%) 4729 (+16%) 3958 (+750%) 3192 (+248%) 3447 (+289%)
div > div > div > p > a.classXX 3615 (+32%) 4690 (+15%) 3423 (+635%) 2699 (+194%) 2881 (+225%)

Bref, privilégiez les règles avec des sélecteurs courts. Ca risque d’alourdir votre code HTML avec plus de classes ou d’ID mais les performances d’affichage de votre page s’en sortiront mieux.

Pour lire les articles de Jon Sykes :

  1. Testing CSS Performance
  2. Testing CSS Performance (pt 2)
  3. More CSS Performance Testing (pt 3)

Steve Sounders creuse le sujet un peu plus loin

Les tests de Jon Sykes datent du printemps 2008.

Récemment (début Mars), Steve Sounders (de l’équipe Performances de Yahoo!) a creusé le sujet. Il considérait que bien que justes, les tests de Jon Sykes s’appliquaient à des pages bien trop volumineuses pour représenter la réalité : peu de pages peuvent se vanter d’aligner un DOM de 60.000 noeuds et de 20.000 règles CSS. Les 10 sites les plus fréquentés ont une moyenne de 923 noeuds sur leur homepage pour 1033 règles.

Les tests de Steve Sounders sont dont légèrement différents de ceux de Jon Sykes : il se limite à 2.000 liens et 2.000 règles CSS (et non plus 20.000) ce qui donne une page avec un DOM de 6.000 noeuds.
Il s’est également demandé si les résultats pour la page ne contenant aucun style et celle ne contenant qu’une seule règle sur la balise A n’avaient pas un gain en performance simplement parce que leur code contient 20.000 lignes de code en moins. Il a donc décidé de rajouter, pour ces deux cas, 2.000 règles CSS (qui ne s’appliquent sur rien du tout) afin que la taille des codes HTML soit pratiquement la même pour tous les cas de test.

Bref des tests sur un DOM plus réduit et plus proche de la réalité et des cas de tests de même volume.

Ses tests montrent des résultats assez différents de ceux de Jon Sykes, comme le montre son graphique :

On constate que la plupart des navigateurs conservent des courbes relativement “planes”. Comme le dit Steve, sur les principaux navigateurs (IE6&7 + FF3), la différence entre le test sans style et le test avec les sélecteurs fils ou descendants est en moyenne de 20ms et sur la totalité des navigateurs ça monte à une moyenne de 50ms. Donc un résultat difficile à percevoir à l’oeil nu.

Les résultats de Jon Sykes n’était donc pas vraiment applicable. Mais pourquoi une telle différence de résultats ?

Pour comprendre ce changement, Steve Sounders (qui est décidément très curieux) a décidé de refaire passer son test sur IE6&7 (ce sont les navigateurs pour lesquels il avait la différence la plus flagrante avec les tests de Jon) en les faisant tourner sur des pages ayant de plus en plus de balise A (et par conséquent de noeuds DOM et de règles CSS). Il a donc commencé avec 1.000 liens et a augmenté jusqu’à atteindre les 20.000 du test de Jon.

C’est avec ce test qu’il a constaté un palier autour de 18.000 noeuds, comme le montre son second graph :

En définitive, que devons-nous tirer de ces deux analyses ?
Simplement que la recherche d’optimisation n’est finalement pas dans l’utilisation parcimonieuse des sélecteurs CSS. Dans la plupart des cas le gain sera négligeable et risquerait d’entraîner une baisse de lisibilité du code pour les développeurs.

Laissez un commentaire :, , plus...

Vous cherchez quelque chose de particulier ?

Utilisez le formulaire ci-dessous pour chercher sur le site :

Vous ne trouvez toujours pas ce que vous cherchez ? Laissez un commentaire sur un billet ou bien contactez-moi et nous tâcherons de trouver ensemble !

Ils peuvent également vous intéresser...

Quelques blogs très intéressants que j'essaye de suivre...

Archives

Tous les billets, classés de manière chronologique...