如何在带有边框的 CSS 中制作可调整大小的心形

问题描述

我想制作一个心形,用户可以将其调整为任意宽度和高度,边框为 1 px。

  1. 我尝试了用纯 CSS 制作的心形: https://stackoverflow.com/a/17386187/1404447

  2. 我尝试使用一种字体,如下所示: https://www.w3schools.com/charsets/tryit.asp?deci=9829&ent=hearts

  3. 并且还尝试了一个 SVG 图片https://css-tricks.com/hearts-in-html-and-css/#inline-svg

但是这是我的问题:

  1. 它不能自由且轻松地缩放到 500x200 像素。很难在它周围添加边框

  2. 它不能被拉伸到其他比例,也不能被放大以适应例如。 500x400 框

  3. 它几乎是完美的,但边框(笔画)会随着尺寸而拉伸。我希望边框总是 1px 宽,无论比例如何

我还尝试将形状的另一个副本制作为阴影(填充黑色并略微偏移,z-index 较低)但它并不完美(边框各处的宽度都不相同):

enter image description here

解决方法

可能 my heart 会做得更好,即使仍然不完美

.heart {
  width:200px;
  height:200px;
  background:
   radial-gradient(90% 90% at 60% 65%,transparent calc(64% - 1px),black 64%,transparent calc(64% + 1px)) top left,radial-gradient(90% 90% at 40% 65%,transparent calc(64% + 1px)) top right,linear-gradient(to bottom left,transparent calc(43% - 1px),black 43%,transparent calc(43% + 1px)) bottom left,linear-gradient(to bottom right,transparent calc(43% + 1px)) bottom right;
  background-size:50% 50%;
  background-repeat:no-repeat;
  border:2px solid red;
  overflow:hidden;
  resize:both;
}
<div class="heart">
</div>

,

对于SVG,如果你想让边框(stroke-width)保持相同的相对大小,
然后在调整大小时重新计算笔画宽度

path.setAttribute("stroke-width",startWidth / divWidth());

(需要更好的计算)

使用 shadowDOM 包裹在 W3C Web 组件(所有现代浏览器都支持)中,
封装的CSS简单,可以使用多个<my-hearts>标签

<style>
  my-heart { --heartwidth: 80px  }
</style>

<my-heart></my-heart>
<my-heart style="--heartwidth:100px"></my-heart>
<my-heart style="--heartwidth:150px"></my-heart>
<my-heart></my-heart>

<script>
  customElements.define("my-heart",class extends HTMLElement {
    constructor() {
      super() // super sets and returns this scope
        .attachShadow({mode:"open"}) // sets and return this.shadowRoot
        .innerHTML = // no need for a Template
        `<style>:host{display: inline-block}
          div {
            width:var(--heartwidth,100px); height:var(--heartwidth,100px);
            resize:both; overflow:auto;
          }
          svg{  
            width:100%; height:100%; background:#ddd; vertical-align:top;
          }
          </style><div><svg preserveAspectRatio="none" viewBox="0 0 34 34">
    <path fill='lightcoral' stroke='red' stroke-width='1' d='m25 2c-3 0-6 3-8 6c-1-3-4-6-8-6c-4 0-8 4-8 8c0 9 10 12 16 21c6-9 16-12 16-21c0-4-4-8-8-8z'/>
    </svg></div>`; // end innerHTML
      let div = this.shadowRoot.querySelector("div");
      let path = this.shadowRoot.querySelector("path");
      let divWidth = () => ~~getComputedStyle(div).width.replace("px","");
      let startWidth = divWidth();
      div.onmousemove =e=> path.setAttribute("stroke-width",startWidth / divWidth());
    }
  });
</script>

,

以下示例基于基于 web component 的简单 iconocss。该示例的缺点是它使用 Query query = FirebaseFirestore.instance .collection("recipes") .where("name",isEqualTo: "test"); QuerySnapshot querySnapshot = await query.get(); CSS 来实现您想要的效果,因此需要 scale() 动态更改比例部分。

Javascript
html,body {
  height: 100%;
  width: 100%;
}

:host {
  display: block;
}

pd-indicator:not(:defined) {
  display: none;
}

pd-indicator,pd-indicator:defined {
  display: block;
  position: absolute;
  top: 20%;
  left: 30%;
  padding: .75rem;
}
pd-indicator:first-child {
  transform: scale(5);
}
pd-indicator:last-child {
  transform: scale(8);
}