Chapitre 5
Manipulation d'images

Retour Accueil CSS

49 Bande dessinée : paroles et pensées.

Termes CSS clés employés : border-radius, ::before, ::after, animation.
Compatibilité navigateurs : IE10+, Firefix22.0+, Chrome et Safari avec préfixe, Opera16+.

Problématique

Créer des éléments simulant des bulles de paroles ou de pensée, de type bande dessinée. Les appliquer à des personnages de façon à ne les afficher que lorsque le pointeur est sur le personnage concerné.

Résolution théorique

Cet exemple est de loin le plus complexe abordé jusqu’à présent, car mettant en œuvre plusieurs des techniques examinées séparément. Une bulle de bande dessinée est un ovale, ce que nous savons définir. Une bulle de pensée surmonte de petits cercles, qu’il est facile d’ajouter avec les pseudo-éléments ::before et ::after. Pour une bulle de parole, c’est un triangle, que nous savons également créer grâce aux effets de marge et ajouter automatiquement grâce à ::after. La seconde partie de l’énoncée est simple : nous employerons la pseudo-classe :hover pour n’afficher les éléments concernés que lorsque le pointeur est sur le personnage

Résolution pratique

La première étape consiste à définir des bulles de bande dessinées. Créer un ovale blanc avec une bordure noire est simple :
.ovale { width:largeur; padding:10px 10px; background:#FFF; border:2px solid black; border-radius:100% / 90%; }
Remarquez que le rayon de la bordure est défini en pourcentage de la largeur. Celle-ci dépend du texte placé dans la bulle : largeur et position devront être définies individuellement pour chaque bulle. Pour une bulle de pensée, il faut ajouter deux cercles de taille décroissante, grâce à ::before et ::after. Nous leur affectons une position absolue par rapport à l’ovale. La position exacte peut devoir être ajustée en fonction du contexte.
/* Grand cercle */ .ovale::before { content:""; position:absolute; bottom:-38px; left:60px; width:25px; height:25px; background:white; border:2px solid black; border-radius:30px; } /* Petit cercle */ .ovale::after { content:""; position:absolute; bottom:-60px; left:70px; width:12px; height:12px; background:white; border:2px solid black; border-radius:15px; }
Dans le cas d’une bulle de parole, nous employons également deux éléments ajoutés grâce à ::before et ::after. Ces deux éléments sont des triangles obtenus par effet de marge : l’élément ::before est une flèche noire, et l’élément ::after une flèche blanche de taille un peu inférieure, puisqu’une marge ne possède pas de bordure.
.ovale::before { content:""; position:absolute; bottom:-55px; /* valeur un peu supérieure à la longueur de la flèche */ left:68px; border-left:0px solid transparent; /* largeur initiale de la partie gauche de la flèche (ici 0) */ border-right:12px solid transparent; /* largeur initiale de la partie droite de la flèche */ border-top:54px solid black; /* longueur de la flèche */ } .ovale::after { content:""; position:absolute; bottom:-48px; /* une valeur un peu inférieure à la longueur de la flèche pour bien réaliser la jonction avec la bulle */ left:70px; border-left:0px solid transparent; /* largeur initiale de la partie gauche de la flèche (ici 0) */ border-right:7px solid transparent; /* largeur initiale de la partie droite de la flèche */ border-top:50px solid white; /* longueur de la flèche */ }
Remarquez qu’il est ici créé un triangle rectangle. Un triangle isocèle serait obtenu en donnant une valeur à la marge gauche. De plus, la flèche pourrait être tournée grâce à un transform:rotate() de façon à être orientée à votre guise. La copie d’écran suivante montre les différentes possibilités :

Bulles de bande dessinée

Texte dans la bulle

Texte dans la bulle

Texte dans la bulle

Texte dans la bulle

Bulle de pensée Bulle de parole
(triangle rectangle)
Bulle de parole
(triangle isocèle)
Bulle de parole
(triangle isocèle avec rotation)

Le résultat n’est pas parfait après une rotation : une solution pourrait être de tricher en augmentant la largeur de la bordure de la bulle. Passons maintenant à la réalisation de votre image de bande dessinée. Le code HTML est relativement simple : un élément conteneur qui comportera l’image en arrière-plan contient autant d’éléments DIV.segment juxtaposés que de personnages. Chaque segment contient un élément bulle, de classe pensee ou parole selon les cas, auxquels sont également attribués un identifiant pour permettre les réglages individuels. Un élément P enfant du précédent détermine le texte à afficher dans la bulle.
<IV class=conteneur> <DIV class=segment> <DIV class=pensee id="pe1"> <P class=texteBD>C'est d'un lourd, ce truc...</P> </DIV> </DIV> <DIV class=segment> <DIV class=pensee id="pe2"> <P class=texteBD>Et après l'avoir jeté, je fais quoi ? </P> </DIV> </DIV> … <DIV class=segment> <DIV class=parole id="pa4"> <P class=texteBD>Attends voir.... Non, ce sont trois trolls !</P> </DIV> </DIV> </DIV>
Dans le code CSS, définissons le conteneur : sa taille est celle de l’image définie comme arrière-plan.
DIV.conteneur { display:block; margin : 2px auto 2px; width:849px; height:410px; border:0px; background-color:white; background-image: url(gondorfort.jpg); }
Les segments sont définis de façon à recouvrir tout le conteneur. La marge gauche négative sert ici à ajuster les choses…
DIV.segment { display:inline-block; float:left; width:142px; height:410px; margin-left:-1px; background-color: transparent; }
Le code des éléments pensee et parole ainsi que celui de leurs éléments ::after et ::before sont identiques aux codes présentés auparavant. Nous employons ici comme flèches de simples triangles rectangles. La taille de la bulle est toutefois omise : cela est effectué individuellement d’après les identifiants, de même que le positionnement exact de chaque bulle, grâce aux marges.
div#pe1 { width:140px; margin-left:5px; margin-top: 115px; } … DIV#pa4 { width:175px; margin-left:-30px; margin-top:0px ; }
Dans le cas présent, la longueur et position par défaut de la flèche pour la dernière bulle ne conviennent pas : nous les modifions explicitement.
DIV#pa4::after { border-top:25px solid white; bottom:-23px; left:120px; } DIV#pa4::before { border-top:24px solid black; bottom:-24px; left:118px; }
Il convient également de définir le style du texte figurant dans la bulle. Comme il s’agit d’une bande dessinée, nous avons fait appel à une police particulière, appelée à l’aide de la règle CSS @font-face de façon à être toujours disponible :
@font-face { font-family: AnimeAce; src: url('Animeace2_reg.ttf'); } .texteBD { text-align:center; font-family:AnimeAce, Arial; margin:10px auto 10px; color:#000; background:transparent;}
Voici le résultat à ce stade.

Bande dessinée

C'est d'un lourd, ce truc...

Et après l'avoir jeté, je fais quoi ?

Le premier qui s'approche...

Hardi les gars !

Mais c'est un troll, là ?

Attends voir.... Non, ce sont trois trolls !

Les bulles se recouvrent, ce qui n’est guère esthétique. Comme nous voulons un affichage séquentiel lorsque le pointeur survole un personnage, interdisons par défaut l’affichage, puis activons-le à l’aide de la pseudo-classe :hover :
.pensee { display:none; … } .parole { display:none; … } DIV.segment:hover .pensee {display:inline-block;} DIV.segment:hover .parole {display:inline-block;}
En déplaçant latéralement le pointeur, les bulles successives apparaissent.

Bande dessinée

C'est d'un lourd, ce truc...

Et après l'avoir jeté, je fais quoi ?

Le premier qui s'approche...

Hardi les gars !

Mais c'est un troll, là ?

Attends voir.... Non, ce sont trois trolls !

Nous pourrions assez aisément pousser un peu la complexité, en ajoutant une animation de façon à ce qu’un personnage puisse effectuer successivement plusieurs déclarations. Commençons par le code HTML. Nous ajoutons simplement dans un segment de nouveaux éléments de classe parole, dûment identifiés.
<IV class=segment> <DIV class=parole id="pa2"><P class=texteBD>Hardi les gars ! </P></DIV> <DIV class=parole id="pa2b"><P class=texteBD>Ils ne sont pas si nombreux...</P></DIV> <DIV class=parole id="pa2c"><P class=texteBD>...et c'est nous les gentils !</P></DIV> </DIV>
Dans le code CSS, définissons la position de ces nouveaux éléments :
DIV#pa2b{ position:absolute; width:150px; margin-left:60px; margin-top:-100px ; } DIV#pa2c { position:absolute; width:180px; margin-left:60px; margin-top:-90px ; }
L’apparition et la disparition des bulles sera effectué par une rotation sur l’axe horizontal : un élément « plat » sera invisible. Nous définissons donc en cas de survol du segment les rotations initiales, puis définissons une animation infinie de 9 secondes pour les trois bulles :
DIV.segment:hover DIV#pa2 {transform:rotateX(0deg);animation: texte1 9s infinite;} DIV.segment:hover DIV#pa2b {transform:rotateX(90deg);animation: texte2 9s infinite;} DIV.segment:hover DIV#pa2c {transform:rotateX(90deg);animation: texte3 9s infinite;}
Enfin, le code des animations proprement dites : chaque image apparaît pendant un tiers de l’animation (soit ici 3 secondes), la rotation étant quasi imperceptible.
@keyframes texte1 { from {transform:rotateX(0deg);} 33% {transform:rotateX(0deg);} 34% {transform:rotateX(90deg);} to {transform:rotateX(90deg);} } @keyframes texte2 { from {transform:rotateX(90deg);} 33% {transform:rotateX(90deg);} 34% {transform:rotateX(0deg);} 66% {transform:rotateX(0deg);} 67% {transform:rotateX(90deg);} to {transform:rotateX(90deg);} } @keyframes texte3 { from {transform:rotateX(90deg);} 66% {transform:rotateX(90deg);} 67% {transform:rotateX(0deg);} to {transform:rotateX(0deg);} }
Remarquez que le code des animations pourrait être pris pour tout groupe de trois dialogues.

Bande dessinée

C'est d'un lourd, ce truc...

Et après l'avoir jeté, je fais quoi ?

Le premier qui s'approche...

Hardi les gars !

Ils ne sont pas si nombreux...

...et c'est nous les gentils !

Mais c'est un troll, là ?

Attends voir.... Non, ce sont trois trolls !


Retour Accueil CSS

© 1999-2014 Fabrice "Fyndhorn Elder" Lemainque