Il m'a fallu un moment avant de reprendre le temps de rédiger un article sur ce blog, j'ai beaucoup travaillé sur mon moteur de recherche PHP et sur mes extensions WordPress comme Advanced Search ou Excerpt Generator, ce qui ne m'a pas laissé beaucoup de temps pour revenir vers vous. Comme j'ai la tête dans le code PHP en ce moment, je vous propose un article sur la création de feuilles de style CSS avec PHP.
Pourquoi ne pas le faire avec les préprocesseurs CSS ?
La tendance actuelle du web est de diriger le CSS vers la création de feuilles de style dynamiques avec des préprocesseurs toujours plus nombreux. Tout a commencé avec SASS/SCSS puis des concurrents tels que LessCSS, Stylus, CSS Crush ou encore Closure de Google et depuis, tout le monde ne parle plus que de ça... Certes, l'envie de créer des CSS dynamiques n'est pas nouvelle, mais je vous avoue que je ne comprends pas totalement l'engouement pour ces meta-langages créés de toutes pièces alors que nous pouvons faire la même chose plus facilement avec du simple PHP...
Pour être tout-à-fait honnête avec vous, j'apprécie quand même les préprocesseurs CSS comme LessCSS ou Stylus pour ne nommer qu'eux, la syntaxe est très simple et il suffit de quelques heures de pratique pour générer des feuilles CSS complexes et abouties. Toutefois, mon principal reproche est de devoir faire appel à des installations parfois "bancales" avec des parseurs PHP ou Javascript qui compilent le code créé un peu quand ils le souhaitent. LessCSS permet également de compiler avec Javascript directement côté client, c'est avantageux mais cela demande davantage de chargement si la feuille est longue et complexe...
En d'autres termes, les préprocesseurs CSS sont plutôt de bons outils, mais il faut vraiment y aller avec des pincettes pour faire de bonnes choses. L'idéal est sûrement de créer ses propres feuilles SCSS ou Less (exemple ci-dessous), de les convertir en CSS avec des outils en ligne puis d'envoyer une copie convertie sur les hébergeurs, mais cela fait pas mal de démarche pour obtenir un CSS dynamiques. Nous allons voir que la technique avec PHP est bien plus efficace et directe, et surtout bien plus complète si elle est bien pensée dès le départ...
Est-il plus avantageux de créer des CSS dynamiques avec PHP ?
Nous pouvons légitimement nous demander pourquoi les préprocesseurs CSS ont été créés si PHP permet de faire également des CSS dynamiques. Ma réponse est simple : je n'en sais rien du tout... Plus sérieusement, l'avantage des préprocesseurs CSS est de pouvoir compiler le code dynamiquement côté serveur mais aussi côté client quand on le souhaite, ce qui peut s'avérer pratique dans certains cas. De plus, ils offrent des écritures simplifiées et relativement pratiques pour faire de l'héritage de sélecteurs ou classes CSS, c'est très pratique et plutôt bien pensé pour conserver une logique de code même dans les feuilles de style (ce qui est souvent reproché au CSS classique).
En réalité, PHP nous permet aussi de faire de l'héritage si nous le souhaitons, il suffit de coder quelques fonctions ou quelques class en PHP objet pour obtenir de tels résultats, mais pour cela, ce sont vos petits doigts qui devront le faire... De plus l'avantage de créer des CSS dynamiques avec PHP est de pouvoir relier cela à des boutons d'actions voire à des bases de données si nécessaire (qui sait...^^). Il est également bien plus simple de coder dans un langage qu'on maîtrise plutôt que d'apprendre encore des mini-langages de niches, bien que les exemples comme SCSS ou Stylus soient plutôt "simples". Enfin, et je parle en connaissance de cause, il est bien plus agréable de passer uniquement par PHP côté serveur plutôt que d'ajouter des couches et sous-couches d'actions avec les parseurs, les compilateurs et tout ce qui va avec, notamment quand la compatibilité n'est pas au rendez-vous (petite pensée pour SCSS qui fonctionne une fois sur deux dans mes projets, selon le navigateur...).
Enfin, sachez que le W3C réfléchit déjà à l'élaboration de feuilles de styles CSS dynamiques avec des variables comme dans les autres langages de programmation. Il s'agit d'un document de travail du 29 octobre 2013 mais cela laisse rêveur. Pour résumer, il sera possible de créer des variables en ajoutant le préfixe "var-" puis en appelant dans la propriété CSS la variable créée avec la fonction "var(nomVariable);"... Le W3C réfléchit également à une fonction @supports et un système conditionnel utilisé dans certains cas comme le prouve la documentation brouillon du 9 novembre 2013. En d'autres termes, peut-être que les préprocesseurs CSS ou la technique qui va suivre
Comment procéder pour créer des CSS dynamiques avec PHP ?
Rien de plus simple en vérité... Voici la méthode complète pour créer des CSS dynamiques avec PHP, cela va même peut-être vous faire mal de savoir que c'était aussi facile si vous ne l'avez jamais tenté :
- Créer une feuille de style "style.php" par exemple ;
- Ajouter le code suivant en haut du fichier créé : <?php header("Content-type: text/css; charset=UTF-8"); ?>
- Appeler le fichier "style.php" dans le HEAD de votre page web avec la balise <link rel="stylesheet" href="style.php" />
Voilà, c'est tout, il suffit ensuite d'ajouter du code avec le header() du fichier "style.php" pour générer des variables (voir exemple ci-dessous). Je vous fournis quelques fonctions par la suite pour avoir une idée de ce que nous pouvons faire avec PHP pour gagner du temps. N'hésitez pas à partager vos idées si vous en avez, tout est bon à prendre pour que nous évoluions tous ensemble !
<?php header("Content-type: text/css; charset=UTF-8"); $couleur = '#242424'; $largeur = "50%"; ?> body { background-color:<?php echo $couleur; ?>; } .maClass { width:<?php echo $largeur; ?>; }
Si vous voulez améliorer les performances, vous pouvez également ajouter les lignes "ob_start('ob_gzhandler');" ou encore "header('Cache-Control: max-age=31536000, must-revalidate');" par exemple, il suffit de les coller juste avant ou juste après le "header("Content-type: text/css; charset=UTF-8");" pour que cela fonctionne bien...
Quelques fonctions d'exemples
Créer ses CSS dynamiques est avantageux mais si nous nous limitons à créer des variables, l'intérêt tombe rapidement à l'eau, surtout que l'écriture pourra paraître "lourde" et le gain de temps réduit. Le plus intéressant est de créer des fonctions qui nous font gagner du temps. Je ne suis pas là pour tout vous fournir mais voici quelques idées de fonctions qui "gagnent" du temps, n'hésitez à créer vos propres fonctions CSS en PHP...
/*----------------------------------------------------------------*/ /*-- Fonction qui permet de créer une grille CSS rapidement --*/ /*----------------------------------------------------------------*/ function creerGrille($nomClass = "class", $nbClass = 20, $baseWidth = 100, $uniteWidth = "%") { if($uniteWidth == "%") { $coefficientWidth = 100/$nbClass; } else { $coefficientWidth = $baseWidth/$nbClass; } for($i=1; $i < $nbClass+1; $i++) { $width = ceil($i * $coefficientWidth); echo ".".$nomClass."-".$i." { width:".$width.$uniteWidth."; }\n"; } } // Fonction qui génère un reset CSS simple (à appeler au début) function resetCSS() { echo "* { margin:0; padding:0; font-size:100%; border:0; font-style:normal; font-weight:normal; }\n"; } // Fonction qui créé la class .clear pour contrer les float function clearCSS($nomClass = "clear") { echo ".".$nomClass." { clear:both; }\n"; } /*---------------------------------------------------*/ /*-- Fonction pour générer la propriété "border" --*/ /*---------------------------------------------------*/ function borderCSS($direction = array(), $couleur = "#000", $width = "1px", $type = "solid") { if(empty($direction) && (!in_array("top", $direction) || !in_array("bottom", $direction) || !in_array("left", $direction) || !in_array("right", $direction))) { echo "border:".$width." ".$type." ".$couleur.";"; } else { foreach($direction as $trbl) { echo "border-".$trbl.":".$width." ".$type." ".$couleur."; "; } } }
Il suffit d'appeler ces fonctions simplement avec des codes PHP :
- <?php resetCSS(); ?>
- <?php clearCSS(); ?>
- <?php creerGrille("item", 10, 960, "px"); // pour créer 10 class de layout (.item-1, .item-2, etc.) jusqu'à 960px de largeur ?>
- <?php borderCSS($array("top", "left")); // pour créer border-top et border-left, etc. ?>
De même, vous pouvez tout à fait créer une fonction simple qui permet d'ajouter les préfixes utiles en cas de besoin (bien que des outils comme PrefixFree ou PrefixR le fassent très bien), comme la fonction suivante :
function prefixesCSS($tableauProprietes = array()) { $result = ""; foreach($tableauProprietes as $propriete => $valeur) { $result .= $propriete.":".$valeur.";\n"; $result .= "-moz-".$propriete.":".$valeur.";\n"; $result .= "-webkit-".$propriete.":".$valeur.";\n"; $result .= "-o-".$propriete.":".$valeur.";\n"; $result .= "-ms-".$propriete.":".$valeur.";\n"; $result .= "-khtml-".$propriete.":".$valeur.";\n"; } return $result; } /* Elle peut s'utiliser ainsi : $tableauProprietes = array( "transform" => "rotate(45deg)", "box-shadow" => "10px 10px 5px #888" ); echo ".maClass {\n".prefixesCSS($tableauProprietes)."}"; */