A TEXT POST

Retour sur: 9ème Meetup HTML5, CSS3 & Pizzas

Le 23 avril dernier, j’ai eu l’occasion d’animer une présentation pompeusement nommée: «Le futur des effets graphiques sur le web» lors du 9ème Meetup HTML5.

Dans cette mini-présentation, j’ai évoquer des fonctionnalités de CSS très, voire trop, avancées. Tous les aspects de cette conférence sont donc à prendre à titre d’expérimentations. J’ai pu y parler de choses diverses:

  • les fonctions d’images: cross-fade(), element()
  • les masques CSS, SVG et les méthodes de rognage
  • les exclusions et les formes CSS
  • les filtres CSS avancés, avec notamment une démo d’utilisation des shaders

Ma présentation est disponible en ligne, directement dans votre navigateur.

Attention, prévoyez différents navigateurs et basculez de l’un à l’autre pour bénéficier de chaque effet:

  • Google Chrome Canary (28) (avec flags actifs: «Fonctionnalités expérimentales WebKit», «Shaders» et éventuellement «WebGL»
  • Firefox Nightly (23)
  • IE10

Lors de ce même Meetup, deux autres présentations ont eu lieu:

Un grand merci aux organisateurs pour ce chouette évènement, ainsi qu’à tout ceux avec qui j’ai pu discuter lors de cette soirée.

Et surtout, expérimentez!

Edit: La vidéo est en ligne!

Edit 2: Quelques tweets pour vous donner envie de regarder la vidéo:

A TEXT POST

Les transformations 3D CSS avec IE10

Avez-vous déjà utilisé les transformations 3D avec CSS? Oui? Bon point. Si ce n’est pas le cas, je vous conseille un article complet que j’avais écrit à ce sujet.

Le problème des transformations CSS 3D, ce n’est pas le support dans les navigateurs, qui est aujourd’hui plutôt bon: Chrome 12+, Safari 4+, Firefox 10+, IE10, iOS, Android 3+ (les navigateurs Opera n’ont actuellement pas de support mais cela devrait changer avec le passage à Blink). De plus, il est assez facile de prévoir des solutions de repli pour les navigateurs trop anciens.

Le problème, c’est bien son support dans IE10, et notamment la propriété transform-style: preserve-3d. Cette propriété, qui permet de forcer les éléments imbriqués à subir les transformations 3D lorsque le parent est transformé, n’est tout simplement pas reconnue dans ce navigateur.

Cette propriété peut être facultative dans le cas de transformations simples (un seul élément), mais devient nécessaire dès lors que l’on souhaite appliquer une transformation commune à un ensemble d’éléments, comme lors de la création du fameux effet Flip-Card (pourtant simple).

Sur le site de Microsoft, il est expliqué clairement:

Pour le moment, Internet Explorer ne supporte pas le mot-clé preserve-3d sur la propriété transform-style. Vous pouvez contourner ce comportement en additionnant manuellement les transformations du parent à chaque élément à transformer.

OK. Alors allons-y…

L’effet Flip-Card

Voici un effet flip-card «classique»:

Notre démo est donc ici composée:

  • d’un élement .scene qui contient un élément .flip
  • l’élément .flip contient les 2 éléments .avant et .arriere.
  • ces 2 éléments sont placés l’un sur l’autre et .arriere est transformé de 180deg sur l’axe X pour l’afficher à l’envers. Les faces arrières sont masquées.

Lors du survol de .scene, l’élément .flip est transformé de 180deg sur l’axe X également pour créer le retournement. Sans oublier de préciser transform-style: preserve-3d sur .flip pour que l’élément imbriqué .arriere subisse la transformation du parent.

.scene{
    perspective: 600px;
}
.flip{
    transform-style: preserve-3d;
}
.avant,
.arriere{
    position: absolute;
    backface-visibility: hidden;
}
.avant{
    background: tomato;
}
.arriere{
    background: deepskyblue;
    transform: rotateX(180deg);
}
.scene:hover .flip{
    transform: rotateX(180deg);
}

Ce code fonctionne dans tous les navigateurs supportant les transformations 3D. Pour IE10, il faut se passer de transform-style et répercuter la transformation du parent sur les enfants. Il nous faut donc:

  • lors du survol de .scene, transformer de 180deg sur l’axe X l’élément .avant (0 +180)
  • lors du survol de .scene, transformer de 360deg sur l’axe Y l’élément .arriere (180 + 180)
  • ôter (ou mettre en commentaire) transform-style-preserve-3d;

Le code CSS devient donc:

.scene{
    perspective: 600px;
}
.flip{
    /* transform-style: preserve-3d; */
}
.avant,
.arriere{
    position: absolute;
    backface-visibility: hidden;
}
.avant{
    background: tomato;
}
.arriere{
    background: deepskyblue;
    transform: rotateX(180deg);
}
.scene:hover .avant{
    transform: rotateX(180deg);
}
.scene:hover .arriere{
    transform: rotateX(360deg);
}

Et voici le rendu final (identique à l’effet précédent mais compatible IE10!):

Conclusion

Ce petit manque d’IE10 peut s’avérer vite pénible, notamment dans le cas d’imbrications complexes où chaque transformation doit alors se répercuter sur chaque enfant. 

Je ne sais pas personnellement pourquoi IE10 n’implémente pas cette valeur pourtant si pratique (performance? politique?). Et vous, connaissez-vous la raison?

A TEXT POST

box-decoration-break: son support progresse… lentement!

La propriété box-decoration-break du module CSS Backgrounds and Borders Level 3 n’est pas très connue, et pourtant s’avère bien pratique!

Comme le dit la spécification, cette propriété propose de définir la façon dont un élément scindé en plusieurs fragments est affiché. Un élément peut se retrouver coupé lors:

  • d’un changement de page (media print)
  • d’un saut de colonne (Multicolumn Layout)
  • d’un changement de ligne, pour les éléments inline

Lorsque qu’une boite est alors scindée, les options disponibles sont:

  • slice: chaque fragment est considéré comme une partie d’un seul élément. (c’est la valeur par défaut)
  • clone: chaque fragment est indépendant et a ses propres bordures, marges et arrière-plans.

Lorsque la valeur clone est utilisée, les propriétés suivantes sont affectées indépendamment pour chaque fragment:

  • border et ses déclinaisons
  • border-image
  • border-radius
  • padding
  • box-shadow
  • background

Sur cette démo, vous distinguez clairement la différence de rendu entre l’élément de la première colonne (avec box-decoration-break: clone) et celui de la deuxième (avec box-decoration-break: slice) si vous utilisez un navigateur compatible.

Cette propriété est actuellement supportée sur Opera (depuis la version  10.60) sans préfixes, et depuis peu dans Chrome avec préfixes. IE10 ne la supporte pas, ni Firefox et Safari d’ailleurs. Cependant Firefox supporte une propriété non standard -moz-background-inline-policy qui définit la manière dont traiter les arrière-plans au sein de plusieurs fragments. C’est une sorte de sous-propriété de box-decoration-break.

Conclusion

Après tests, il s’avère que parmi les 3 situations qui créent des fragments, seule une est implémentée dans les navigateurs: celle qui s’applique aux éléments inline sur plusieurs lignes. En conséquence, il n’est pas possible d’utiliser box-decoration-break pour des fragments sur plusieurs colonnes ou sur plusieurs pages d’impression. Et c’est bien dommage…

A TEXT POST

Les avantages de hsl() par rapport à rgb()

Le module CSS3 Color définit 4 fonctions de couleur: rgb(), hsl() et leurs pendants respectifs avec transparence rgba() et hsla().

Les fonctions rgb() ou rgba(), comme leurs noms l’indiquent, acceptent comme paramètres les valeurs Rouge (R), Vert (G), Bleu (B) et Alpha (A) définissants une couleur.

  • les valeurs R, V, et B allant de 0 (noir) à 255 (blanc)
  • la valeur Alpha allant de 0 (transparent) à 1 (visible).

Voici deux exemples d’utilisation:

/* Un rouge foncé */
rgb(80, 0, 0);

/* Du noir transparent à 50% */
rgba(0, 0, 0, .5);

Cela peut être très pratique, mais dans la majorité des cas il est très difficile de décliner une couleur afin d’obtenir des couleurs plus claires, plus foncées ou la couleur complémentaire de la teinte de base. Par exemple, prenons cette couleur:

rgb(227, 93, 54);

Personne ne peut me dire instantanément les valeurs de la couleur qui est 10% plus foncée! Après un passage dans Photoshop, je trouve

rgb(201, 84, 48);

Super.

Les avantages de hsl()

Les fonctions hsl() ou hsla() reposent sur un mode de représentation des couleurs différent, basé sur une Teinte (H), la Saturation (S) et la Lumière (L):

  • Teinte: valeur de couleur sur un cercle chromatique de 0° (Rouge) à 360° (Rouge). A 60°: Jaune, à 120°: Vert, à 180°: Cyan, à 240°: Bleu, à 300°: Magenta.
  • Saturation: de 0 à 100%
  • Lumière ou Luminance: de 0 (entièrement noir) à 100% (entièrement blanc). 50% correspond à la teinte de base.

Voici donc du rouge foncé:

hsl(0, 100%, 16%);

Et du noir transparent (peu importe la teinte et la saturation en fait, seule la luminosité à 0% compte)

hsla(0, 100%, 0%, .5);

Cette façon de représenter la couleur nous offre pas mal d’avantages.

Représentation graphique du modèle HSL en CSS

Représentation graphique du modèle HSL en CSS

Nuances et ombres

Le premier avantage est la possibilité évidente de définir les nuances (couleurs plus claires) et ombres (couleurs plus foncées) d’une teinte. Il suffit pour cela de modifier la luminosité.

/* Teinte de base */
hsl(14, 76%, 55%);

/* Plus foncée */
hsl(14, 76%, 75%);

/* Plus claire */
hsl(14, 76%, 35%);

Couleurs complémentaires

En jouant sur le paramètre Teinte, il est possible d’obtenir les couleurs complémentaires. Pour cela, il suffit d’ajouter 180° à la valeur de la teinte sur le cercle chromatique (un demi-tour).

/* Teinte de base */
hsl(14, 76%, 55%);

/* Couleur complémentaire */
hsl(194, 76%, 55%);

Il est également envisageable d’obtenir les couleurs complémentaires adjacentes en ajoutant 120° puis 240°.

/* Complémentaire adj. 1 */
hsl(134, 76%, 55%);

/* Complémentaire adj. 2 */
hsl(254, 76%, 55%);

Couleurs analogues

Toujours en jouant sur ce paramètre Teinte, il est possible d’obtenir les couleurs analogues (couleurs adjacentes). Pour cela, il suffit d’ajouter ou d’enlever à la valeur de la teinte des angles de 30°.

/* Analogue 1 */
hsl(44, 76%, 55%);

/* Analogue 2 */
hsl(344, 76%, 55%);

Couleurs monochromes

Enfin, en modifiant le paramètre Saturation, nous obtenons une palette de couleur dite monochrome.

/* Désaturation */
hsl(14, 46%, 55%);

/* Désaturation plus forte */
hsl(14, 16%, 55%);

Conclusion

Les avantages à utiliser hsl() au lieu de rgb() sont évidents. Néanmoins, il existe une contrainte de taille: les logiciels graphiques (tel Photoshop) n’utilisent pas le même modèle HSL que celui de CSS. Il n’est donc pas possible de récupérer les valeurs fournies pour les utiliser directement dans votre CSS. Pour pouvoir utiliser les bonnes valeurs, vous devrez les convertir grâce à des outils comme:

Deuxième contrainte, ces fonctions ne sont supportées qu’à partir d’IE9. Espérons que la mise à jour vers Windows 8 accélère les choses.

Allez, et comme vous êtes sympa, voici une petite démo en ligne!

A TEXT POST

La cascade CSS: inherit et initial.

Dans la gestion de la cascade CSS, il existe deux mots-clés qui peuvent s’avérer bien pratique. Ce sont les mots-clés inherit et initial.

Le mot-clé inherit

Lorsque que la valeur spécifiée pour une propriété CSS est inherit, la valeur calculée de cet élément est identique à la valeur calculée de son parent. Cela permet de forcer l’héritage. Par exemple, prenons ce code HTML:

<p>Hello CSS!</p>

Et le CSS suivant:

p{
    background: tomato;
}
p::after{
    background: inherit;
}

Dans ce cas, la couleur d’arrière-plan (qui ne s’hérite pas par défaut) du pseudo-élément sera la même que celle de l’élément <p>. Il est par exemple possible de créer une infobulle où la couleur de la petite flèche est toujours la même que la couleur de la bulle elle-même. Cela offre un gain de temps dans la mise à jour: une seule modification requise.

Mais il existe pleins d’autres cas où ce mot-clé est très pratique (width et height d’un élément en absolute par exemple). Il existe même une utilisation détournée de inherit qui permet d’animer les pseudo-éléments.

Le mot-clé inherit est très bien supporté dans les navigateurs (depuis IE8).

Le mot-clé initial en CSS3

Lorsque la valeur d’une propriété CSS est initial, la valeur utilisée sera la valeur initiale de la propriété telle qu’elle est définie dans la spécification CSS. C’est une sorte de retour à un «état normal», non hérité. Elle peut s’avérer pratique lorsque l’on souhaite annuler l’effet d’héritage tout en réinitialisant à la valeur par défaut:

  • lorsque l’on ne se souvient plus de cette valeur (e.g. C’est quoi déjà la valeur par défaut de white-space? auto, normal, none, 0? initial est le mot-clé passe-partout)
  • lorsque cette valeur est dynamique (e.g. text-align vaut left en mode ltr, et vaut right en mode rtl. text-align: initial vaut left ou right en fonction du contexte. Par ailleurs, les valeurs start et end couvrent justement ce cas là).

Cas d’utilisation: Annuler la propagation des tailles de police

Lorsque l’on utilise des unités de polices relatives (avec l’unité em par exemple), la gestion de la cascade est toujours délicate. Par exemple, sur un navigateur configuré par défaut à 16px, si l’élément <html> est défini à 0.9em (14.4px) et les p à 1em, les <p> seront affichés en fait à 0.9em (14.4px). Il faudrait utiliser 1.111111em pour que les <p> soit proche de 16px. Le mot-clé initial peut alors devenir utile dès lors que l’imbrication devient complexe.

Cas simple d’utilisation possible

html{
    font-size: .9em; /* 14.4px */
}
p{
    font-size: initial; /* 16px */
}

Vous l’aurez compris, son utilisation est limitée. De plus, le support de initial est malheureusement plus faible, Opera et Internet Explorer ne la reconnaissent tout simplement pas.

Ce mot-clé deviendra certainement plus utile lorsque la propriété all arrivera dans les navigateurs. La propriété all permettant de redéfinir l’ensemble des propriétés CSS et ainsi stopper la cascade de manière globale.

Ressources supplémentaires

Pour référence, voici quelques liens intéressants: