A TEXT POST

Kiwiparty 2012

La kiwiparty vient de s’achever. C’était l’occasion pour moi de donner une première conférence, sur CSS bien entendu.

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

  • apports en matière de typographie, avec notamment font-feature-settings pour le contrôle poussée des variantes de caractères.
  • les fonctions d’images: cross-fade() ou element()
  • l’interaction entre SVG et CSS
  • les filtres CSS (flou, niveau de gris, négatif) et les filtres SVG complexes
  • les masques CSS et SVG
  • un soupçon de CSS4

Retrouvez ma présentation Les effets graphiques (très) avancés sous différents support

Note: La version HTML/CSS utilise le framework reveal.js de Hakim El Hattab.

Pour aller plus loin:

Encore un grand merci à Alsacréations pour l’organisation.

A TEXT POST

CSS 3D panorama

Il y a quelques temps, je me suis amusé à réaliser un panorama 3D qui utilise uniquement les transformations CSS 3D.

Pour ce faire, les 6 images du panorama sont appliquées sur un cube. L’interaction avec le cube est réalisée via Javascript. Un telle réalisation permets de voir un cas d’utilisation précis des transformations 3D, tout en conservant la séparation fond/forme/contrôle.

Ce panorama fonctionne aujourd’hui avec les versions de Safari 4, Firefox 10 et Chrome 20 (le bug a été fixé). IE10, qui pourtant supporte les transformations 3D, ne reconnait pas encore la déclaration transform-style: preserve-3d, donc les transformations sont appliquées à plat. Opéra ne reconnait pas encore les transformations 3D. En ce qui concerne le rendu sur mobile, iOS et Android 4 s’en sortent très bien.

La démo est en ligne sur CSS3Create.

A TEXT POST

Imbrication de boites en CSS avec display: table

Tout d’abord, plantons un peu le décor: les valeurs table, table-row, table-cell, etc. permettent de simuler une structure en tableau, de la même façon que le faisaient les balises table, tr, td, etc., mais de façon propre, puisque la mise en forme est entièrement réalisée via CSS.

Si vous avez besoin d’un rappel, la conférence donnée par Raphaël à Paris-Web 2011, justement sur les tableaux de mise en page est une très bonne introduction. 

Maintenant que nous savons que IE7 est mort aussi (moins de 4% en mars en France), les valeurs table et cie de la propriété display prennent tout leur sens dans la construction de pages web. Il est donc temps de faire quelques tests d’empilements, parce que tout n’est pas si rose, surtout à l’heure du responsive design.

Le deal: en mode “écran de bureau”, on affiche 4 blocs cotes à cotes, puis en mode “tablette”, 2 blocs sur 2 lignes, et en mode mobile, 4 blocs les uns en dessous des autres. Pour faire cela avec les valeurs table, ce n’est pas si simple. Je me suis amusé à le créer et cela demande plusieurs imbrications de blocs.

La démo en ligne est par ici.

Le fonctionnement

En mode “écran de bureau”, on a donc 4 éléments en display: table-cell (cellule) et un élément en display: table. Facile. 

<div id="bloc">
     <div>1</div>
     <div>2</div>
     <div>3</div>
     <div>4</div>
</div>
#bloc{
     display: table;
     table-layout: fixed;
}
#bloc > div{
     display: table-cell;
     text-align: center;
     vertical-align: middle;
}

Le problème se pose quand on passe en mode tablette, car il nous faut 2 lignes de 2 éléments. Il nous manque alors un élément parent pour les deux premiers blocs, et un pour les deux suivants afin de créer les lignes. Le problème, c’est qu’en ajoutant de nouveaux blocs parents, la mise en forme “écran de bureau” n’est plus possible, car les cellules ne sont plus enfants directs du tableau. 

Pour pallier ce problème, il nous faut ruser en multipliant les éléments, pour que certains se comportent comme des cellules de tableau, et en même temps, qu’ils se comportent comme des tableaux qui contiendront d’autres cellules, afin de créer un layout complexe.

<div id="bloc">
     <div>
          <div>
               <div>1</div>
               <div>2</div>
          </div>
     </div>
     <div>
          <div>
               <div>3</div>
               <div>4</div>
          </div>
     </div>
</div>
/* ecran de bureau */
#bloc{
     display: table;
     table-layout: fixed;
}
#bloc > div{
     display: table-cell;
}
#bloc > div > div{
     display: table;
}
#bloc > div > div > div{
     display: table-cell;
}

/* tablette */
#bloc > div{
     display :table;
}
#bloc > div > div{
     display: table-row;
}
#bloc > div > div > div{
     display: table-cell;
}

En mode “mobile”, l’empilement des blocs n’est pas non plus évident à gérer car trop d’éléments sont parfois présents, mais dans le même temps, il en manque au dernier niveau. Il faut alors recourir à un empilement supplémentaire de blocs et de valeurs, comme table-row-group (groupe de lignes) qui contient des table-row (lignes), qui contiennent des table-cell (cellules) pour que l’élément en bas de la hiérarchie conserve les avantages des tableaux. (Sinon, display: block est très bien!)

Conclusion

Tout cela n’est pas très optimisé niveau balisage HTML, mais ça a le mérite de fonctionner, et aucun élément ne sort du flux de la page. Mais surtout, tous les avantages que l’on connait aux tableaux sont applicables (hauteurs de blocs identiques, alignement vertical au sein d’une cellule, largeurs fluides, etc.)

Je n’ai (pour le moment) trouver aucune autre façon de faire, mais je suis en attente de vos commentaires et/ou retours d’expériences sur l’utilisation de cette technique.

J’ai quand même l’impression que ces valeurs (si pratiques soient-elles) ne vont pas servir souvent dans le cadre d’un web design adaptatif complet. C’est dommage. Elle serviront par contre parfaitement pour une partie précise d’une page. Du coup, les modèles Flexbox, Grid Layout (avec template) restent encore très attendus.

Note: Marche parfaitement dans Firefox, Chrome/Safari, IE8 (avec Respond.js pour media-querie), Opéra.

Edit (12/04/12): Le principe de ce test est d’avoir toujours le dernier enfant affiché telle une cellule. De cette façon, les éléments frères ont une hauteur identique. J’ai donc ajouté la possibilité de modifier le contenu de chaque élément pour voir le comportement des éléments frères. Pour que tout marche parfaitement, j’ai du ajouter un vertical-align: top sur les enfants.

A TEXT POST

[Astuce] Utiliser les transitions CSS sur les dégradés

Faire des transitions entre les images d’arrière-plan est un rêve pour tout designer CSS. Actuellement, c’est totalement impossible, que ce soit avec des images ou avec des dégradés. La spécification CSS 3 a tenté de résoudre ce problème en proposant la fonction cross-fade(), qui permettrait exactement de réaliser cela, mais cette fonction a été retirée pour une étude plus poussée dans CSS4. Les dernières versions de Webkit supportent néanmoins une version expérimentale de cette fonction avec quelques contraintes, comme la taille des images identiques. 

En attendant que la fonction cross-fade() soit correctement définie et disponible pour tout les navigateurs, quelques astuces nous permettent de réaliser des transitions entre deux dégradés. Voici un article pour effectuer des transitions entre images.

Première astuce

La première astuce consiste à utiliser une couleur de fond unie et un dégradé au dessus avec la transparence, par exemple:

div{
     background-color: deeppink;
     background-image: linear-gradient( white, rgba(255,255,255,0));
     transition: background-color 1s;
}
div:hover{
     background-color: steelblue;
}

Ainsi, lors du :hover, la couleur du fond est modifiée avec les transitions CSS. Le dégradé, lui, ne l’est pas. La contrainte de cette technique est que le dégradé doit avoir au minimum une couleur identique, celle du dégradé. Vous pouvez trouver un exemple de cette technique sur CSS3Create.

Seconde astuce

La deuxième astuce consiste à combiner la première avec l’utilisation des ombres. Grâce à box-shadow, il suffit de créer un “faux” dégradé, et d’animer cette propriété, comme ceci:

div{
     background-color: deeppink;
     box-shadow: 0 200px 100px -100px white inset; 
     transition: box-shadow 1s;
}
div:hover{
     background-color: green;
     box-shadow: 0 200px 100px -100px yellow inset; 
}

L’astuce ici réside dans le mot-clé inset pour créer une ombre interne, et dans l’utilisation de la valeur d’étendue de l’ombre pour agrandir la taille de l’ombre et ainsi simuler un dégradé linéaire. 

De plus, cette technique à le mérite de fonctionner depuis assez longtemps dans les navigateurs.
J’attends vos commentaires et retours d’expérience.