32

Увидел интересную идею для Tooltip. Её отличие от других состоит в том, что боковые полосы стрелки заходят в тело образовывая две прозрачные полосы. Не могу понять, как осуществить эти вырезы.

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

Мой код:

.tooltip {
  display: inline-block;
  position: relative;
  padding: 10px;
  background-color: #0391fd;
  color: white;
  border-radius: 6px;
}

.tooltip:before { display: block; content: ''; position: absolute; top: 100%; left: 50%; width: 0; height: 0; border-left: 6px solid transparent; border-right: 6px solid transparent; border-top: 6px solid #0391fd; transform: translateX(-50%); }

<div class="tooltip">Текст</div>

Как сделать прозрачные вырезы?

Уточнение: в Tooltip должен вставляться текст. При этом тело Tooltip должно быть резиновым, т.е. размер Tooltip должен изменяться под текст внутри

Yuri
  • 15,957
  • 3
    svg. на чистом css такое можно сделать, но надо очень сильно любить градиенты и уметь ими пользоваться как джедай. – Andrei Fedorov May 13 '17 at 20:10

8 Answers8

28

SVG решение

В любом векторном редакторе, например: Inkscape, рисуем предложенный автором вопроса tooltip

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

Я сделал крупный рисунок, чтобы были видны узлы патча: всего их 15: 8 – закругленные углы прямоугольника, 6 контуры вырезов, 1 – вершина треугольника.

Далее делаю оптимизацию кода SVG с помощью SVGOMG

Ниже пример кода tooltip

<svg id="svg1" version="1.1" xmlns:svg="http://www.w3.org/2000/svg" xmlns="http://www.w3.org/2000/svg" 
 viewBox="0 0 240 240"   >
  <path d="m20 10c-5.5 0-10 4.5-10 10l0 50c0 5.5 4.5 10 10 10L41.4 80.2 37.3 75.7c-2.4-2.3 0.9-4 2-2.2L59.9 95.1 80.3 73.3c1.6-1.7 3.7 0.5 1.9 2.1L78 80.2 100 80c5.5 0 10-4.5 10-10l0-50c0-5.5-4.5-10-10-10z" style="fill:#0391FD;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:0.4;stroke:#0391fd"/>
  </svg>

Пример анимации tooltip

Интересные эффекты могут быть реализованы при плавной анимация перехода патча из одной формы в другую. Допустим из прямоугольника в данный tooltip Для этого используется анимация атрибута d="M20 ..". Указывается начальное значение и конечное.
Самое главное, чтобы количество узлов патча в начальном и конечном положении совпадало!

Для этого снова загружаем файл в Inkscape и перемещаем узлы, как показано на рисунке ниже: введите сюда описание изображения

Получаем новый патч с 15 узлами, но это уже прямоугольник

<svg version="1.1" xmlns:svg="http://www.w3.org/2000/svg" xmlns="http://www.w3.org/2000/svg" 
 viewBox="0 0 240 240"  >

<path d="m20 10c-5.5 0-10 4.5-10 10l0 50c0 5.5 4.5 10 10 10l21.4 0.2-0.1-0.1c4.2 0.1 11.3 0.1 11.3 0.1l7.7 0 8.9 0c16.6 0 7.2-2 5.5-0.3L78 80.2 100 80c5.5 0 10-4.5 10-10l0-50c0-5.5-4.5-10-10-10z" style="fill:#0391FD;stroke-linecap:round;stroke-linejoin:round;"/> </svg>

Далее добавляем команду анимации атрибута d

 <animate id="an_path" attributeName="d"  values="m20 10c-5.5 0-10   

body {
  background: url('http://badumka.ru/images/1523569_krasochnaya-priroda.jpg') no-repeat;
  background-size: cover;
  height: 100%;
  width: 100%;
  overflow: hidden;
}

.bdiv { display: table; }

.container { position: relative; width: 500px; margin: 0 auto; }

<div class="bdiv">
  <div class="container">
    <svg id="svg1" version="1.1" xmlns:svg="http://www.w3.org/2000/svg" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 240 240">
      <g transform="scale(0.8)">
        <path d="m20 10c-5.5 0-10 4.5-10 10l0 50c0 5.5 4.5 10 10 10l21.4 0.2-0.1-0.1c4.2 0.1 11.3 0.1 11.3 0.1l7.7 0 8.9 0c16.6 0 7.2-2 5.5-0.3L78 80.2 100 80c5.5 0 10-4.5 10-10l0-50c0-5.5-4.5-10-10-10z" style="fill:dodgerblue;stroke-linecap:round;stroke-linejoin:round; fill-opacity:0.5">
          <animate id="an_path"
          attributeName="d"
          values="m20 10c-5.5 0-10 4.5-10 10l0 50c0 5.5 4.5 10 10 10l21.4 0.2-0.1-0.1c4.2 0.1 11.3 0.1 11.3 0.1l7.7 0 8.9 0c16.6 0 7.2-2 5.5-0.3L78 80.2 100 80c5.5 0 10-4.5 10-10l0-50c0-5.5-4.5-10-10-10z;
      m20 10c-5.5 0-10 4.5-10 10l0 50c0 5.5 4.5 10 10 10L41.4 80.2 37.3 75.7c-2.4-2.3 0.9-4 2-2.2L59.9 95.1 80.3 73.3c1.6-1.7 3.7 0.5 1.9 2.1L78 80.2 100 80c5.5 0 10-4.5 10-10l0-50c0-5.5-4.5-10-10-10z;m20 10c-5.5 0-10 4.5-10 10l0 50c0 5.5 4.5 10 10 10l21.4 0.2-0.1-0.1c4.2 0.1 11.3 0.1 11.3 0.1l7.7 0 8.9 0c16.6 0 7.2-2 5.5-0.3L78 80.2 100 80c5.5 0 10-4.5 10-10l0-50c0-5.5-4.5-10-10-10z;
      m20 10c-5.5 0-10 4.5-10 10l0 50c0 5.5 4.5 10 10 10L41.4 80.2 37.3 75.7c-2.4-2.3 0.9-4 2-2.2L59.9 95.1 80.3 73.3c1.6-1.7 3.7 0.5 1.9 2.1L78 80.2 100 80c5.5 0 10-4.5 10-10l0-50c0-5.5-4.5-10-10-10z"
          begin="svg1.click"
          dur="8s"
          repeatCount="1"
          fill="freeze"
          restart="whenNotActive">
          </animate>
        </path>
        <text x="30" y="50" font-size="18" fill="white">click me </text>
      </g>
    </svg>
  </div>
</div>
Alexandr_TT
  • 110,146
  • 23
  • 114
  • 384
  • 1
    как-то мыльно выглядит, похоже это из цвета бордера, вернее из-за opacity Для stroke – Grundy May 16 '17 at 19:56
  • @Grundy посмотри, пожалуйста, может еще чего найдешь – Alexandr_TT May 16 '17 at 20:24
  • Интересное решение, но оно имеет большой минус - тултип не сможет нормально растягиваться по ширине... – MihailPw May 17 '17 at 05:54
  • @AGS17 Спасибо. Замечу лишь, что это решение SVG и, как следует из матчасти - масштабируемой векторной графики - изображение может быть растянуто отдельно по горизонтали или по вертикали или по обоим направлениям сразу при изменении атрибутов viewport и viewBox – Alexandr_TT May 17 '17 at 07:01
  • 2
    @Alexandr_T я про то, что по идее эта стрелка будет на столько же процентов растянута, на сколько будет растянут прямоугольник. Позиция узлов стрелки не изменяется же при изменении размера прямоугольника – MihailPw May 17 '17 at 07:08
  • @AGS17 наконец понял вас, вы имеете ввиду этот конкретный пример анимации, а я имел ввиду статичную фигуру tooltip, которая выше. – Alexandr_TT May 17 '17 at 07:28
  • @Alexandr_T А можете сделать чтобы можно было сделать вашу svg просто фоном через свойство background-image для произвольного блока div (только без text и т.д. внутри svg)? У меня, допустим только вот что получилось. – Vadim Ovchinnikov Jun 12 '17 at 08:29
  • @VadimOvchinnikov через неделю попытаюсь, сейчас нахожусь в командировке – Alexandr_TT Jun 13 '17 at 05:49
  • @Alexandr_T Уже можете попробовать? Просто было бы очень любопытно запихнуть эту svg в стили, которые можно было бы переиспользовать, и желательно без значительных изменений. – Vadim Ovchinnikov Jun 23 '17 at 06:05
  • @VadimOvchinnikov попробую, в любом случае дам ответ – Alexandr_TT Jun 25 '17 at 12:32
  • @VadimOvchinnikov Если я Вас правильно понял, то вы хотите взять код svg тултипа и через background: добавить в стили к какому-то классу, а затем присваивая этот класс разным блокам реализовать, тем самым многократное использование тултипа. Но такое решение подразумевает, что тултипы будут абсолютно одинаковы по форме, по цвету, по позиционированию, что протворечит самому предназначению тултипа - нести поясняющую информацию и указывать на объект, к которой она относится. Я не сторонник добавлять svg на вебстраничку через бэкграунд из-за некоторых ограничений этого способа. – Alexandr_TT Jun 25 '17 at 17:18
  • @VadimOvchinnikov лучше один раз добавить svg картинку в проект посредством <object>,а затем многократно использовать через <use> при этом можно применять стили из внешней таблицы CSS , позиционировать толтип, изменять его размеры – Alexandr_TT Jun 25 '17 at 17:23
  • @Alexandr_T Это круто, спасибо за мысли, а можете ответ дополнить как именно это сделать, с примерами? Я думаю это многим будет полезно, например, мне:-). – Vadim Ovchinnikov Jun 25 '17 at 18:14
  • @VadimOvchinnikov вот готовый пример - https://ru.stackoverflow.com/a/667483/28748 Как настраивать, позиционировать очень подробно в описании ниже примера. CSS - можно вынести в отдельную таблицу, svg правда добавлен инлайн, но его можно вынести в отдельный файл svg и добавить через , как это сделать здесь - https://svg-art.ru/?page_id=1047 Показать здесь пример загрузки через object не cмогу, так как сниппет накладывает ограничения безопасности по загрузке внешних файлов. Пример с различными тутипами адаптивен, попробуйте менять размер окна браузера. – Alexandr_TT Jun 25 '17 at 18:43
  • 1
