Comment puis-je créer une «info-bulle» en utilisant du CSS pur?

89

Je viens de tomber sur une astuce CSS. Découvrez le violon ...

.tooltiptail {
  display: block;
  border-color: #ffffff #a0c7ff #ffffff #ffffff;
  border-style: solid;
  border-width: 20px;
  width: 0px;
  height: 0px;
}
.anothertail {
  background-image: url(http://static.jqueryfordesigners.com/demo/images/coda/bubble-tail2.png);
  display: block;
  height: 29px;
  width: 30px;
}
<div>Cool Trick:
  <br />
  <div class="tooltiptail"></div>
</div>
<br />

<div>How do I get this effect with only CSS?
  <br />
  <div class="anothertail"></div>
</div>

Cela crée un petit effet de type flèche / triangle, une "queue d'info-bulle". Cela me souffle! Je suis vraiment intéressé de savoir comment cela fonctionne?!

De plus, existe-t-il un moyen d'étendre cette astuce CSS pour créer un effet comme suit:

entrez la description de l'image ici

C'est un problème intéressant. Cela peut-il être fait en utilisant uniquement CSS, en ignorant l'ombre pour le moment?


MISE À JOUR 1

J'ai trouvé une solution à ma question initiale. Voici le violon ...

http://jsfiddle.net/duZAx/7/

HTML

<div style="position: relative;">Cool Trick:<br />
    <div class="tooltiptail"></div>
    <div class="tooltiptail2"></div>
</div>

CSS

.tooltiptail {
    display: block;
    border-color: #ffffff #a0c7ff #ffffff #ffffff;
    border-style: solid;
    border-width: 20px;
    width: 0px;
    height: 0px;
}
.tooltiptail2 {
    display: block;
    border-color: transparent #ffffff transparent transparent;
    border-style: solid;
    border-width: 18px;
    width: 0px;
    height: 0px;
    position: relative;
    left: 4px;
    top: -38px;
}

Maintenant, comment imiter exactement la petite image ci-dessus en utilisant du CSS pur, y compris l'ombre et en la rendant compatible avec tous les navigateurs?


MISE À JOUR 2

Voici ma solution après une combinaison des réponses ci-dessous. Je ne l'ai pas testé sur plusieurs navigateurs, mais il a fière allure dans Chrome.

http://jsfiddle.net/UnsungHero97/MZXCj/688/

HTML

<div id="toolTip">
    <p>i can haz css tooltip</p>
    <div id="tailShadow"></div>
    <div id="tail1"></div>
    <div id="tail2"></div>
</div>

CSS

#toolTip {
    background-color: #ffffff;
    border: 1px solid #73a7f0;
    width: 200px;
    height: 100px;
    margin-left: 32px;
    position:relative;
    border-radius: 4px;
    -moz-border-radius: 4px;
    -webkit-border-radius: 4px;
    box-shadow: 0px 0px 8px -1px black;
    -moz-box-shadow: 0px 0px 8px -1px black;
    -webkit-box-shadow: 0px 0px 8px -1px black;
}

#toolTip p {
    padding:10px;
}

#tailShadow {
    background-color: transparent;
    width: 4px;
    height: 4px;
    position: absolute;
    top: 16px;
    left: -8px;
    z-index: -10;
    box-shadow: 0px 0px 8px 1px black;
    -moz-box-shadow: 0px 0px 8px 1px black;
    -webkit-box-shadow: 0px 0px 8px 1px black;
}

#tail1 {
    width: 0px;
    height: 0px;
    border: 10px solid;
    border-color: transparent #73a7f0 transparent transparent;
    position:absolute;
    top: 8px;
    left: -20px;
}

#tail2 {
    width: 0px;
    height: 0px;
    border: 10px solid;
    border-color: transparent #ffffff transparent transparent;
    position:absolute;
    left: -18px;
    top: 8px;
}

Hristo
la source
Dans quels navigateurs doit-il fonctionner?
thirtydot
1
à ce stade, je m'en fiche :) Je veux juste voir si c'est possible! de façon réaliste, j'utiliserais une image mais je suis intéressé par le défi
Hristo
Cela devrait être faisable si vous utilisez des éléments en couches et un positionnement parfait au pixel pour le contour. Avec ou sans l'ombre?
Arc
@Archimedix ... tout à fait d'accord, mais pouvez-vous le faire?
Hristo
1
C'est si simple mais tellement génial, bonne trouvaille Hristo!
Wesley Murch le

