How do I create a shape like this to display on a webpage?
I don\'t want to use images since they would get blurry on scaling
As there are a fair few answers here I thought why not add to it with another method. This is using both HTML and CSS to create the teardrop.
This will allow you to change the colour of the border and background of the teardrop and also re-size the top part of it.
Using a single div
we can create a circle with border
and border-radius
. Then using pseudo elements (:before
& :after
) we create a CSS triangle more here, this will act as the tip of the teardrop. Using the :before
as the border we place :after
on top with a smaller size and the desired background colour.
div {
width: 100px;
height: 100px;
border-radius: 50%;
border: 4px solid;
margin: 80px auto;
position: relative;
}
div:before,
div:after {
content: "";
display: block;
position: absolute;
width: 0;
height: 0;
}
div:before {
border-left: 50px solid transparent;
border-right: 50px solid transparent;
border-bottom: 104px solid black;
top: -75px;
}
div:after {
border-left: 46px solid transparent;
border-right: 46px solid transparent;
border-bottom: 96px solid #fff;
top: -66px;
left: 0;
right: 0;
margin: auto;
z-index: 1;
}
<div></div>
Here is a demo of the teardrop with a background colour
div {
width: 100px;
height: 100px;
border-radius: 50%;
border: 4px solid;
background: red;
margin: 80px;
position: relative;
}
div:before,
div:after {
content: "";
display: block;
position: absolute;
width: 0;
height: 0;
}
div:before {
border-left: 50px solid transparent;
border-right: 50px solid transparent;
border-bottom: 100px solid black;
top: -70px;
}
div:after {
border-left: 46px solid transparent;
border-right: 46px solid transparent;
border-bottom: 96px solid red;
top: -66px;
left: 0;
right: 0;
margin: auto;
z-index: 1;
}
<div></div>
It is as simple as putting a background colour onto the div
and changing :after
bottom-border
colour to the same. To change the border you will need to change div
border colour and :before
background colour too.
Your main issue with your CSS code was:
So, by 'fixing' these issues, you would generate:
.tear {
display: inline-block;
transform: rotate(-45deg);
border: 5px solid green;
width: 100px;
height: 100px;
border-top-left-radius: 50%;
border-bottom-left-radius: 50%;
border-bottom-right-radius: 50%;
}
/***for demo only***/
.tear {
margin: 50px;
}
<div class="tear">
</div>
Please also note to save on CSS length, you could re-write your border-radius properties to:
border-radius: 50% 0 50% 50%;
this could be enhanced with pseudo elements as shown in this fiddle
I found this by Vinay Challuru on codepen.
Please note that with the logic here, I was able to create the SVG to nearly any possible build shape/etc. For example, a quick output was:
<svg viewBox='0 0 400 400'>
<path fill="none" stroke="#333" stroke-width="5" d="M200,40 C200,115 280,180 280,240 A80,80,0 0,1,120,240 C120,180 200,115 200,40" stroke-linejoin='miter'></path>
</svg>
It's using an SVG and allows you to alter the shape in multiple ways, having the ability to alter its shape to the desired result:
var SVG = function() {
this.element = document.getElementsByTagName("svg")[0];
this.namespace = "http://www.w3.org/2000/svg";
this.width = 400;
this.height = 400;
}
/****Let's initialise our SVG ready to draw our shape****/
var svg = new SVG();
/****This sets up the user interface - we've included the script for this as an external library for the codepen****/
var gui = new dat.GUI();
/****Here's where the code to create the shape begins!****/
var Teardrop = function() {
this.x = svg.width * 0.5;
this.y = svg.height * 0.1;
this.width = svg.width * 0.4;
this.triangleHeight = svg.height * 0.5;
this.yCP1 = svg.height * 0.2;
this.yCP2 = svg.height * 0.45;
this.element = null;
this.ctrlPoints = [];
this.anchors = [];
this.fill = "none";
this.stroke = "#333";
this.strokeWidth = 2;
this.showCtrlPoints = true;
this.init();
}
Teardrop.prototype.init = function() {
this.element = document.createElementNS(svg.namespace, "path");
svg.element.appendChild(this.element);
this.element.setAttribute("fill", this.fill);
this.element.setAttribute("stroke", this.stroke);
this.element.setAttribute("stroke-width", this.strokeWidth);
for (var i = 0; i < 3; i++) {
this.ctrlPoints.push(document.createElementNS(svg.namespace, "circle"));
svg.element.appendChild(this.ctrlPoints[i]);
this.ctrlPoints[i].setAttribute("fill", this.fill);
this.ctrlPoints[i].setAttribute("stroke", 'red');
this.ctrlPoints[i].setAttribute("stroke-width", 1);
this.anchors.push(document.createElementNS(svg.namespace, "line"));
svg.element.appendChild(this.anchors[i]);
this.anchors[i].setAttribute("stroke-width", 1);
this.anchors[i].setAttribute("stroke", this.stroke);
this.anchors[i].setAttribute("stroke-dasharray", "3,2");
}
this.draw();
}
Teardrop.prototype.draw = function() {
this.radius = this.width / 2;
path = [
"M", this.x, ",", this.y,
"C", this.x, ",", this.yCP1, " ", this.x + this.width / 2, ",", this.yCP2, " ", this.x + this.width / 2, ",", this.y + this.triangleHeight,
"A", this.radius, ",", this.radius, ",", "0 0,1,", this.x - this.width / 2, ",", this.y + this.triangleHeight,
"C", this.x - this.width / 2, ",", this.yCP2, " ", this.x, ",", this.yCP1, " ", this.x, ",", this.y
];
this.element.setAttribute("d", path.join(""));
cpCoords = [];
cpCoords[0] = [this.x, this.yCP1];
cpCoords[1] = [this.x - this.width / 2, this.yCP2];
cpCoords[2] = [this.x + this.width / 2, this.yCP2];
anchorCoords = [];
anchorCoords[0] = [this.x, this.y];
anchorCoords[1] = [this.x - this.width / 2, this.y + this.triangleHeight];
anchorCoords[2] = [this.x + this.width / 2, this.y + this.triangleHeight];
for (var i = 0; i < 3; i++) {
this.ctrlPoints[i].setAttribute("cx", cpCoords[i][0]);
this.ctrlPoints[i].setAttribute("cy", cpCoords[i][1]);
this.anchors[i].setAttribute("x1", cpCoords[i][0]);
this.anchors[i].setAttribute("x2", anchorCoords[i][0]);
this.anchors[i].setAttribute("y1", cpCoords[i][1]);
this.anchors[i].setAttribute("y2", anchorCoords[i][1]);
if (this.showCtrlPoints) {
this.ctrlPoints[i].setAttribute("r", 2);
this.anchors[i].setAttribute("stroke-width", 1);
} else {
this.ctrlPoints[i].setAttribute("r", 0);
this.anchors[i].setAttribute("stroke-width", 0);
}
}
}
var teardrop = new Teardrop();
gui.add(teardrop, 'triangleHeight', 0, svg.height * 0.75);
gui.add(teardrop, 'width', 0, 200);
gui.add(teardrop, 'yCP1', 0, svg.height);
gui.add(teardrop, 'yCP2', 0, svg.height);
gui.add(teardrop, 'showCtrlPoints', 0, svg.height);
for (var i in gui.__controllers) {
gui.__controllers[i].onChange(function() {
teardrop.draw();
});
}
html,
body {
height: 100%;
}
svg {
display: block;
margin: 0 auto;
background: url('http://unitedshapes.com/images/graph-paper/graph-paper.png');
}
<script src="//cdnjs.cloudflare.com/ajax/libs/dat-gui/0.5/dat.gui.min.js"></script>
<svg width='400px' height='400px'></svg>
Disclaimer I did not write the above pen, only sourced it.
Although this is far from complete, you may also be able to generate this shape using CSS.
.tear{
height:200px;
width:200px;
background: linear-gradient(to bottom, rgba(0,0,0,0) 0%,rgba(0,0,0,0) 29%,rgba(0,0,0,1) 30%,rgba(0,0,0,1) 100%);
border-radius:50%;
margin:120px;
position:relative;
}
.tear:before{
content:"";
position:absolute;
top:-70%;left:0%;
height:100%;width:50%;
background: radial-gradient(ellipse at -50% -50%, rgba(0,0,0,0) 0%,rgba(0,0,0,0) 75%,rgba(0,0,0,1) 76%,rgba(0,0,0,1) 100%);
}
.tear:after{
content:"";
position:absolute;
top:-70%;left:50%;
height:100%;width:50%;
background: radial-gradient(ellipse at 150% -50%, rgba(0,0,0,0) 0%,rgba(0,0,0,0) 75%,rgba(0,0,0,1) 76%,rgba(0,0,0,1) 100%);
}
<div class="tear"></div>
I should know that SVG should be at the top of this answer, however, I like a challenge and so here is an attempt with SVG.
svg {
height: 300px;
}
svg path {
fill: tomato;
}
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" viewBox="0 0 100 100">
<path d="M49.015,0.803
c-0.133-1.071-1.896-1.071-2.029,0
C42.57,36.344,20,43.666,20,68.367
C20,83.627,32.816,96,48,96
s28-12.373,28-27.633
C76,43.666,53.43,36.344,49.015,0.803z
M44.751,40.09
c-0.297,1.095-0.615,2.223-0.942,3.386
c-2.007,7.123-4.281,15.195-4.281,24.537
c0,5.055-2.988,6.854-5.784,6.854
c-3.189,0-5.782-2.616-5.782-5.831
c0-11.034,5.315-18.243,10.005-24.604
c1.469-1.991,2.855-3.873,3.983-5.749
c0.516-0.856,1.903-0.82,2.533,0.029
C44.781,39.116,44.879,39.619,44.751,40.09z"/>
</svg>
Altering the path
values, you would be able to alter the shape of your teardrop design.
It is quite easy to do this with SVG by just using an image conversion resource such as http://image.online-convert.com/convert-to-svg, which was used to create the following:
<?xml version="1.0" standalone="no"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 20010904//EN"
"http://www.w3.org/TR/2001/REC-SVG-20010904/DTD/svg10.dtd">
<svg version="1.0" xmlns="http://www.w3.org/2000/svg"
width="213.000000pt" height="300.000000pt" viewBox="0 0 213.000000 300.000000"
preserveAspectRatio="xMidYMid meet">
<metadata>
Created by potrace 1.12, written by Peter Selinger 2001-2015
</metadata>
<g transform="translate(0.000000,300.000000) scale(0.100000,-0.100000)"
fill="#000000" stroke="none">
<path d="M1035 2944 c-143 -250 -231 -380 -508 -752 -347 -465 -432 -616 -493
-882 -91 -394 10 -753 285 -1013 508 -479 1334 -361 1677 240 126 221 165 494
105 726 -66 254 -178 452 -609 1076 -96 140 -226 335 -288 435 -155 249 -135
229 -169 170z m85 -212 c40 -69 192 -298 543 -818 268 -396 354 -593 364 -835
12 -281 -82 -509 -296 -714 -103 -99 -236 -173 -396 -221 -82 -25 -105 -27
-260 -28 -148 -1 -181 2 -255 22 -348 96 -611 357 -691 689 -41 167 -25 392
41 587 62 185 154 334 444 716 177 235 320 444 402 592 27 49 51 88 54 88 3 0
25 -35 50 -78z"/>
</g>
</svg>
Here are four progressively simpler SVG teardrop shapes:
<svg viewbox="-20 -20 180 180">
<g stroke="black" fill="none">
<path transform="translate(0)"
d="M 0 0
C 0 10 10 17 10 27
C 10 40 -10 40 -10 27
C -10 17 0 10 0 0
Z"/>
<path transform="translate(40)"
d="M 0 0
C 0 16 15 25 5 34
Q 0 38 -5 34
C -15 25 0 16 0 0
Z"/>
<path transform="translate(80)"
d="M 0 0
C 0 10 18 36 0 36
S 0 10 0 0
Z"/>
<path transform="translate(120)"
d="M 0 0
Q 18 36 0 36
T 0 0
Z"/>
<g stroke-width="0.25" stroke="red">
<g transform="translate(0)">
<ellipse rx="1" ry="1" cx="0" cy="0" />
<ellipse rx="1" ry="1" cx="0" cy="10"/>
<ellipse rx="1" ry="1" cx="10" cy="17"/>
<ellipse rx="1" ry="1" cx="10" cy="27"/>
<ellipse rx="1" ry="1" cx="10" cy="40"/>
<ellipse rx="1" ry="1" cx="-10" cy="40"/>
<ellipse rx="1" ry="1" cx="-10" cy="27"/>
<ellipse rx="1" ry="1" cx="-10" cy="17"/>
<line x1="0" y1="0" x2="0" y2="10"/>
<line x1="10" y1="17" x2="10" y2="40"/>
<line x1="-10" y1="40" x2="-10" y2="17"/>
</g>
<g transform="translate(40)">
<ellipse rx="1" ry="1" cx="0" cy="0" />
<ellipse rx="1" ry="1" cx="0" cy="16"/>
<ellipse rx="1" ry="1" cx="15" cy="25"/>
<ellipse rx="1" ry="1" cx="5" cy="34"/>
<ellipse rx="1" ry="1" cx="0" cy="38"/>
<ellipse rx="1" ry="1" cx="-5" cy="34"/>
<ellipse rx="1" ry="1" cx="-15" cy="25"/>
<line x1="0" y1="0" x2="0" y2="16"/>
<line x1="15" y1="25" x2="0" y2="38"/>
<line x1="0" y1="38" x2="-15" y2="25"/>
</g>
<g transform="translate(80)">
<ellipse rx="1" ry="1" cx="0" cy="0" />
<ellipse rx="1" ry="1" cx="0" cy="10"/>
<ellipse rx="1" ry="1" cx="18" cy="36"/>
<ellipse rx="1" ry="1" cx="0" cy="36"/>
<ellipse rx="1" ry="1" cx="-18" cy="36" stroke="gray"/>
<line x1="0" y1="0" x2="0" y2="10"/>
<line x1="18" y1="36" x2="0" y2="36"/>
<line x1="0" y1="36" x2="-18" y2="36" stroke="gray" stroke-dasharray="0.5"/>
</g>
<g transform="translate(120)">
<ellipse rx="1" ry="1" cx="0" cy="0" />
<ellipse rx="1" ry="1" cx="18" cy="36"/>
<ellipse rx="1" ry="1" cx="0" cy="36"/>
<ellipse rx="1" ry="1" cx="-18" cy="36" stroke="gray"/>
<line x1="18" y1="36" x2="0" y2="36"/>
<line x1="0" y1="36" x2="-18" y2="36" stroke="gray" stroke-dasharray="0.5"/>
</g>
</g>
</g>
<g font-size="6" transform="translate(-1.5,-4)">
<text x="-10" y="-8"># of unique points:</text>
<text transform="translate( 0)">8</text>
<text transform="translate( 40)">7</text>
<text transform="translate( 80)">4</text>
<text transform="translate(120)">3</text>
</g>
</svg>
Or if your viewers' font supports it, use the Unicode characters
I also found this on Codepen made by user Ana Tudor using CSS and the box-shadow
style and parametric equations. Very simple, very little code. And many browsers support the CSS3 Box-shadow style:
body {
background-color: black;
}
.tear {
position: absolute;
top: 50%;
left: 50%;
margin: -0.125em;
width: 0.25em;
height: 0.25em;
border-radius: 50%;
box-shadow: 0em -5em red, 0.00118em -4.97592em #ff1800, 0.00937em -4.90393em #ff3000, 0.03125em -4.7847em #ff4800, 0.07283em -4.6194em #ff6000, 0.13915em -4.40961em #ff7800, 0.23408em -4.15735em #ff8f00, 0.36em -3.86505em #ffa700, 0.51777em -3.53553em #ffbf00, 0.70654em -3.17197em gold, 0.92382em -2.77785em #ffef00, 1.16547em -2.35698em #f7ff00, 1.42582em -1.91342em #dfff00, 1.69789em -1.45142em #c7ff00, 1.97361em -0.97545em #afff00, 2.2441em -0.49009em #97ff00, 2.5em 0.0em #80ff00, 2.73182em 0.49009em #68ff00, 2.93032em 0.97545em #50ff00, 3.08681em 1.45142em #38ff00, 3.19358em 1.91342em #20ff00, 3.24414em 2.35698em #08ff00, 3.23352em 2.77785em #00ff10, 3.15851em 3.17197em #00ff28, 3.01777em 3.53553em #00ff40, 2.81196em 3.86505em #00ff58, 2.54377em 4.15735em #00ff70, 2.21783em 4.40961em #00ff87, 1.84059em 4.6194em #00ff9f, 1.42017em 4.7847em #00ffb7, 0.96608em 4.90393em #00ffcf, 0.48891em 4.97592em #00ffe7, 0.0em 5em cyan, -0.48891em 4.97592em #00e7ff, -0.96608em 4.90393em #00cfff, -1.42017em 4.7847em #00b7ff, -1.84059em 4.6194em #009fff, -2.21783em 4.40961em #0087ff, -2.54377em 4.15735em #0070ff, -2.81196em 3.86505em #0058ff, -3.01777em 3.53553em #0040ff, -3.15851em 3.17197em #0028ff, -3.23352em 2.77785em #0010ff, -3.24414em 2.35698em #0800ff, -3.19358em 1.91342em #2000ff, -3.08681em 1.45142em #3800ff, -2.93032em 0.97545em #5000ff, -2.73182em 0.49009em #6800ff, -2.5em 0.0em #7f00ff, -2.2441em -0.49009em #9700ff, -1.97361em -0.97545em #af00ff, -1.69789em -1.45142em #c700ff, -1.42582em -1.91342em #df00ff, -1.16547em -2.35698em #f700ff, -0.92382em -2.77785em #ff00ef, -0.70654em -3.17197em #ff00d7, -0.51777em -3.53553em #ff00bf, -0.36em -3.86505em #ff00a7, -0.23408em -4.15735em #ff008f, -0.13915em -4.40961em #ff0078, -0.07283em -4.6194em #ff0060, -0.03125em -4.7847em #ff0048, -0.00937em -4.90393em #ff0030, -0.00118em -4.97592em #ff0018;
}
<div class="tear"></div>