如何在 CSS 中制作一个带边框的可调整大小的心形
How to make a resizable heart in CSS with a border
我想制作一个心形,用户可以将其调整为任意宽度和高度,边框为 1 像素。
我试过一颗纯正的心CSS:
我试过使用这样的字体:
https://www.w3schools.com/charsets/tryit.asp?deci=9829&ent=hearts
还试了一张SVG图片:
https://css-tricks.com/hearts-in-html-and-css/#inline-svg
但是我的问题是:
无法自由轻松地缩放到 500x200 像素。很难在其周围添加边框
它不能拉伸到其他比例,也不能放大以适应例如。 500x400 框
它几乎是完美的,但边框(描边)随着大小而延伸。我希望边框始终为 1px 宽,无论比例如何
我也尝试制作另一个形状的副本作为阴影(填充为黑色并略微偏移,z-index 较低)但它并不完美(边框各处的宽度不同):
可能 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), black 64%, 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), black 43%, 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,如果要保持边框(描边宽度)相同的相对大小,
然后在 resize
上重新计算笔画宽度
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 that is based on iconocss。该示例的缺点是它使用 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);
}
<script type="module" src="https://unpkg.com/pd-indicator@1.1.7/pd-indicator.js"></script>
<div class="parent">
<pd-indicator type="icon-heart" color="000099" active-color="990000"></pd-indicator>
<pd-indicator type="icon-heart" color="000099" active-color="990000"></pd-indicator>
</div>
我想制作一个心形,用户可以将其调整为任意宽度和高度,边框为 1 像素。
我试过一颗纯正的心CSS:
我试过使用这样的字体: https://www.w3schools.com/charsets/tryit.asp?deci=9829&ent=hearts
还试了一张SVG图片: https://css-tricks.com/hearts-in-html-and-css/#inline-svg
但是我的问题是:
无法自由轻松地缩放到 500x200 像素。很难在其周围添加边框
它不能拉伸到其他比例,也不能放大以适应例如。 500x400 框
它几乎是完美的,但边框(描边)随着大小而延伸。我希望边框始终为 1px 宽,无论比例如何
我也尝试制作另一个形状的副本作为阴影(填充为黑色并略微偏移,z-index 较低)但它并不完美(边框各处的宽度不同):
可能 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), black 64%, 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), black 43%, 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,如果要保持边框(描边宽度)相同的相对大小,
然后在 resize
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 that is based on iconocss。该示例的缺点是它使用 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);
}
<script type="module" src="https://unpkg.com/pd-indicator@1.1.7/pd-indicator.js"></script>
<div class="parent">
<pd-indicator type="icon-heart" color="000099" active-color="990000"></pd-indicator>
<pd-indicator type="icon-heart" color="000099" active-color="990000"></pd-indicator>
</div>