Partager l'article ! [CSS] Infobulles 3- Faire un peu plus joli: On progresse. Le premier article donnait les bases et traitait le cas du rectangle coloré, le deu ...
On progresse. Le premier article donnait les bases et traitait le cas du rectangle coloré, le deuxième examinait de plus près l'emploi d'une image de fond et une seule, nous voilà à parler d'images extensibles. L'important, contrairement à ce qu'on pourrait penser, n'est pas l'extensibilité dans une direction ou dans deux mais l'éloignement du modèle primitif, à savoir le rectangle à fond uni (éventuellement encadré). Allons du plus proche au plus éloigné.
Petite note : tout comme dans le deuxième article, il est essentiellement question ici de peinturlure de background. Tout comme dans le deuxième article, les infobulles sont donc fixes pour vous épargner de balader votre curseur partout. L'art et la manière de rendre ces bulles escamotables sont expliqués dans le premier article.
Ça, c'est déjà vu : le rectangle à fond uni. Très sommaire (une couleur de fond, une à quatre couleurs pour les quatre bords) mais très simple à produire.
Nous ne l'avons pas exploité à fond : si on utilise une image assez grande (trop
grande), elle pourra tapisser
des bulles de dimensions très variées sans que leur contenu déborde de
l'image. Avec un peu de réflexion et un balisage inchangé on peut déjà produire un effet intéressant… lisez le chapitre qui vient.
Regardez cette image :
C'est une bulle
dont le coin supérieur gauche est un peu travaillé
(=pas un angle droit). Elle se prolonge à l'infini
vers la droite et vers le bas. Notez aussi qu'elle est bordée d'un trait gris en haut et à gauche mais ni en bas ni à droite. Maintenant regardez ce CSS :
.infotexte {padding:12px;
background:
transparent
url(http:gnagnagna/bulleCoin.gif)
scroll no-repeat top left;
border-style:solid; border-color: #888;
border-width:0 1px 1px 0;
color:black;
font-weight:normal; font-style:normal; font-family:sans-serif;
font-size:12px;line-height:normal; text-decoration:none;
position:absolute; margin-top:1em; margin-left:-999em
}
a:hover .infotexte {margin-left:-1em}
L'image sert de fond (c'était à prévoir) et il y a un pixel de bordure, mais seulement en bas et à droite (les indications sur fond grisé, toujours les mêmes, ne seront plus répétées dans la suite). Voilà le résultat :
Voici un lien une ligne un peu longue, juste pour voir muni d'une infobulle un peu longue et un autre lien
plusieurs
lignes
et encore une à bulle multi-lignes
Plaisant, non ? Toute l'astuce réside dans une définition soigneuse des bordures (n'en mettre aucune sur les côtés du coin spécial
) combinée au fait que le fond ne déborde jamais du
rectangle de remplissage. Ça nous a contrariés dans l'article précédent, il est juste que ça nous rende service dans celui-ci ! Si vous préférez que le coin spécial
ne soit pas celui du
haut à gauche il suffira, après avoir préparé une autre image infinie
, de remplacer top left par autre chose et d'ajuster les bordures.
Mais pour aller plus loin, pour des formes moins proches du rectangle pur, il faut compliquer un peu le HTML et le CSS.
Les images de fond déformables ça n'existe pas : il n'existe pas un format spécial de fichier image ni des propriétés magiques de CSS pour indiquer que les coins sont immuables, que chaque bord s'étire dans un seul sens et le centre dans les deux sens.
Au lieu de quoi nous allons combiner deux images de fond (pour commencer). Oui mais… on ne peut indiquer qu'une seule background-image par élément de page ? Très juste, c'est bien pourquoi nous utiliserons deux éléments HTML.
Jusqu'ici l'infobulle ne comportait qu'un seul élément HTML : le span de classe infotexte. Pour des raisons qui apparaîtront dans la suite, l'élément supplémentaire sera emboîté dans l'infobulle plutôt que placé avant, après, ou autour.
Trêve de parlotes : depuis deux articles nous utilisons ce code HTML :
Voici <a href="..." >un lien <span class="infotexte">qui vous enverra je ne sais où !</span> </a> muni d'une infobulle.
Il s'agit d'un span de classe infotexte contenant le texte de la bulle. Maintenant nous le complétons comme ceci :
Voici <a href="..." >un lien <span class="infotexte"> <span>qui vous enverra je ne sais où !</span> </span> </a> muni d'une infobulle.
Il s'agit d'un span de classe infotexte contenant un deuxième span sans classe particulière, lequel contient le texte de la bulle. Cherchez le changement. Très très compliqué, hein ? :-). Première vision :
Voici un lien qui vous enverra je ne sais où ! muni d'une infobulle.
Les deux fonds gris, provisoires, montrent l'assemblage. Dans le CSS, juste une nouvelle ligne :
.infotexte {padding:0;
/* etc. */}
.infotexte span {display:block}
Le display:block permettra de cuisiner tranquillement la géométrie de ce nouveau span. Le span principal est déjà, implicitement, en display:block du fait de son positionnement absolu, sans quoi il faudrait le dire explicitement. Maintenant, au boulot !
Voici les deux images que nous utiliserons :
|
|
|
|
Demi-bulle gauche 16x32 pixels |
Corps de bulle infinivers la gauche et demi-bulle droite 484x32 pixels |
Qui utiliser comme fond de quoi ? Puisque les deux spans sont superposés, la question n'est pas sotte. Mettons le corps de bulle, qui se verra derrière le texte, en fond du span interne. Tant qu'on y pense, et puisque l'image fait 32 pixels de hauteur, choisissons height et padding de ce span pour totaliser 32 :
.infotexte {padding:0;}
.infotexte span {display:block
height:16px; padding:8px 0;/* 16+8+8=32*/
background:
transparent
url(http:gnagnagna/bulleDlongue.gif)
scroll no-repeat
top right
}
Voici un lien qui vous enverra je ne sais où ! muni d'une infobulle.
Notez le top right dans le CSS pour que le coin supérieur droit de l'image soit dans le coin supérieur droit du span, sans quoi on est mal. Autre chose : le texte s'arrête au ras de la bulle, logique puisqu'il n'y a pas de padding à droite. Le demi-cercle de droite est large de 16 pixels, corrigeons le CSS en conséquence et voyons ce que ça donne :
.infotexte {padding:0;}
.infotexte span {display:block
height:16px; padding:8px 0;padding-right:16px;
background:
transparent
url(http:gnagnagna/bulleDlongue.gif)
scroll no-repeat
top right
}
Voici un lien qui vous enverra je ne sais où ! muni d'une infobulle.
Maintenant, la partie gauche. Elle va servir de fond au span principal, bien sûr, mais si on s'en tient là on ne verra rien : elle sera sous le corps de bulle parce que, actuellement, le span emboîté remplit tout le span principal. Pour dégager la vue ajoutons un peu de padding-left à ce span principal en même temps que la deuxième image de fond:
.infotexte {padding-left:16px;
background:
transparent
url(http:gnagnagna/bulleG.gif)
scroll no-repeat
top left
}
.infotexte span {display:block
height:16px; padding:8px 0;padding-right:16px;
background:
transparent
url(http:gnagnagna/bulleDlongue.gif)
scroll no-repeat
top right
}
Résultat avec seulement le padding à gauche (fond gris) :
Voici un lien qui vous enverra je ne sais où ! muni d'une infobulle.
Résultat avec l'image :
Voici un lien qui vous enverra je ne sais où ! muni d'une infobulle.
Et, comme promis, c'est extensible :
Voici un lien court ! muni d'une infobulle.
Voici un lien trèèèèèèèèèèèèèèèèèèèèèèèèèèèèèèèèèèèèèèèèès long ! muni d'une infobulle.
Voilà tout le secret…
Sous IE6 la fin du paragraphe précédent donne ceci :
… qui est amusant, pour le dire aimablement. En repartant du modèle simple (le rectangle coloré à un seul span) et en le complétant progressivement, on observe ceci :
IE ne place pas correctement la bulle au chargement de la page ? Faites l'essai en remplaçant le -999em qui l'envoie hors champ par 0, par exemple. On voit la bulle se placer d'abord contre le
bord gauche de l'article (alors qu'elle devrait rester juste après le texte du lien), puis à la place attendue (en léger retrait du lien) lorsqu'on survole le lien, enfin revenir à l'aplomb du
lien lorsqu'on cesse de le survoler (là où elle aurait dû se trouver dès le début). Cela vient, je pense, de ce que le lien est un élément inline
: IE6 ne le prend pas en compte en
faisant sa mise en page de la bulle. Au survol du lien il se réveille : Ah tiens, je devrais placer cet absolu d'une certaine manière
et dès lors reste dans les clous. Par chance,
dans le cas de notre infobulle, ce placement initial incorrect ne se remarque pas : -999em ou -1004em, c'est de toute façon hors champ. Mais tout de même…
Continuons, continuons, ça va devenir franchement rigolo. D'après le W3C, mettre la bulle en position absolue a deux conséquences :
blocksordinaires qui sont aussi larges que possible, est aussi faible que possible : adaptée au contenu de la bulle.
Cette adaptation de la largeur au contenu est justement ce qui rend la bulle extensible en largeur, elle est à la base du procédé. Quand on ajoute le span interne, lui aussi affiché
comme un block
mais sans positionnement absolu (vous saisissez la finesse ?), il se rend aussi large que possible dans les limites de son contenant, à savoir la bulle, bulle
dont la largeur dépend… de ce qu'il y a dans ce nouveau span ! Comment IE6 s'en débrouille-t-il ?
Seulement il faut bien préciser la géométrie de ce span interne. Essayons :
Les propriétés height (et width) ne sont pertinentes que pour un élément block
(en gros). Ici, tout se passe comme si IE6 se disait Ça alors, c'est vraiment un
bloc ! Faut que je le formatte dans les règles ! Pleine largeur, zou !
en oubliant totalement que ce span se trouve dans un élément absolu
et que pleine largeur
signifie donc largeur de la bulle
. Largeur qui, du fait du placement absolu, dépend justement de ce span intérieur…
N'accablons pas davantage le pécheur. La Providence permet qu'on s'en sorte à moindres frais en n'utilisant surtout pas height: 16px mais font-size: 16px;line-height: 16px. Tout ça pour ça ? Ben oui, c'est IE, que voulez-vous…
Quelle différence entre ces deux propriétés ? height est une dimension d'un block
, un rectangle à l'intérieur duquel on fourre ce qu'on veut, gros ou petit. À l'opposé
line-height est une propriété du texte, apparentée à la taille de la police de caractères : hauteur complète d'une ligne de texte, c'est elle qui détermine l' interlignage
du
texte, l'espacement vertical entre lignes. En rendant les deux identiques on supprime l'interlignage. Normalement ces deux propriétés sont indépendantes mais j'ai observé qu'IE6, sûrement pour
simplifier la vie des auteurs de pages Web, limite l'interlignage selon la taille de la police. Donc ceinture ET bretelles, autant imposer les deux.
Exactement le même principe, avec les mots width, top et bottom au lieu de height, left et right (ici pas de souci avec IE6 car les largeurs sont fixées, on ne définit pas les hauteurs, il se sent beaucoup mieux). Les deux images :
|
|
|
|
Demi-bulle haut 16x192 pixels |
Très haut corps de bulle et demi-bulle bas 112x192 pixels |
Le CSS :
.infotexte {padding-top:16px;
background:
transparent
url(http:gnagnagna/bulleH.gif)
scroll no-repeat
top left
}
.infotexte span {display:block
width:176px; padding:0 8px; padding-bottom:16px;
background:
transparent
url(http:gnagnagna/bulleB.gif)
scroll no-repeat
bottom left
}
Le résultat :
Voici un lien une ligne muni d'une infobulle et un autre lien plusieurs
lignes
et encore une muni d'une infobulle.
Où ça devient
beau (attention aux bulles ! baissez la tête),
où ça devient beau c'est que le HTML est rigoureusement identique dans ces deux cas, même pas besoin d'une classe supplémentaire tant que le texte ne contient pas à son tour d'autres
span. Transformer une bulle horizontale en une verticale ne demande ainsi que des modifications de CSS, c'est toujours plus commode quand on perfectionne le design de son site.
Ça, c'est le principe des infobulles dans mes modules. Ce cas est lui aussi IE6-proof.
|
|
|
|
Bord gauche 12x128 pixels |
Corps de bulle et bord droit 376x128 pixels |
C'est un hybride de la bulle à un seul coin spécial (mais ici tout le côté G est spécial) et de la bulle extensible en largeur (mais on va gagner de l'élasticité en hauteur). Voici les particularités :
infiniedans une direction verticale, vers le bas ou vers le haut (ici, vers le bas pour les deux images) ;
infiniedans une direction horizontale, ici vers la droite (on en a profité pour caser un petit motif jaune en haut à G : coin
spécial).
Le résultat :
.infotexte {padding-left:12px;
background:
transparent
url(http:gnagnagna/infiniG.gif)
scroll no-repeat
top left
}
.infotexte span {display:block
padding: 8px; border-style:solid; border-color: #888;
border-width:0 1px 1px 0;
background:
transparent
url(http:gnagnagna/infiniD.gif)
scroll no-repeat
bottom left
}
Voici un lien un mot avec infobulle et un autre lien Les deux images sont infinies vers le bas.
Celle du texte est spéciale
en haut à G (motif jaune) et infinie
à D.
Les bordures viennent fermer les côtés infinis
. doté d'une infobulle plus copieuse.
En changeant le choix des directions infinies
on peut produire divers effets, on est cependant obligé de conserver au moins deux coins normaux
.
C'est du chinois ? Voici un autre exemple :
|
|
|
|
Bord gauche 8x128 pixels |
Corps de bulle et bord droit 377x128 pixels |
.infotexte {padding-left:8px;padding-top:6px;
background:
transparent
url(http:gnagnagna/coinsHGBD-G.gif)
scroll no-repeat
top left
}
.infotexte span {display:block
padding: 10px; border-style:solid; border-color: #888;
border-width:1px 0 0 0;
background:
transparent
url(http:gnagnagna/coinsHGBD-D.gif)
scroll no-repeat
bottom right
}
Toujours un lien un mot avec infobulle et un autre lien Image infinie
vers le haut et la gauche.
Notez le placement en bottom right
et la définition des bordures,
notez aussi le padding-top ajouté au span principal. muni d'une infobulle.
Ce cas-là, je crois que je le garde pour un prochain article : celui-ci est bien assez long, vous ne trouvez pas ?
Sur la page du présent article les bulles ne sont pas 'à éclipse', simplement pour épargner au lecteur de promener son curseur partout (je l'avais précisé dans le précédent article, je devrais sans doute le rappeler dans celui-ci aussi). Est-ce cela qui vous tracasse ou bien avez-vous un pb pour réaliser cette bulle sur une de vos pages ?
Les bulles du module "Orientation", en haut à d, appliquent cette technique. Elles marchent ?
Mais on tombe si souvent sur des tutos qui en fait ne fonctionnent pas ou plus...
Quoiqu'il en soit merci pour cet article, très bien écrit, et votre réponse si rapide.
La réponse rapide est un pur coup de chance : jouez au Loto, c'est le jour ! Mais il y a toujours une réponse.
Je m'efforce de tenir en état de marche ce que je propose, mais on n'est jamais à l'abri d'une erreur, j'apprécie toujours qu'on me les signale.
Et si, par-dessus le marché, cet article vous a plu, alors... nirvana !
Je passe tout à fait par hasard, je cherche un code css pour un demi rond.
Je n'ai pas trouvé mon bonheur, c'est trop "savant" pour mes modestes connaissances mais je voulais juste vous dire que votre fond d'écran m'a vraiment séduite, très original et puis ça bouge, vraiment super et du pas vu, félicitations !
Merci ! Je ne voudrais pas vous laisser dans la débine, cependant.
CSS3 (non utilisé dans cet article) permet de définir les rayons de courbure des coins. Si on pousse l'idée un peu loin :
petit exemple :
.demirond {border:20px solid red;border-width:20px 20px 0 ; border-radius:20px 20px 0 0;width:0;height:0 }
Alors
<div class="demirond"></div>
sera rendu comme un demi-cercle rouge de rayon 20px
Tous les détails CSS3 pour approfondir la question. Bien sûr, je ne garantis pas que ça marche pour tous les navigateurs. Si vous tenez vraiment à votre demi-cercle, faites une image !
Bon courage et bons essais ;-)
Demain matin, à tête reposée, je vais faire des essais.
Vous avez de quoi occuper vos loisirs avec cette magnifique bibliothèque bien pleine :-) :-)
Bonne fin de soirée et merci encore.