Как я могу создать «хвост всплывающей подсказки», используя чистый CSS?

89

Я только что наткнулся на изящный трюк с CSS. Посмотри на скрипку ...

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

Это создает эффект небольшой стрелки / треугольника, «хвоста всплывающей подсказки». Это взрывает мой разум! Мне действительно интересно узнать, как это работает ?!

Кроме того, есть способ расширить этот трюк CSS для создания следующего эффекта:

введите описание изображения здесь

Это интересная проблема. Можно ли это сделать, используя только CSS, игнорируя пока тень?


ОБНОВЛЕНИЕ 1

Я нашел решение своего первоначального вопроса. Вот скрипка ...

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

Теперь, как мне точно имитировать маленькую картинку выше, используя чистый CSS, включая тень и кроссбраузерность?


ОБНОВЛЕНИЕ 2

Вот мое решение после комбинации ответов ниже. Я не тестировал его в нескольких браузерах, но он отлично смотрится в 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;
}

Христо
источник
В каких браузерах он должен работать?
30dot
1
на данный момент мне все равно :) Я просто хочу посмотреть, возможно ли это! реально, я бы использовал изображение, но меня интересует задача
Христо
Должно быть выполнимо при использовании многослойных элементов и точного позиционирования контура. С тенью или без?
Arc
@Archimedix ... полностью согласен, но ты можешь это сделать?
Христо
1
Это так просто, но так здорово, хорошая находка, Христо!
Уэсли Мерч

Ответы:

60

Вот пример с box-shadow, все браузеры последних версий должны поддерживать это

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
источник
1
Потрясающие! Я имел в виду довольно похожее решение, но после всего того, что я объяснил, мне лень было сделать что-нибудь :) +1
BoltClock
@mdmullinax ... эпично! когда я получу обратно свои права голоса, я дам вам +1
Христо
вау, отлично! Небольшая ошибка: тень также немного видна в верхней части всплывающей подсказки
Юлиус Курт
@iuliux ... эту ошибку можно легко исправить с помощью z-index :)
Христо
56

Вот объяснение, чтобы ответить на ваш первый вопрос (я оставлю сам CSS другим, поскольку я ленив - пожалуйста, проголосуйте за их ответы, которые, по вашему мнению, заслуживают голосов!):

Это создает эффект небольшой стрелки / треугольника, «хвоста всплывающей подсказки». Это взрывает мой разум! Мне действительно интересно узнать, как это работает ?!

  1. При рендеринге границы с разными цветами краев, но в одном стиле (в вашем случае solid), стык, разделяющий каждую пару соседних углов, представляет собой диагональную линию. Это очень похоже на то , что схема здесь изображает из groove, ridge, insetи outsetстилей границ.

    Обратите внимание, что, хотя все браузеры ведут себя одинаково и делали это столько, сколько я помню, это поведение не полностью определено ни в спецификации CSS2.1, ни в модуле CSS Backgrounds and Borders. В последнем есть раздел, описывающий переходы цветов и стилей в углах , и описание, похоже, подразумевает, что для границ с нулевым радиусом углов отображаемая линия фактически является линией, которая соединяет угол края отступа с углом граница границы (в результате получается линия под углом 45 градусов для границ равной ширины), но спецификация по-прежнему предупреждает, что это может быть не всегда (тем более, что она даже не учитывает явно границы с нулевым радиусом угла). 1

  2. Согласно модели бокса содержимого (исходный W3C) , область 40x40 создается из 20-пиксельных границ с размерами содержимого, определяемыми как 0x0.

  3. Разделение квадрата диагональными линиями, соединяющими его четыре угла, дает четыре прямоугольных треугольника, прямые углы которых пересекаются в средней точке квадрата (см. Ниже).

  4. Верхняя, нижняя и левая границы белые, чтобы соответствовать фону .tooltiptailконтейнера элемента, а правая граница имеет оттенок синего цвета, чтобы соответствовать цвету фона всплывающей подсказки:

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

В результате границы помечены, а границы добавлены с помощью моего надежного инструмента Line Tool:

Изменение ориентации хвоста всплывающей подсказки - это просто вопрос смены цвета всплывающей подсказки. Например, в результате получится хвост, прикрепленный к нижней части наконечника:

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

jsFiddle предварительный просмотр


1 Если вы приверженец соблюдения стандартов, то можете считать все это хакерством.

