How do I create a teardrop in HTML?

后端 未结 12 521
生来不讨喜
生来不讨喜 2020-12-02 03:59

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

相关标签:
12条回答
  • 2020-12-02 04:28

    CSS Version

    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.

    0 讨论(0)
  • 2020-12-02 04:31

    Your main issue with your CSS code was:

    1. You used a different height than width
    2. You haven't rotated the correct angle size

    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

    Alternatives

    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.


    CSS Version

    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>

    SVG Version

    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.

    0 讨论(0)
  • 2020-12-02 04:42

    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>

    0 讨论(0)
  • 2020-12-02 04:44

    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>

    0 讨论(0)
  • 2020-12-02 04:45

    Or if your viewers' font supports it, use the Unicode characters

    DROPLET:

    0 讨论(0)
  • 2020-12-02 04:46

    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>

    0 讨论(0)
提交回复
热议问题