【问题标题】:How to create a heart shape using CSS?如何使用 CSS 创建心形?
【发布时间】:2022-01-25 22:53:44
【问题描述】:

我在 SO 上的一个答案中找到了以下 CSS,我想知道为什么它会创建所需的心形:

#heart { 
    position: relative; 
    width: 100px; 
    height: 90px; 
} 

#heart:before, #heart:after { 
    position: absolute; 
    content: ""; 
    left: 50px; 
    top: 0; 
    width: 50px; 
    height: 80px; 
    background: red; 
    border-radius: 50px 50px 0 0; 
    transform: rotate(-45deg); 
    transform-origin: 0 100%; 
} 

#heart:after { 
    left: 0; 
    transform: rotate(45deg); 
    transform-origin :100% 100%; 
}
<div id="heart"></div>

谁能解释一下?

【问题讨论】:

标签: html css css-shapes


【解决方案1】:

CSS3 Mon Amour - 4 步恋爱

使用 CSS3 创建心形有几个步骤:

  1. 在您的 DOM 中创建一个块级元素,例如 <div>,并为其分配 id="heart" 并应用 CSS:

    #heart {
         position:relative; 
         width:100px; 
         height:90px;
         margin-top:10px; /* leave some space above */
    }
    
  2. 现在使用伪元素#heart:before 我们创建一个带有圆形边缘的红色盒子,如下所示:

    #heart:before {
        position: absolute; 
        content: ""; 
        left: 50px; 
        top: 0; 
        width: 52px; 
        height: 80px; 
        background: red; /* assign a nice red color */
        border-radius: 50px 50px 0 0; /* make the top edge round */ 
    }
    

    你的心脏现在应该是这样的:

  3. 让我们通过添加来分配一点旋转:

    #heart:before {
        -webkit-transform: rotate(-45deg); /* 45 degrees rotation counter clockwise */
           -moz-transform: rotate(-45deg); 
            -ms-transform: rotate(-45deg); 
             -o-transform: rotate(-45deg); 
                transform: rotate(-45deg); 
        -webkit-transform-origin: 0 100%; /* Rotate it around the bottom-left corner */
           -moz-transform-origin: 0 100%; 
            -ms-transform-origin: 0 100%; 
             -o-transform-origin: 0 100%; 
                transform-origin: 0 100%;
    }
    

    我们现在得到:

    已经开始聚在一起了:)。

  4. 现在对于右侧部分,我们基本上只需要旋转相同的形状 顺时针 45 度而不是逆时针。 为了避免代码重复,我们附上 css 的#heart:before 也到#heart:after,然后应用更改 位置和角度:

    #heart:after { 
        left: 0; /* placing the right part properly */
        -webkit-transform: rotate(45deg); /* rotating 45 degrees clockwise */
           -moz-transform: rotate(45deg); 
            -ms-transform: rotate(45deg); 
             -o-transform: rotate(45deg); 
                transform: rotate(45deg); 
        -webkit-transform-origin: 100% 100%; /* rotation is around bottom-right corner this time */
           -moz-transform-origin: 100% 100%; 
            -ms-transform-origin: 100% 100%; 
             -o-transform-origin: 100% 100%; 
                transform-origin :100% 100%; 
    } 
    

    然后瞧!一个完整的心形<div>

不带任何前缀的片段:

#heart {
  position: relative;
  width: 100px;
  height: 90px;
  margin-top: 10px;
}

#heart::before, #heart::after {
  content: "";
  position: absolute;
  top: 0;
  width: 52px;
  height: 80px;
  border-radius: 50px 50px 0 0;
  background: red;
}

#heart::before {
  left: 50px;
  transform: rotate(-45deg);
  transform-origin: 0 100%;
}

#heart::after {
  left: 0;
  transform: rotate(45deg);
  transform-origin: 100% 100%;
}
<div id="heart"></div>

【讨论】:

  • 令人着迷,真的很棒!对于其他人,不要忘记将第一个 #heart:before { 更改为 #heart:before, #heart:after {。 Yotam 是这么说的,但是我太快了,在尝试代码时没有看到这个信息。
  • 也许在第 4 步之后添加另一个图像,其中第二半是另一种颜色以更好地显示图层?为了更好地展示正在应用的“技巧”:)
  • 另外,这些属性不需要供应商前缀 :) 我也将它们从问题中删除以简化
