Jak mogę stworzyć „ogon podpowiedzi” używając czystego CSS?

89

Właśnie trafiłem na zgrabną sztuczkę CSS. Sprawdź skrzypce ...

.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>

Tworzy to efekt przypominający małą strzałkę / trójkąt, „ogon podpowiedzi”. To mnie zaskakuje! Naprawdę interesuje mnie, jak to działa ?!

Ponadto, czy istnieje sposób na rozszerzenie tej sztuczki CSS, aby uzyskać następujący efekt:

wprowadź opis obrazu tutaj

To ciekawy problem. Czy można to zrobić używając tylko CSS, na razie ignorując cień?


AKTUALIZACJA 1

Znalazłem rozwiązanie mojego początkowego pytania. Oto skrzypce ...

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;
}

Jak dokładnie naśladować powyższy obrazek, używając czystego CSS, w tym cienia i kompatybilności z różnymi przeglądarkami?


AKTUALIZACJA 2

Oto moje rozwiązanie po połączeniu poniższych odpowiedzi. Nie testowałem tego w wielu przeglądarkach, ale wygląda świetnie w 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
źródło
W jakich przeglądarkach musi działać?
trzydzieści kropek
1
w tym momencie nie obchodzi mnie to :) Chcę tylko zobaczyć, czy to jest możliwe! realistycznie, użyłbym obrazu, ale interesuje mnie wyzwanie
Hristo
Powinno to być wykonalne, jeśli używasz warstwowych elementów i idealnie dopasowanego piksela do konturu. Z cieniem czy bez?
Arc
@Archimedix ... całkowicie się zgadzam, ale czy możesz to zrobić?
Hristo,
1
To takie proste, ale tak niesamowite, dobrze znajdź Hristo!
Wesley Murch,

Odpowiedzi:

60

Oto przykład z cieniem pola, wszystkie najnowsze wersje przeglądarek powinny to obsługiwać

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
źródło
1
Niesamowite! Miałem na myśli raczej podobne rozwiązanie, ale byłem leniwy, aby coś po tym wszystkim wyjaśnić :) +1
BoltClock
@mdmullinax ... epickie! kiedy odzyskam uprawnienia do głosowania za awansem, dam ci +1
Hristo.
Wow świetne! Mały błąd: cień jest również trochę widoczny w górnej części podpowiedzi
Iulius Curt
@iuliux ... że błąd może być łatwo ustalony z z-index :)
Hristo
56

Oto wyjaśnienie, aby odpowiedzieć na Twoje pierwsze pytanie (faktyczny CSS zostawię innym, ponieważ jestem leniwy - proszę, zagłosuj za ich odpowiedzi, które Twoim zdaniem zasługują na głosy!):

Tworzy to efekt przypominający małą strzałkę / trójkąt, „ogon podpowiedzi”. To mnie zaskakuje! Naprawdę interesuje mnie, jak to działa ?!

  1. Podczas renderowania obramowania z różnymi kolorami krawędzi, ale w tym samym stylu (w twoim przypadku solid), szew dzielący każdą parę sąsiednich rogów jest linią ukośną. Jest bardzo podobny do tego, co schemat tutaj przedstawia z groove, ridge, inseti outsetstylów obramowania.

    Zauważ, że chociaż wszystkie przeglądarki zachowują się w ten sam sposób i robią to odkąd pamiętam, to zachowanie nie jest w pełni zdefiniowane ani w specyfikacji CSS2.1, ani w module CSS Backgrounds and Borders. Ta ostatnia ma sekcję opisującą przejścia kolorów i stylów w rogach , a opis wydaje się sugerować, że w przypadku obramowań z zerowymi promieniami narożników renderowana linia jest w rzeczywistości linią łączącą narożnik krawędzi dopełnienia z narożnikiem border edge (co skutkuje ukośną linią pod kątem 45 stopni dla granic o równej szerokości), ale specyfikacja nadal ostrzega, że ​​nie zawsze tak jest (zwłaszcza, że ​​nie uwzględnia wyraźnie granic z zerowymi promieniami narożników). 1

  2. Zgodnie z modelem pudełka zawartości (oryginalny W3C) obszar 40x40 jest tworzony z 20-pikselowych granic, z wymiarami zawartości zdefiniowanymi jako 0x0.

  3. Dzielenie kwadratu ukośnymi liniami łączącymi jego cztery rogi daje w wyniku cztery trójkąty prostokątne, których kąty proste spotykają się w środku kwadratu (patrz poniżej).

  4. Górna, dolna i lewa krawędź są białe, aby pasowały do ​​tła .tooltiptailkontenera elementu, a prawe obramowanie jest w odcieniu niebieskim, aby dopasować się do koloru tła podpowiedzi:

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

Wynik jest następujący, z etykietami i granicami dodanymi za pomocą mojego zaufanego narzędzia Line Tool:

Zmiana orientacji ogona podpowiedzi jest po prostu kwestią zmiany koloru podpowiedzi. Na przykład dałoby to ogon, który jest przymocowany do spodu końcówki:

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

jsFiddle podgląd


1 Jeśli jesteś zwolennikiem zgodności ze standardami, równie dobrze możesz uznać to wszystko za hack.