17

Градиенты + псевдоэлементы + 1 вложенный элемент.

body {
  background-image: linear-gradient(to right, white, rebeccapurple);
  display: flex;
  flex-direction: column;
  min-height: 100vh;
}

.tooltip { position: relative; display: inline-block; border-radius: 10px; padding: 15px 25px 25px; color: #fff; font-size: 22px; background: linear-gradient(to bottom, #0391fd calc(100% - 10px), transparent calc(100% - 10px)), radial-gradient(circle at 50% 100%, transparent 24px, #0391fd 25px); margin: auto; }

.tooltip:before, .tooltip:after { position: absolute; content: ' '; bottom: 0; left: 0; width: 50%; height: 11px; border-bottom-left-radius: 10px; background-image: linear-gradient(45deg, #0391fd calc(100% - 18px), transparent calc(100% - 18px)); }

.tooltip:after { left: auto; right: 0; border-bottom-right-radius: 10px; background-image: linear-gradient(-45deg, #0391fd calc(100% - 18px), transparent calc(100% - 18px)); }

.tooltip__arrow { position: absolute; left: calc(50% - 21px); bottom: -10px; width: 0; height: 0; border-style: solid; border-width: 21px 21px 0 21px; border-color: #0391fd transparent transparent transparent; }

<div class=tooltip>Это какой-нибудь текст для примера
  <span class=tooltip__arrow></span>
</div>
<br>
<div class=tooltip>текст чуть поменьше
  <span class=tooltip__arrow></span>
</div>
15

Вариант №1 (новый)

создаём дополнительный элемент в DOM так как без него это реализовать на css не возможно , я применил свободное пространство имён

html,body{
height:100%; 
background:url(https://walldeco.ua/img/gallery/29/thumbs/thumb_l_2971.jpg);
background-size:cover;
}
a{
 padding:6px 10px;
 border:1px solid #fff;
 text-decoration:none;
 color:#fff;
 position:relative;
 top:50px; left:50px;
}
tooltipe{
 display:none;
 width:100%;
 height:100px;
 position:absolute;
 transform:translate(-100%,70px);
 overflow:hidden;
}
left{
 display:block;
 width:50%;
 height:100%;
 background:red;
 position:absolute;
 left:-33px;
 transform:skew(-21deg);
}
right{
 display:block;
 width:50%;
 height:100%;
 background:red;
 position:absolute;
 right:-33px;
 transform:skew(21deg);
}

right:after{ content:""; position:absolute; display:block; width:200px; height:80px; background:red; left:-90%; top:20px; transform:skew(-21deg); }

a.tool:hover:after{ content:""; display:block; position:absolute; border:18px solid transparent; border-bottom:50px solid red; left:41.5%; top:40px; } a:hover tooltipe{ display:inline-block; } tooltext{ display:block; position:absolute; left:0; padding:15px; }

<a href="" class="tool">
  <span>Это текст на которыйнадо  сделать подсказку</span>
  <tooltipe>
    <left></left>
    <right></right>

   <tooltext> 
     <p> Cras ultricies ligula sed magna dictum porta. Donec rutrum congue leo eget malesuada. Nulla porttitor accumsan tincidunt.</p>
  </tooltext>
  </tooltipe>
</a>

Вариант не очень (требуется доработать) №2

* {
  margin: 0;
  padding: 0;
  font-size: 20px;
  letter-spacing: 2px;
}

html, body { padding: 10px; }

span.tooltipe { background-color: #ccc; padding: 0 10px; border-radius: 4px; position: relative; z-index: 100; color: #fefefe; }

span.tooltipe a { text-decoration: none; color: #fefefe; display: inline-block; }

.tool { position: absolute; display: inline-block; width: 328px; height: 0; border: 1px solid #ccc; top: 80px; left: 0; padding: 20px; padding-top: 50px; background: transparent; }

.overlay { display: block; background: #000; padding: 10px; width: 350px; position: relative; z-index: 100; left: -20px; text-align: center; }

.tool cover { position: absolute; width: 100%; height: 70px; top: 0; left: 0; z-index: -1; background: rgba(0, 0, 0, .4); }

.tool:after { content: ""; position: absolute; border-width: 70px 140px 0px 0; border-style: solid; border-color: #000 transparent; top: 0; left: 0; z-index: 10; }

.tool:before { content: ""; position: absolute; border-width: 0 140px 70px 0; border-style: solid; border-color: transparent #000; top: 0; z-index: 10; right: 0; }

cover:after { content: ""; display: block; position: absolute; top: 0; left: 4%; border: 170px solid transparent; border-bottom: 70px solid #000; border-top: 0px solid #000; z-index: 210; }

cover:before { content: " v "; display: block; color: red; position: absolute; top: -15px; left: 44%; transform: rotate(180deg)scaleX(12)scaleY(3); color: transparent; text-shadow: 0 0 1px rgba(0, 0, 0, .7); }

.tool, .overlay, cover { display: none; }

span.tooltipe:hover .tool, .overlay, cover { display: block; }

<p>Curabitur aliquet quam id dui posuere blandit. Nulla porttitor accumsan tincidunt. Mauris blandit aliquet elit, eget tincidunt

  <span class="tooltipe"><a href=""> Curabitur arcu pretium ut lacinia in</a>
  <span class="tool"><cover></cover><span class="overlay">Quisque velit nisi, , elementum id enim. Curabitur aliquet quam id dui posuere blandit. Donec rutrum congue leo eget malesuada. Sed porttitor lectus nibh. Nulla porttitor accumsan tincidunt. Mauris blandit aliquet elit, eget tincidunt nibh pulvinar a. Proin eget tortor risus. Proin eget tortor risus. Curabitur aliquet quam id dui posuere blandit. Nulla porttitor accumsan tincidunt.</span>
  <!--overlay-->
  </span>
  </span>

  nibh pulvinar a. erat, accumsan id imperdiet et, porttitor at sem.Vivamus suscipit tortor eget felis porttitor volutpat. Mauris blandit aliquet elit, eget tincidunt nibh pulvinar a. Cras ultricies ligula sed magna dictum porta.
</p>

Вариант №3 (уже видели его)

* {
  margin: 0;
  padding: 0;
  text-decoration: none;
  box-sizing: border-box;
}

a { display: inline-block; padding: 10px 20px; border: 1px solid #ccc; position: relative; font-size: 20px; color: #ccc; }

a:hover { background-color: #ccc; color: #fefefe; }

a[tooltipe]:hover:after { content: attr(tooltipe); display: inline-block; white-space: pre; position: absolute; top: 60px; left: 50%; color: #fefefe; cursor: default; pointer-events: none; border: 3px solid #fefefe; padding: 10px 20px; background: #cc0000; }

a[tooltipe]:hover:before { content: ""; display: inline-block; position: absolute; top: 53px; left: 80%; color: #cc0000; background-image: linear-gradient(to bottom right, #cc0000, #cc0000, #cc0000); cursor: default; pointer-events: none; border: 4px solid #fefefe; background: ; width: 20px; height: 20px; z-index: 1; transform: rotate(45deg); border-bottom: transparent; border-right: transparent; }

<a href="" tooltipe="Это подсказка"> 
      Некий понт на css
    </a>

Вариант №4 не адаптивный :к сожалению по ссылке смотреть

14

CSS решение

Это можно реализовать обычной версткой. Без дополнительной графики, кроссбраузерно.

.back {
  width: 850px;
  height: 640px;
  background: url(http://orig09.deviantart.net/5063/f/2012/219/c/4/inari_fox__ivory_by_santani-d5a465m.jpg);
}

.tooltip { min-width: 50px; max-width: 300px;

/* Стили ниже только для демонстрации. Можно удалить. */ display: inline-block; vertical-align: top; margin: 10px; }

.tooltip .content { border-radius: 10px 10px 0 0; background: #3f51b5; padding: 10px; color: #fff; }

.tooltip .footer { position: relative; display: flex; }

.tooltip .footer .left { flex: 1 1 auto; position: relative; border-bottom: 10px solid #3f51b5; border-right: 10px solid transparent; border-bottom-left-radius: 10px; }

.tooltip .footer .circle { position: absolute; top: -1px; width: 3px; height: 3px; border-radius: 50%; border-top: 1px solid #3f51b5; }

.tooltip .footer .circle:after { content: ''; position: absolute; width: 0; height: 0; }

.tooltip .footer .left .circle { right: -5px; border-left: 1px solid #3f51b5; }

.tooltip .footer .left .circle:after { top: -3px; left: -3px; border-right: 3px solid #3f51b5; border-top: 2px solid transparent; border-bottom: 3px solid transparent; transform: rotate(45deg); }

.tooltip .footer .right { flex: 1 1 auto; position: relative; border-bottom: 10px solid #3f51b5; border-left: 10px solid transparent; border-bottom-right-radius: 10px; }

.tooltip .footer .right .circle { left: -5px; border-right: 1px solid #3f51b5; }

.tooltip .footer .right .circle:after { top: -3px; right: -3px; border-left: 3px solid #3f51b5; border-top: 3px solid transparent; border-bottom: 2px solid transparent; transform: rotate(-45deg); }

.tooltip .footer .center { flex: 0 0 28px; position: relative; }

.tooltip .footer .center:after { content: ''; position: absolute; left: -6px; width: 0; height: 0; border-left: 20px solid transparent; border-top: 20px solid #3f51b5; border-right: 20px solid transparent; }

<div class="back">
    <div class="tooltip">
        <div class="content">
            Lorem ipsum
        </div>
        <div class="footer">
            <div class="left"><div class="circle"></div></div>
            <div class="center"></div>
            <div class="right"><div class="circle"></div></div>
        </div>
    </div>

    <div class="tooltip">
        <div class="content">
            Lorem ipsum dolor sit amet
        </div>
        <div class="footer">
            <div class="left"><div class="circle"></div></div>
            <div class="center"></div>
            <div class="right"><div class="circle"></div></div>
        </div>
    </div>

    <div class="tooltip">
        <div class="content">
            Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vestibulum eu mauris ut nisl pretium sollicitudin.
        </div>
        <div class="footer">
            <div class="left"><div class="circle"></div></div>
            <div class="center"></div>
            <div class="right"><div class="circle"></div></div>
        </div>
    </div>

    <div class="tooltip">
        <div class="content">
            Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vestibulum eu mauris ut nisl pretium sollicitudin. Cras laoreet accumsan eros vitae ultrices. Cras sit amet iaculis quam. Nullam bibendum lorem quis viverra euismod. Ut sagittis nec nisl sodales euismod. Vivamus eget ornare augue. Morbi ultricies at augue eget vestibulum. Nullam a dapibus libero, fermentum pretium leo. Cras ac sagittis ex, in mattis ante. Sed lobortis vehicula orci, pulvinar pulvinar orci consectetur eu. Sed accumsan, lorem ut lacinia tempus, tortor tellus venenatis nisi, a tincidunt quam nibh commodo erat. Vestibulum posuere, risus eu efficitur interdum, orci diam molestie est, id sodales neque mi nec ipsum. Donec consectetur sit amet ligula quis gravida. Nunc in finibus nisi. Morbi at neque mi.
        </div>
        <div class="footer">
            <div class="left"><div class="circle"></div></div>
            <div class="center"></div>
            <div class="right"><div class="circle"></div></div>
        </div>
    </div>
</div>

В данном примере используется flex-box в футере. Если очень нужно поддерживать IE <= 9, можно заменить на классический аналог.

  • Мои поздравления :) – Yuri May 23 '17 at 14:39
  • @Yuri мой 4 вариант тоже самое –  May 26 '17 at 07:23
  • Если вы про Вариант №1 (новый), то мой отличается версткой и, самое главное, он резиновый, что является условием данного компонента. – Roman Maksimov May 26 '17 at 10:57
11

Режем низ на три части и с помощью православного calc наводим порядок:

body {
  background: radial-gradient(circle at 0% 50%, rgba(96, 16, 48, 0) 9px, #613 10px, rgba(96, 16, 48, 0) 11px) 0px 10px, radial-gradient(at 100% 100%, rgba(96, 16, 48, 0) 9px, #613 10px, rgba(96, 16, 48, 0) 11px), #8a3;
  background-size: 20px 20px;
}

.tooltip { margin: 50px; }

.tooltip-top { background: #0391fd; color: #FFF; text-align: center; border-radius: 10px 10px 0 0; padding: 10px 5px; font-family: Verdana, sans-serif; }

.tooltip-bottom { height: 15px; overflow: visible; }

.tooltip-bottom-left { background: #0391fd; float: left; width: calc(50% - 30px); height: 15px; border-radius: 0 0 0 10px; }

.tooltip-bottom-center { float: left; background: url('https://i.stack.imgur.com/Nw7uL.png'); width: 60px; height: 41px; background-size: 60px 41px; }

.tooltip-bottom-right { background: #0391fd; float: left; width: calc(50% - 30px); height: 15px; border-radius: 0 0 10px 0; }

<div class="tooltip" style="width:100px">
  <div class="tooltip-top">Тултипчик</div>
  <div class="tooltip-bottom">
    <div class="tooltip-bottom-left"></div>
    <div class="tooltip-bottom-center"></div>
    <div class="tooltip-bottom-right"></div>
  </div>
</div>
<div class="tooltip" style="width:200px">
  <div class="tooltip-top">Тултип</div>
  <div class="tooltip-bottom">
    <div class="tooltip-bottom-left"></div>
    <div class="tooltip-bottom-center"></div>
    <div class="tooltip-bottom-right"></div>
  </div>
</div>
<div class="tooltip" style="width:400px">
  <div class="tooltip-top">Тултипище<br />c тултипом-женой<br />и тултипятами</div>
  <div class="tooltip-bottom">
    <div class="tooltip-bottom-left"></div>
    <div class="tooltip-bottom-center"></div>
    <div class="tooltip-bottom-right"></div>
  </div>
</div>

Сорян за косо обрезанную картинку.

br3t
  • 4,379
  • Я так и подумал, что решить можно. Думал, что может есть вариант легче :) – Yuri May 17 '17 at 07:09
11

Магия clip-path и 6 вложенных элементов.

*, *:before, *:after {
  box-sizing: border-box;
}

html { height: 100vh; background-image: linear-gradient(to right, #ecdff9, #af7fe0); background-size: 100% 100%; }

body { height: 100%; margin: 0 10px; }

.tooltip { position: relative; display: inline-block; margin: 10px auto; }

.tooltip__block { display: block; font-size: 28px; color: #fff; font-family: Arial; background-color: #0391fd; padding: 20px 35px 50px; width: 100%; height: 100%; border-radius: 15px; clip-path: polygon(0 0, 100% 0, 100% 100%, calc(50% + 90px) 100%, calc(50% + 90px) calc(100% - 30px), calc(50% - 90px) calc(100% - 30px), calc(50% - 90px) 100%, 0 100%); }

.tooltip__arrow { position: absolute; left: calc(50% - 85px); top: calc(100% - 30px); height: 60px; width: 170px; background-color: #0391fd; clip-path: polygon(0 0, 100% 0, 50% 100%); }

.tooltip__circle { display: block; position: absolute; top: calc(100% - 30px); width: 7px; background-image: radial-gradient(circle, transparent 40%, #0391fd 60%); }

.tooltip__circle:before { float: left; content: ''; padding-top: 100%; }

.tooltip__circle--left { left: calc(50% - 91px); clip-path: polygon(0 0, 50% 0, 50% 50%, 0 50%); }

.tooltip__circle--right { right: calc(50% - 91px); clip-path: polygon(50% 0, 50% 50%, 100% 50%, 100% 0); }

.tooltip__triangle { width: 36px; background-color: #0391fd; position: absolute; bottom: 0; }

.tooltip__triangle:before { float: left; padding-top: 72%; content: ''; }

.tooltip__triangle--left { left: calc(50% - 91px); clip-path: polygon(0 0, 100% 100%, 0 100%); }

.tooltip__triangle--right { right: calc(50% - 91px); clip-path: polygon(100% 0, 100% 100%, 0 100%); }

<div class=tooltip>
  <span class=tooltip__block>Текст в тултипе</span>
  <span class=tooltip__arrow></span>
  <span class="tooltip__circle tooltip__circle--left"></span>
  <span class="tooltip__circle tooltip__circle--right"></span>
  <span class="tooltip__triangle tooltip__triangle--left"></span>
  <span class="tooltip__triangle tooltip__triangle--right"></span>
</div>
<br>
<br>
<br>
<div class=tooltip>
  <span class=tooltip__block>Чертовски длинный текст в тултипе, чтобы показать, что блок тянется</span>
  <span class=tooltip__arrow></span>
  <span class="tooltip__circle tooltip__circle--left"></span>
  <span class="tooltip__circle tooltip__circle--right"></span>
  <span class="tooltip__triangle tooltip__triangle--left"></span>
  <span class="tooltip__triangle tooltip__triangle--right"></span>
</div>
  • там есть нюансы, вроде как не везде работает calc() внутри clip-path, ну и clip-path не везде работает, это не секрет ) – Sasha Omelchenko May 19 '17 at 09:07
10

Первый мой ответ был опубликован до объявления конкурса и не совсем выполнял его условия. Поэтому публикую новый ответ.
Если я правильно понял задачу, то необходимо было выполнить следующие условия:

  1. Вёрстка должна быть полностью адаптивна
  2. Вырезы на тултипе должны быть прозрачны

  3. Тултип должен растягиваться по горизонтали в зависимости от длины текста в тултипе и по вертикали (желательно), если строчек больше одной.

Пример ниже полностью адаптивен: блоки, тултипы, текст.

Проверена работоспособность в IE11, Firefox, Chrome, Opera

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8" />
<title>Вывод Tooltip</title>  
<style>

.square { float:left; position: relative; width: 30%; padding-bottom : 30%; margin:1.66%; background-position:center center; background-repeat:no-repeat; background-size:cover; }

.img_1-1{background-image:url('https://i.stack.imgur.com/S8q6Z.jpg');} .img_1-2{background-image:url('https://i.stack.imgur.com/Ox8J2.jpg');} .img_1-3{background-image:url('https://i.stack.imgur.com/zdZU0.jpg');}

svg path { fill:inherit; } #svg1 { fill:yellow; } .container { width:80%; height:auto; margin:0px; padding:0px; position:relative; clear:both; } </style> </head>

<body> <div class="square img_1-1"> <div class="container"> <svg id="svg1" version="1.1" xmlns:svg="http://www.w3.org/2000/svg" xmlns="http://www.w3.org/2000/svg" viewBox="-100 -100 480 240" >

<g transform="scale(1.4 1.2)"> <use xlink:href="#tooltip" x="0%" y="3%" fill="yellow" opacity="0.9" > </use> <text font-size="24" x="30" y="57" fill="dodgerblue">Морж</text> </g>

</svg> </div> </div> <div class="square img_1-2"> <div class="container"> <svg id="svg1" version="1.1" xmlns:svg="http://www.w3.org/2000/svg" xmlns="http://www.w3.org/2000/svg" viewBox="5 0 240 240" >

<g transform="scale(2.2 0.75)"> <use xlink:href="#tooltip" x="0%" y="3%" fill="dodgerblue" opacity="0.8" > </use>

</g> <text font-size="16" font-family="serif" x="45" y="45" fill="white">Харьковский дельфинарий</text> </svg> </div> </div> <div class="square img_1-3">
<div class="container"> <svg id="svg1" version="1.1" xmlns:svg="http://www.w3.org/2000/svg" xmlns="http://www.w3.org/2000/svg" viewBox="-60 -45 240 240" > <g transform="scale(1.5 1.5)"> <use xlink:href="#tooltip" x="3%" y="3%" fill="crimson" opacity="0.6" > </use> <text font-size="16" x="30" y="40" fill="white">Дельфины <tspan dx="-45" dy="20"> и </tspan> <tspan dx="-20" dy="15"> мяч</tspan> </text> </g> </svg> </div> </div>

<div class="container"> <svg id="svg1" version="1.1" xmlns:svg="http://www.w3.org/2000/svg" xmlns="http://www.w3.org/2000/svg" width="100%" height="100%" viewBox="-100 -100 480 240"> <defs> <g id="tooltip" transform="scale(1 1)"> <path d="m20 10c-5.5 0-10 4.5-10 10l0 50c0 5.5 4.5 10 10 10L41.4 80.2 37.3 75.7c-2.4-2.3 0.9-4 2-2.2L59.9 95.1 80.3 73.3c1.6-1.7 3.7 0.5 1.9 2.1L78 80.2 100 80c5.5 0 10-4.5 10-10l0-50c0-5.5-4.5-10-10-10z" style="stroke-linecap:round;stroke-linejoin:round; "/> </g>
</defs>

</svg> </div>

</body> </html>

Масштабирование тултипа осуществляется командой - transform="scale(2.2 0.75)", где первая цифра это увеличение по горизонтали, вторая уменьшение высоты. Это пример для однострочного тултипа на второй картинке (Харьковский дельфинарий)

Важный атрибут viewBox выполняет сразу несколько задач:

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

Обязательным условием для выполнения этого является,- либо отсутствие viewport в шапке svg файла, либо задание высоты и ширины окна просмотра браузера в процентах.
Если не указан viewport то значения по умолчанию - width="100%" и height="100%" от размеров окна браузера.

Параметры viewBox="5 0 240 240" (не путать с viewport)

Первые две цифры отвечают за смещение svg изображения по осям X, Y
3,4 цифры отвечают за масштабирование изображения внутри viewport
При изменении этих параметров необходимо помнить, что:

У viewBox всё наоборот.

Поэтому, если вправо перемещаем viewBox - min-x > 0, то изображение сдвигается влево. Подробнее тут и тут.
Если увеличиваем viewBox, то изображение уменьшается. Это всё применяется для позиционирования и масштабирования тултипа.

Клонирование тултипа

Для этого применяется команда use

<use xlink:href="#tooltip"  x="0%" y="3%" fill="dodgerblue" opacity="0.8" > </use>  

Как видно в этой команде делается дополнительной позиционирование тултипа по вертикали и горизонтали.
Цифры только в процентах, иначе svg не будет масштабироваться!

Чтобы осуществить стилизацию клонов тултипа из внутренней или из внешней таблицы стилей необходимо применить принудительное наследование

svg path 
{
fill:inherit;    
}    

А в самом path заполнение fill обязательно удалить!

Перенос текста

В SVG нет автоматического переноса текста, как в html
Поэтому приходится использовать тег <tspan>

<text font-size="16" x="30" y="40" fill="white">Дельфины
 <tspan dx="-45" dy="20"> и </tspan>
 <tspan dx="-20" dy="15"> мяч</tspan>
 </text>    

Но думаю это не критично, так как размещение и заполнение тултипа делается при вёрстке Html.

Alexandr_TT
  • 110,146
  • 23
  • 114
  • 384
7

Думаю это белые полосы, наложенные поверх

.tooltip:before {
  display: block;
  content: '';
  position: absolute;
  top: 10%;
  left: 50%;
  width: 2px;
  height:  14px;
  background-color: #fff;
  border-radius: 1px 1px 1px 1px;
  transform: rotate(45deg);
  z-index: 1;
}

.tooltip:after {
  display: block;
  content: '';
  position: absolute;
  top: 10%;
  left: 36%;
  width: 2px;
  height:  14px;
  background-color: #fff;
  border-radius: 1px 1px 1px 1px;
  transform: rotate(-45deg);
  z-index: 1;
}

Попробуй так сделать, а треугольник можешь добавить через div, так как before и after заняты.

Yuri
  • 15,957
  • Идея хорошая, но мне нужно, чтобы полосы были прозрачные (т.е. был виден задний фон через них), а не белые – Yuri May 14 '17 at 09:00
  • В таком случае я бы сделал .png в фотошопе) – Кулага Илья May 15 '17 at 08:34
  • 3
    Да и с PNG проблема. Размер должен быть резиновым. А если нарисовать всё тело картинкой, то размер Tooltip будет фиксированной :) – Yuri May 15 '17 at 09:24