Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Line with indented circle

I would like to know how this heart with the indented circle around it is implemented. How can I make the curves go like this? Is it possible with CSS, HTML?

I know how to implement a heart with CSS or even an image, but the curved border is beyond my knowledge.

border-radius doesn't seem to be a solution in this case.

border with indented circle

like image 369
hermann Avatar asked May 28 '15 12:05

hermann


4 Answers

Here is an idea of how you can achieve this layout with an inline svg.

In the SVG :

  • The first path is the line with the indented circle. The indented circle is created with an arc command
  • The second path element is the heart outline. It uses the Bezier curve command for the top part of the heart.

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>

For more info on the path commands in SVG, see MDN

like image 192
web-tiki Avatar answered Nov 12 '22 07:11

web-tiki


You can use a pseudo-element:

$borderWidth: 3px;
$heartSize: 30px;
div {
  border-bottom: $borderWidth solid orange;
  position: relative;
}
div:after {
  content: '♡'; /* Heart character (U+2661) */
  font-size: 30px;
  height: $heartSize;
  width: $heartSize;
  line-height: $heartSize;
  text-align: center;
  position: absolute;
  bottom: -3*$borderWidth;
  right: 10%;
  border: $borderWidth solid orange;
  border-radius: 50%;
  background: #fff;
  clip: rect(0, $heartSize+2*$borderWidth, $heartSize, 0); /* Old syntax */
  clip-path: inset(0 0 2*$borderWidth 0); /* New syntax */
}

div {
  border-bottom: 3px solid orange;
  position: relative;
}
div:after {
  content: '♡'; /* Heart character (U+2661) */
  font-size: 30px;
  height: 30px;
  width: 30px;
  line-height: 30px;
  text-align: center;
  position: absolute;
  bottom: -9px;
  right: 15%;
  border: 3px solid orange;
  border-radius: 50%;
  background: #fff;
  clip: rect(0, 36px, 30px, 0);
  -webkit-clip-path: inset(0 0 6px 0); /* Old syntax */
  clip-path: inset(0 0 6px 0); /* New syntax */
}
<div>Foo<br />bar</div>
like image 6
Oriol Avatar answered Nov 12 '22 07:11

Oriol


So the best solution for your problem would be to use an SVG shape like this, or a custom font as you can modify the colour and they will scale well for retina etc.

Normally CSS3 is great for creating basic shapes, however when it comes to outline shapes it kind off falls over. This is because they normally rely on creating multiple shapes using before and after selectors. This normally works but if you want to apply a border it will cause overlapping issues with the shape.

The only real css solution would be to create a second heart shape slightly smaller as a mask. But this is allot of markup bloat so SVG really is your best option.

A quick and dirty example over and overlapping heart is here https://jsfiddle.net/6qywoxsk/

.heart {
    position: absolute;
    width: 100px;
    height: 90px;
}
.heartCon{
    position:relative;
}
.heart:before,
.heart:after {
    position: absolute;
    content: "";
    left: 50px;
    top: 0;
    width: 50px;
    height: 80px;
    background: red;
    -moz-border-radius: 50px 50px 0 0;
    border-radius: 50px 50px 0 0;
    -webkit-transform: rotate(-45deg);
       -moz-transform: rotate(-45deg);
        -ms-transform: rotate(-45deg);
         -o-transform: rotate(-45deg);
            transform: rotate(-45deg);
    -webkit-transform-origin: 0 100%;
       -moz-transform-origin: 0 100%;
        -ms-transform-origin: 0 100%;
         -o-transform-origin: 0 100%;
            transform-origin: 0 100%;
}
.heart:after {
    left: 0;
    -webkit-transform: rotate(45deg);
       -moz-transform: rotate(45deg);
        -ms-transform: rotate(45deg);
         -o-transform: rotate(45deg);
            transform: rotate(45deg);
    -webkit-transform-origin: 100% 100%;
       -moz-transform-origin: 100% 100%;
        -ms-transform-origin: 100% 100%;
         -o-transform-origin: 100% 100%;
            transform-origin :100% 100%;
}
.heart2{
     -ms-transform: scale(0.9); /* IE 9 */
    -webkit-transform: scale(0.9); /* Safari */
    transform: scale(0.9);
}
.heart2:before,
.heart2:after {
     background:#fff;   
     top: 0px;
}
<div class="heartCon">
  <div class="heart"></div>
  <div class="heart heart2"></div>
</div>
like image 5
Dominic Green Avatar answered Nov 12 '22 06:11

Dominic Green


The simplest, safest and cross-browser solution is to use an image.

The other ways: canvas, border-radius, transform or SVG.

like image 3
Mihey Egoroff Avatar answered Nov 12 '22 07:11

Mihey Egoroff