BoltClock
источник
Чертовски быстро печатал, собирался сказать то же самое ... +1
easwee
Что ж, я явно не умею читать вопросы. Это даже сказано "I'm not worried about the shadow yet".
30dot
1
@BoltClock ... когда я получу обратно свои права голоса, я дам вам +1
Христо
@BoltClock, Согласовано ли поведение в разных браузерах? А насколько стандартно такое поведение по w3c?
Pacerier
@Pacerier: Конкретное поведение при визуализации углового шва в виде диагональной линии не определено ни в одной спецификации. Однако поведение одинаково во всех браузерах и остается неизменным долгое время. Я поясню это в своем ответе.
BoltClock
19

Я делаю эту подсказку только с одним divэлементом.

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

Демо

Пояснение:

У меня есть обычный div с рамкой, как и в другом примере. Хвост - это простая комбинация CSS:

  • Я использую псевдоселектор: before (: after тоже отлично работает)
  • Я заставляю содержимое с белым пространством сделать видимым хвост.
  • Я поворачиваю коробку с 45 градусов, чтобы зафиксировать угол сбоку подсказки.
  • Неудивительно для размера и расположения.
  • Я добавляю границу с двух сторон, которые хочу.
  • И, наконец, я добавляю тени к внешней границе.
Йоанн
источник
@Hristo Для IE я действительно не знаю, как это сделать, но посмотрите какую-нибудь статью: samuli.hakoniemi.net/… Но это выглядит непросто ... "Приятного вам мужества!"
Йоанн,
@DoubleYo: Что касается IE ... если мне нужно сделать этот IE совместимым, я просто буду использовать изображения и условную таблицу стилей :)
Христо
11

Подсказка без тени

Демо скрипки


С Shadow (выглядит немного странно в WebKit ... я думаю, нужно его оптимизировать):

Демо 1 , Демо 2

Дуга
источник
@Archimedix ... круто :) теперь я знаю 2 способа сделать это, ну и 3, если считать по изображениям. хотите пойти на эффект тени?
Христо
@Archimedix ... отлично выглядит! когда я получу обратно свои права голоса, я поставлю вам +1
Христо
Приятно, как и мое второе решение - мне также удалось исправить некоторую прозрачность границы в IE6 - все еще нужно решение для оболочки стрелки для отображения границы в IE6.
easwee
6

Кроссбраузерный подход:

Этот работает в IE7 + (работает и в IE6 с использованием ( filter: chroma(color=white);), но не отображает черную рамку вокруг стрелки).

Исправление 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);
        }

Это сделает уродливую черную прозрачность, которая отображается в IE6, того цвета, который вы указали в фильтре цветности (я сделал белый цвет, чтобы он исчез в фоновом режиме).


Подход CSS 3:

Вы можете сделать это с помощью ротации CSS3, но в браузерах, несовместимых с 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
источник
@easwee ... круто !!! Не могли бы вы предоставить дополнительную информацию о ротации css3, ссылки на учебные пособия и другие ресурсы?
Христо
@hristo - в IE есть фильтр dx для поворота, но проблема в том, что он принимает только 4 значения - msdn.microsoft.com/en-us/library/ms532918%28v=vs.85%29.aspx
easwee
@easwee ... Меня не слишком беспокоит IE, особенно IE 6. Спасибо, что указали на это. Любые ошибки IE можно легко преодолеть с помощью условных обозначений :)
Христо
Вращение @hristo css3 поддерживается только в IE9, поэтому вам все равно придется позаботиться о ie7-8, которые по-прежнему являются стандартом для кодирования. Но это только начало.
easwee
@easwee ... круто. Если мне когда-нибудь понадобится сделать это и сделать его IE-совместимым, я бы использовал изображение и условную таблицу стилей :) Не могли бы вы предоставить дополнительную информацию о ротации css3, ссылки на учебные пособия и другие ресурсы?
Христо
3

Вы можете использовать псевдоэлементы: before и: after CSS. Например,: before можно использовать для вставки треугольника и: after для вставки прямоугольника. Комбинация этих двух элементов создает всплывающую подсказку.

Например:

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

Онлайн-инструмент доступен по адресу http://www.careerbless.com/services/css/csstooltipcreator.php.

Kiran
источник
Почему настраиваемый атрибут, а не, скажем title,?
BoltClock
1
Я бы сказал, что aria-labelэто более подходящий настраиваемый атрибут для всплывающей подсказки. С помощью titleвы также получаете отображение всплывающей подсказки браузера по умолчанию (в любом случае для зрячих пользователей).
rink.attendant.6
Спасибо. Я также попытался использовать span:beforeи span:afterсоздать треугольник и настроить в соответствии с потребностями с webblogsforyou.com/… .
immayankmodi