如何创建CSS心脏? /为什么这个CSS会创建一个心形?

时间:2013-06-30 01:13:40

标签: html css3 css-shapes

我在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; 
        -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%; 
     }

请有人解释一下吗?

2 个答案:

答案 0 :(得分:41)

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 */ 
    }
    

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

    enter image description here

  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%;
    }
    

    我们现在得到:

    enter image description here

    已经开始走到一起了:)。

  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>

    enter image description here

  5. 没有任何前缀的代码段

    #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>

答案 1 :(得分:0)

这是使用一个元素并依靠多个背景来实现心脏形状的另一个想法:

.heart {
  width:200px;
  height:200px;
  background:
   radial-gradient(circle at 50% 83%, red 29%, transparent 30%) -40px -100px,
   radial-gradient(circle at 50% 83%, red 29%, transparent 30%) 40px -100px,
   linear-gradient(to bottom left,red 43%,transparent 43%) bottom left/50% 50%,
   linear-gradient(to bottom right,red 43%,transparent 43%) bottom right/50% 50%;
  background-repeat:no-repeat;
}
<div class="heart">
</div>

它如何工作?

使用4个渐变组合整个形状:2个渐变创建顶部,2个创建底部。

底部

我仅使用两个linear-gradient来创建两个覆盖底部的三角形。第一个将给出以下信息:

.heart {
  width:200px;
  height:200px;
  border:1px solid;
  background:
   linear-gradient(to bottom right,red 43%,transparent 43%) bottom right/50% 50%;
  background-repeat:no-repeat;
}
<div class="heart"></div>

第二个是放置在另一侧的第一个的镜像。

.heart {
  width:200px;
  height:200px;
  border:1px solid;
  background:
   linear-gradient(to bottom right,red 43%,transparent 43%) bottom right/50% 50%,
   linear-gradient(to bottom left,red 43%,transparent 43%) bottom left/50% 50%;
  background-repeat:no-repeat;
}
<div class="heart"></div>

每个梯度的大小为[50% 50%],都分别位于bottom leftbottom right

顶部

在顶部,我将在逻辑上使用radial-gradient。这个想法是在彼此上方有两个圆圈,在底部有一个截断的部分。

.heart {
  width:200px;
  height:200px;
  border:1px solid;
  background:
  radial-gradient(circle at 50% 83%, red 29%, transparent 30%);
  background-repeat:no-repeat;
}
<div class="heart">
</div>

如您所见,我将圆心定为[50% 83%],半径为29%,以获得所需的形状。现在,我们需要调整其位置:

.heart {
  width:200px;
  height:200px;
  border:1px solid;
  background:
  radial-gradient(circle at 50% 83%, red 29%, transparent 30%) -40px -100px;
  background-repeat:no-repeat;
}
<div class="heart">
</div>

我们添加相同的梯度,但位置略有不同,并且顶部是

.heart {
  width:200px;
  height:200px;
  border:1px solid;
  background:
  radial-gradient(circle at 50% 83%, red 29%, transparent 30%) -40px -100px,
  radial-gradient(circle at 50% 83%, red 29%, transparent 30%)  40px -100px;
  background-repeat:no-repeat;
}
<div class="heart">
</div>

现在我们只需将这两个部分结合在一起

.heart {
  width:200px;
  height:200px;
  background:
   radial-gradient(circle at 50% 83%, red 29%, transparent 30%) -40px -100px,
   radial-gradient(circle at 50% 83%, red 29%, transparent 30%)  40px -100px,
   linear-gradient(to bottom left,red 43%,transparent 43%) bottom left/50% 50%,
   linear-gradient(to bottom right,red 43%,transparent 43%) bottom right/50% 50%;
  background-repeat:no-repeat;
}
<div class="heart">
</div>

如果您想要更多

我们可以通过添加CSS变量使形状更灵活,以便轻松调整尺寸:

.heart {
  --d:200px;
  width:var(--d);
  height:var(--d);
  background:
   radial-gradient(circle at 50% 83%, red 29%, transparent 30%) calc(-1 * var(--d)/5) calc(-1 * var(--d)/2),
   radial-gradient(circle at 50% 83%, red 29%, transparent 30%)  calc(1 * var(--d)/5) calc(-1 * var(--d)/2),
   linear-gradient(to bottom left,red 43%,transparent 43%) bottom left/50% 50%,
   linear-gradient(to bottom right,red 43%,transparent 43%) bottom right/50% 50%;
  background-repeat:no-repeat;
  display:inline-block;
}
<div class="heart">
</div>
<div class="heart" style="--d:100px">
</div>
<div class="heart" style="--d:60px">
</div>