Réponses:

60

Voici un exemple avec une boîte-ombre, tous les navigateurs de la dernière version devraient le prendre

http://jsfiddle.net/MZXCj/1/

HTML:

<div id="toolTip">
    <p>i can haz css tooltip</p>
    <div id="tailShadow"></div>
    <div id="tail1"></div>
    <div id="tail2"></div>
</div>

CSS:

body {font-family:Helvetica,Arial,sans-serif;}

#toolTip {
    position:relative;
}

#toolTip p {
    padding:10px;
    background-color:#f9f9f9;
    border:solid 1px #a0c7ff;
    -moz-border-radius:5px;-ie-border-radius:5px;-webkit-border-radius:5px;-o-border-radius:5px;border-radius:5px;
}

#tailShadow {
    position:absolute;
    bottom:-8px;
    left:28px;
    width:0;height:0;
    border:solid 2px #fff;
    box-shadow:0 0 10px 1px #555;
}

#tail1 {
    position:absolute;
    bottom:-20px;
    left:20px;
    width:0;height:0;
    border-color:#a0c7ff transparent transparent transparent;
    border-width:10px;
    border-style:solid;
}

#tail2 {
    position:absolute;
    bottom:-18px;
    left:20px;
    width:0;height:0;
    border-color:#f9f9f9 transparent transparent transparent;
    border-width:10px;
    border-style:solid;
}

MikeM
la source
1
Impressionnant! J'avais une solution assez similaire en tête mais j'étais paresseux de faire quelque chose après tout ce que j'ai expliqué :) +1
BoltClock
@mdmullinax ... épique! quand je récupérerai mes privilèges de vote positif, je vous donnerai un +1
Hristo
wow, super! Un petit bug: l'ombre est aussi un peu visible dans la partie supérieure de l'infobulle
Iulius Curt
@iuliux ... ce bogue peut être facilement corrigé avec z-index :)
Hristo
56

Voici une explication pour répondre à votre première question (je laisserai le CSS réel aux autres car je suis paresseux - veuillez voter pour leurs réponses qui, selon vous, méritent les votes!):