【解决方案2】:

一个用更少代码的新想法:

.heart {
  display:inline-block;
  width: 200px; 
  aspect-ratio: 1;
  border-image: radial-gradient(red 69%,#0000 70%) 84.5% fill/100%;
  clip-path: polygon(-41% 0,50% 91%, 141% 0);
}
<div class="heart"></div>
<div class="heart" style="width:100px"></div>
<div class="heart" style="width:50px"></div>

这是另一个想法,使用一个元素并依靠多个背景来实现心形。您也可以通过仅更改宽度来轻松调整大小:

.heart {
  width:200px;
  background:
   radial-gradient(circle at 60% 65%, red 64%, transparent 65%) top left,
   radial-gradient(circle at 40% 65%, red 64%, transparent 65%) top right,
   linear-gradient(to bottom left, red 43%,transparent 43%) bottom left ,
   linear-gradient(to bottom right,red 43%,transparent 43%) bottom right;
  background-size:50% 50%;
  background-repeat:no-repeat;
  display:inline-block;
}
.heart::before {
  content:"";
  display:block;
  padding-top:100%;
}
<div class="heart">
</div>
<div class="heart" style="width:100px">
</div>
<div class="heart" style="width:60px">
</div>
<div class="heart" style="width:30px">
</div>

你也可以使用mask,你可以有任何颜色:

.heart {
  width:200px;
  display:inline-block;
  -webkit-mask:
     radial-gradient(circle at 60% 65%, red 64%, transparent 65%) top left,
     radial-gradient(circle at 40% 65%, red 64%, transparent 65%) top right,
     linear-gradient(to bottom left, red 43%,transparent 43%) bottom left ,
     linear-gradient(to bottom right,red 43%,transparent 43%) bottom right;
  -webkit-mask-size:50% 50%;
  -webkit-mask-repeat:no-repeat;
  mask:
     radial-gradient(circle at 60% 65%, red 64%, transparent 65%) top left,
     radial-gradient(circle at 40% 65%, red 64%, transparent 65%) top right,
     linear-gradient(to bottom left, red 43%,transparent 43%) bottom left ,
     linear-gradient(to bottom right,red 43%,transparent 43%) bottom right;
  mask-size:50% 50%;
  mask-repeat:no-repeat;
  background:linear-gradient(red,blue);
}
.heart::before {
  content:"";
  display:block;
  padding-top:100%;
}
<div class="heart">
</div>
<div class="heart" style="width:100px;background:linear-gradient(45deg,grey 50%,purple 0)">
</div>
<div class="heart" style="width:60px;background:radial-gradient(red,yellow,red)">
</div>
<div class="heart" style="width:30px;background:blue">
</div>


它是如何工作的?

使用 4 个渐变组合整个形状:2 个渐变用于创建顶部,2 个用于创建底部。每个渐变占用 1/4 大小并放置在一个角落。

为每个渐变使用不同的颜色以清楚地识别拼图

.heart {
  width:200px;
  background:
   radial-gradient(circle at 60% 65%, red  64%, grey 65%) top left,
   radial-gradient(circle at 40% 65%, blue 64%, black 65%) top right,
   linear-gradient(to bottom left, green 43%,black 43%) bottom left ,
   linear-gradient(to bottom right,purple 43%,grey 43%) bottom right;
  background-size:50% 50%;
  background-repeat:no-repeat;
  display:inline-block;
  border:5px solid yellow;
}
.heart::before {
  content:"";
  display:block;
  padding-top:100%;
}
<div class="heart">
</div>

【讨论】:

  • 惊人的答案,您介意解释一下您是如何实现第一个片段中的效果的吗?
  • @James 这里是一个说明剪辑路径在做什么的插图:jsfiddle.net/7xb50yrm .. 对于边框部分,我邀请您阅读这个答案以了解它是如何工作的:stackoverflow.com/a/56915094/8620333
猜你喜欢
  • 2011-04-18
  • 1970-01-01
  • 1970-01-01
  • 2019-11-27
  • 1970-01-01
  • 1970-01-01
  • 2013-10-30
  • 2012-12-19
相关资源
最近更新 更多