8

Помогите разобраться, как сделано сердце с отступом вокруг него. Как получить такую же изогнутую линию? Это возможно с помощью CSS, HTML?

Я знаю, как добавить сердце с помощью CSS или картинки, но как добиться изогнутой границы вокруг него?

Похоже, border-radius здесь не поможет...

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

Перевод вопроса: Line with indented circle @hermann

Alexandr_TT
  • 110,146
  • 23
  • 114
  • 384

3 Answers3

5

Конечно же, border-radius поможет. Но придётся подбирать размеры вложенных блоков и согласовывать толщину границ с толщиной линий в иконках.

CSS

  1. Круг помещаем псевдоэлементом в блок с overflow:hidden;. Получаем дугу.

  2. Сердечко берём из Font Awesome. Чтобы задать иконку через стили, создаём ещё один блок с псевдоэлементом. Если бы сердечко не выступало за нижнюю границу дуги и ему не грозил бы добавленный нами overflow:hidden;, то мы поместили бы оба пседоэлемента в один блок.

  3. Позиционируем собранный блок поверх картинки с нижней рыжей границей. Даём отрицательный bottom, чтобы опуститься на ширину границы.

https://codepen.io/glebkema/pen/MoyXxp

.arch {
  overflow: hidden;
  position: absolute; top: 0; left: 0;
  width: 100%; height: 100%;
}
.arch:before {
  background: white;
  border: solid 3px orange;
  border-radius: 50%;
  box-sizing: border-box;
  content: '';
  display: block;
  position: absolute; top: 0; left: 0;
  width: 100%; height: 133.333333%;
}

.heart { position: absolute; bottom: -3px; right: 60px; width: 48px; height: 36px; } .heart:after { color: orange; content: '\f08a'; /* http://fontawesome.io/icon/heart-o/ */ display: block; font-family: 'FontAwesome'; font-size: 28px; font-weight: bold; line-height: 1; position: absolute; bottom: -4px; left: 0; text-align: center; width: 100%; }

.photo { background: #9cf; border-bottom: solid 3px orange; height: 120px; position: relative; }

<div class="photo"><div class="heart"><div class="arch"></div></div></div>

<link rel="stylesheet" href="//maxcdn.bootstrapcdn.com/font-awesome/4.7.0/css/font-awesome.min.css">
3

Вот идея о том, как вы можете реализовать этот макет с помощью inline svg.

SVG :

  • Первый path - это круговая линия с отступом. Вырезанная окружность создается с помощью команды дуги (arc)
  • Второй элемент path - это само сердце. Патч использует команду кривой Безье для верхней части сердца.

img {
  width: 100%;
  display: block;
}
div {
  position: relative;
  height: 100px;
  background: #fff;
}
svg {
  position: absolute;
  bottom: 100%;
  width: 100%;
}
<img src="http://lorempixel.com/640/200" alt="">
<div>
  <svg viewbox="0 0 100 18.4">
    <path stroke="orange" stroke-width="0.8" fill="#fff" d="M-1 21 V18 H79.5 A7 7 0 1 1 90.5 18 H101 V21" />
    <path stroke="orange" stroke-width="0.8" fill="#fff" d="M85 18 L81 13 C80 10 85 10 85 12 C85 10 90 10 89 13z " />
  </svg>
</div>

Дополнительные сведения о командах path в SVG см. тут и тут.


Перевод ответа @web-tiki.

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

SVG + Анимация

Три последовательных анимации:

  1. Рисование изогнутой линии вокруг сердца
  2. Рисование контура сердца
  3. Заполнение цветом

Первые две анимации реализованы с помощью изменения атрибута патча stroke-dashoffset от максимального значения до нуля, тем самым реализован эффект рисования линии.

Для точного вычисления длины пути линии и контура сердца применяем команду JS getTotalLength()

<!DOCTYPE html>
<head>
  <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
</head>
  <input  type="button" value="Total"  onclick="TotalLength()"/>

<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:ev="http://www.w3.org/2001/xml-events" width="100%" height="100%" >

     &lt;path id="check" fill= "none" stroke ="grey" stroke-width ="1" 
    d="M-1 21 V18 H79.5 A7 7 0 1 1 90.5 18 H101 V21" /&gt; 

</svg> <script> function TotalLength(){ var path = document.querySelector('#check'); var len = Math.round(path.getTotalLength() ); alert("Длина пути - " + len); }; </script> </html>

Для изогнутой линии длина получилась равной 128px Для контура сердца =26px

Подставляем эти значения в анимацию атрибута stroke-dashoffset.

Начало анимации - click по треугольнику в правом нижнем углу

img {
  width: 100%;
  display: block;
}
div {
  position: relative;
  height: 100px;
  background: #fff;
}
svg {
  position: absolute;
  bottom: 100%;
  width: 100%;
<img src="http://lorempixel.com/640/200" alt="">
<div>
   <svg id="svg1" version="1.1"  baseProfile="full" xmlns="http://www.w3.org/2000/svg" 
  xmlns:xlink="http://www.w3.org/1999/xlink"   viewBox="0 0 100 18.4">

<path stroke="orange" stroke-width="1" fill="#fff" stroke-dasharray="128" stroke-dashoffset="128" d="M-1 21 V18 H79.5 A7 7 0 1 1 90.5 18 H101 V21" > <animate id="an1" attributeName="stroke-dashoffset" values="128;0" begin="svg1.click" dur="4s" fill="freeze" restart="whenNotActive" /> </path>

<path stroke="crimson" stroke-width="1" fill="#fff" stroke-dasharray="26" stroke-dashoffset="26" d="M85 18 L81 13 C80 10 85 10 85 12 C85 10 90 10 89 13z" > <animate id="an2" attributeName="stroke-dashoffset" values="26;0" begin="an1.end" dur="2s" fill="freeze" restart="whenNotActive"/> <animate attributeName="fill" values="white; crimson" begin="an2.end" dur="2s" fill="freeze" restart="whenNotActive"/> </path> <path stroke="orange" stroke-width="1" fill="orange" d="M83.5 17 L83.5 9 L89 13.5z " > <animate id="btn1" attributeName="opacity" values="1;0" dur="3s" begin="svg1.click" /> <set attributeName="visibility" to="hidden" begin="btn1.end"/> </path> </svg> </div>

Похожие темы:

Alexandr_TT
  • 110,146
  • 23
  • 114
  • 384