BoltClock
źródło
Cholernie szybkie pisanie, miało powiedzieć to samo ... +1
łatwe
Cóż, wyraźnie jestem do dupy w czytaniu pytań. To nawet powiedział "I'm not worried about the shadow yet".
trzydzieści kropek
1
@BoltClock ... kiedy się moje przywileje upvoting powrotem, dam ci +1
Hristo
@BoltClock, czy zachowania są spójne w różnych przeglądarkach? A jak standardowe jest to zachowanie według w3c?
Pacerier
@Pacerier: Specyficzne zachowanie renderowania szwu narożnego jako linii ukośnej nie jest zdefiniowane w żadnej specyfikacji. Zachowanie jest spójne we wszystkich przeglądarkach i pozostaje niezmienione przez długi czas. Wyjaśnię to w mojej odpowiedzi.
BoltClock
19

Robię tę podpowiedź z tylko jednym divelementem.

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);
}

Próbny

Wyjaśnienie:

Mam swój normalny div z obramowaniem, tak jak w innym przykładzie. Ogon to prosta kombinacja CSS:

  • Używam pseudo selektora: przed (: po też działa dobrze)
  • Wymuszam treść białą przestrzenią, aby ogon był widoczny.
  • Obracam pudełko od 45 stopni, aby naprawić róg z boku podpowiedzi
  • Nic dziwnego, jeśli chodzi o rozmiar i położenie.
  • Dodaję obramowanie z dwóch stron, które chcę.
  • I na koniec dodaję cienie do zewnętrznej granicy.
Yoann
źródło
@Hristo Dla IE Naprawdę nie wiem, jak to zrobić, ale przeczytaj artykuł: samuli.hakoniemi.net/… Ale wygląda na to, że jest to trudne ... " Bonamana !"
Yoann
@DoubleYo: W odniesieniu do IE ... jeśli muszę zrobić to IE kompatybilny, ja po prostu użyć wizerunki i warunkową stylów :)
Hristo
11

Etykietka bez cienia

Fiddle Demo


Z Shadow (wygląda trochę dziwnie w WebKit ... chyba muszę to zoptymalizować):

Demo 1 , Demo 2

Łuk
źródło
@Archimedix ... super :) teraz znam 2 sposoby na zrobienie tego, no cóż 3, jeśli liczyć używając obrazów. zależy Ci na efekcie cienia?
Hristo
@Archimedix ... wygląda świetnie! kiedy odzyskam uprawnienia do głosowania za awansem, dam Ci +1
Hristo
Ładnie, tak samo jak moje drugie rozwiązanie - udało mi się również naprawić część przezroczystości obramowania w IE6 - nadal potrzebuję rozwiązania dla opakowania strzałki, aby wyświetlić obramowanie w IE6.
easwee
6

Podejście między przeglądarkami:

Ten działa z IE7 + (działa również w IE6 przy użyciu ( filter: chroma(color=white);), ale nie wyświetla czarnej ramki wokół strzałki).

Poprawka 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);
        }

To sprawi, że brzydka czarna przezroczystość renderowana przez IE6 będzie miała kolor określony w filtrze chrominancji (zrobiłem biały, więc znika w tle).


Podejście CSS 3:

Możesz to zrobić z rotacją CSS3, ale zakończy się niepowodzeniem w przeglądarkach niezgodnych z 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>
łatwe
źródło
@easwee ... cool !!! Czy byłbyś w stanie podać więcej informacji na temat rotacji CSS3, linków do samouczków i innych zasobów?
Hristo
@hristo - w IE jest filtr dx do rotacji - ale problem polega na tym, że przyjmuje tylko 4 wartości - msdn.microsoft.com/en-us/library/ms532918%28v=vs.85%29.aspx
easwee
@easwee ... Nie martwię się zbytnio o IE, zwłaszcza IE 6. Dziękuję za zwrócenie uwagi. Wszelkie błędy IE można łatwo usunąć za pomocą warunku :)
Hristo
Rotacja @hristo css3 jest obsługiwana tylko w IE9 - więc nadal musisz uważać na ie7-8, które nadal są standardem w kodowaniu. Ale to początek.
easwee
@easwee ... awesome. Jeśli kiedykolwiek będę musiał to zrobić i uczynić go kompatybilnym z IE, użyłbym obrazu i warunkowego arkusza stylów :) Czy byłbyś w stanie podać więcej informacji na temat rotacji css3, linków do samouczków i innych zasobów?
Hristo
3

Możesz skorzystać z pseudoelementów CSS: before i: after. Dla instancji: before można użyć do wstawienia trójkąta, a: after do wstawienia prostokąta. Połączenie tych dwóch elementów tworzy bąbelkową wskazówkę

Np .:

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;
}

Narzędzie internetowe jest dostępne pod adresem http://www.careerbless.com/services/css/csstooltipcreator.php

Kiran
źródło
Dlaczego atrybut niestandardowy, a nie, powiedzmy title,?
BoltClock
1
Powiedziałbym, że aria-labeljest to bardziej odpowiedni atrybut niestandardowy dla podpowiedzi. Dzięki temu titleotrzymujesz również domyślne renderowanie podpowiedzi przeglądarki (i tak dla widzących użytkowników).
rink.attendant 6
Dzięki. Próbowałem również użyć span:beforei span:afterstworzyć trójkąt i dostosowałem go zgodnie z potrzebami z webblogsforyou.com/… .
immayankmodi