Cela crée un petit effet de type flèche / triangle, une "queue d'info-bulle". Cela me souffle! Je suis vraiment intéressé de savoir comment cela fonctionne?!

  1. Lors du rendu d'une bordure avec des couleurs de bord variables mais du même style (dans votre cas, solid), la couture séparant chaque paire de coins adjacents est une ligne diagonale. Il est tout à fait semblable à ce que le schéma ci représente la groove, ridge, insetetoutset les styles de bordure.

    Notez que si tous les navigateurs se comportent de la même manière et l'ont fait aussi longtemps que je m'en souvienne, ce comportement n'est pas entièrement défini dans la spécification CSS2.1 ou dans le module Arrière-plans et bordures CSS. Ce dernier a une section décrivant les transitions de couleur et de style aux coins , et la description semble impliquer que pour les bordures avec un rayon de coin nul, la ligne qui est rendue est en fait une ligne qui joint le coin du bord de remplissage avec le coin du bord de la bordure (résultant en une ligne inclinée à 45 degrés pour les bordures de largeur égale), mais la spécification avertit toujours que cela peut ne pas toujours être le cas (d'autant plus que cela ne prend même pas en compte explicitement les bordures avec des rayons de coin zéro). 1

  2. Par le modèle de boîte de contenu (W3C d'origine) , une zone de 40 x 40 est créée à partir des bordures de 20 pixels, les dimensions du contenu étant définies comme 0x0.

  3. La division d'un carré avec des lignes diagonales joignant ses quatre coins donne quatre triangles rectangles dont les angles droits se rencontrent au milieu du carré (voir ci-dessous).

  4. Les bordures supérieure, inférieure et gauche sont blanches pour correspondre à l'arrière-plan du .tooltiptailconteneur de l' élément, tandis que la bordure droite est d'une nuance de bleu pour correspondre à la couleur d'arrière-plan de l'info-bulle:

    border-color: #ffffff #a0c7ff #ffffff #ffffff;

Le résultat est le suivant, avec les bordures étiquetées et les limites de bordure ajoutées à l'aide de mon fidèle outil de ligne:

La réorientation de la queue de l'infobulle consiste simplement à changer la couleur de l'infobulle. Par exemple, cela donnerait une queue attachée au bas d'une pointe:

border-color: #a0c7ff #ffffff #ffffff #ffffff;

Aperçu de jsFiddle


1 Si vous tenez à respecter les normes, vous pouvez tout aussi bien considérer tout cela comme un hack.

BoltClock
la source
Putain de frappe rapide, était sur le point de dire la même chose ... +1
easwee
Eh bien, je suis clairement nul à lire des questions. Il a même dit "I'm not worried about the shadow yet".
thirtydot
1
@BoltClock ... lorsque je récupère mes privilèges de vote positif, je vous donne un +1
Hristo
@BoltClock, les comportements sont-ils cohérents entre les navigateurs? Et dans quelle mesure ce comportement est-il standard selon le w3c?
Pacerier
@Pacerier: Le comportement spécifique du rendu de la couture d'angle sous forme de ligne diagonale n'est défini dans aucune spécification. Le comportement est cohérent entre les navigateurs et est resté inchangé pendant longtemps, cependant. Je vais clarifier cela dans ma réponse.
BoltClock
19

Je fais cette info-bulle avec un seul divélément.

HTML:

<div class="tooltip">Lorem ipsum dolor sit amet, consectetur adipiscing elit. Praesent augue justo, venenatis non tincidunt sit amet, suscipit eget ligula.</div>

CSS:

.tooltip{
    position: relative;
    border: 1px solid #73a7f0;
    width: 200px;
    margin-left: 20px;
    padding: 5px 14px;
    border-radius: 4px;
    -webkit-border-radius: 4px;
    -moz-border-radius: 4px;
    box-shadow: 0px 0px 6px rgba(0, 0, 0, .7);
    -webkit-box-shadow: -0px 0px 6px rgba(0, 0, 0, .7);
    -moz-box-shadow: 0px 0px 6px rgba(0, 0, 0, .7);
}
.tooltip:before{
    content: ' ';
    display: block;
    position: absolute;
    left: -8px;
    top: 15px;
    width: 14px;
    height: 14px;
    border-color: #73a7f0;
    border-width: 1px;
    border-style: none none solid solid;
    background-color: #fff;
    box-shadow: -2px 2px 3.5px rgba(0, 0, 0, .5);
    -webkit-box-shadow: -2px 2px 3.5px rgba(0, 0, 0, .5);
    -moz-box-shadow: -2px 2px 3.5px rgba(0, 0, 0, .5);
    transform: rotate(45deg);
    -webkit-transform: rotate(45deg);
    -moz-transform: rotate(45deg);
}

Démo

Explication:

J'ai mon div normal avec une bordure comme les autres exemples. La queue est une simple combinaison de CSS:

  • J'utilise le pseudo sélecteur: before (: after fonctionne très bien aussi)
  • Je force le contenu avec un espace blanc pour rendre la queue visible.
  • Je fais pivoter ma boîte de 45 degrés pour fixer le coin sur le côté de l'info-bulle
  • Pas de surprise pour la taille et le positionnement.
  • J'ajoute une bordure sur les 2 côtés que je veux.
  • Et enfin j'ajoute les ombres à la bordure extérieure.
Yoann
la source
@Hristo Pour IE, je ne sais pas vraiment comment faire, mais voir un article: samuli.hakoniemi.net / ... Mais ça a l' air d'être difficile ... "Bon courage!"
Yoann
@DoubleYo: En ce qui concerne IE ... si j'ai besoin de rendre cet IE compatible, je vais juste utiliser des images et une feuille de style conditionnelle :)
Hristo
11

Info-bulle sans ombre

Démo Fiddle


Avec Shadow (ça a l'air un peu bizarre dans WebKit ... je dois l'optimiser je suppose):

Démo 1 , Démo 2

Arc
la source
@Archimedix ... cool :) maintenant je connais 2 façons de le faire, enfin 3 si vous comptez utiliser des images. voulez-vous opter pour l'effet d'ombre?
Hristo
@Archimedix ... ça a l'air génial! quand je récupérerai mes privilèges de vote positif, je vous donnerai un +1
Hristo
Bien comme ma deuxième solution - j'ai également réussi à corriger une partie de la transparence des bordures dans IE6 - j'ai encore besoin d'une solution pour que le wrapper de la flèche affiche la bordure dans ie6.
easwee
6

Approche Crossbrowser:

Celui-ci fonctionne à partir d'IE7 + (fonctionne également dans IE6 en utilisant ( filter: chroma(color=white);) mais n'affichera pas la bordure noire autour de la flèche).

Correction d'IE6:

* html .arrow {
        border-bottom-color:white;
        border-left-color:white;
        border-right-color:white;
        filter: chroma(color=white);

}
* html .arrow i
        {
        border-bottom-color:white;
        border-left-color:white;
        border-right-color:white;
        filter: chroma(color=white);
        }

Cela donnera à la vilaine transparence noire rendue par IE6 la couleur que vous avez spécifiée dans le filtre de chrominance (j'ai fait du blanc pour qu'il disparaisse en arrière-plan).


Approche CSS 3:

Vous pouvez le faire avec la rotation CSS3, mais échouera dans les navigateurs non compatibles CSS3:

.tooltip {
    position:relative;
    padding:10px;
    background:#ccc;
    border-bottom:1px solid #000;
}
.tooltip:before {
    content:"";
    display:block;
    width:10px;
    height:10px;
    position:absolute;
    bottom:-6px;
    border-left:1px solid #000;
    border-bottom:1px solid #000;
    background:#ccc;
    -webkit-transform: rotate(-45deg);
    -moz-transform: rotate(-45deg);
    transform: rotate(-45deg);
}
<div class="tooltip"> 
    Tooltip text that wants to be your friend.
</div>
easwee
la source
@easwee ... cool !!! Seriez-vous en mesure de fournir plus d'informations sur la rotation CSS3, des liens vers des didacticiels et d'autres ressources?
Hristo
@hristo - il existe un filtre dx pour la rotation dans IE - mais le problème est qu'il ne prend que 4 valeurs - msdn.microsoft.com/en-us/library/ms532918%28v=vs.85%29.aspx
easwee
@easwee ... Je ne suis pas trop inquiet pour IE, en particulier IE 6. Merci de l'avoir signalé. Tous les bogues IE peuvent facilement être surmontés avec un conditionnel :)
Hristo
La rotation @hristo css3 est uniquement prise en charge dans IE9 - vous devez donc toujours prendre soin de ie7-8 qui est toujours un standard pour coder. Mais c'est un début.
easwee
@easwee ... génial. Si jamais j'ai besoin de le faire et de le rendre compatible avec IE, j'utiliserais une image et une feuille de style conditionnelle :) Pourriez-vous fournir plus d'informations sur la rotation css3, des liens vers des tutoriels et d'autres ressources?
Hristo
3

Vous pouvez utiliser les pseudo-éléments: before et: after de CSS. Par exemple,: before peut être utilisé pour insérer un triangle et: after pour insérer un rectangle. La combinaison de ces deux crée une info-bulle

Par exemple :

a[bubbletooltip]:before
{
    content: "";
    position: absolute;
    border-bottom: 21px solid #e0afe0;
    border-left: 21px solid transparent;
    border-right: 21px solid transparent;
    visibility: hidden;
    bottom: -20px;
    left: -12px;
}

a[bubbletooltip]:after
{
    position: absolute;
    content: attr(bubbletooltip);
    color: #FFF;
    font-weight:bold;
    bottom: -35px;
    left: -26px;
    white-space: nowrap;
    background: #e0afe0;
    padding: 5px 10px;
    -moz-border-radius: 6px;
    -webkit-border-radius:6px;
    -khtml-border-radius:6px;
    border-radius: 6px;
    visibility: hidden;
}

Un outil en ligne est disponible à http://www.careerbless.com/services/css/csstooltipcreator.php

Kiran
la source
Pourquoi un attribut personnalisé et pas, disons title,?
BoltClock
1
Je dirais que aria-labelc'est un attribut personnalisé plus approprié pour une info-bulle. Avec title, vous obtenez également le rendu de l'infobulle par défaut du navigateur (pour les utilisateurs voyants de toute façon).
rink.attendant 6
Merci. J'avais aussi essayé d'utiliser span:beforeetspan:after de créer triangle et ajusté selon le besoin de webblogsforyou.com/... .
immayankmodi