如何通过以圆形方式堆叠 div 来创建棒棒糖形状?
How to create a lollipop shape by stacking divs in a circular manner?
如何以循环方式堆叠 div,其中最后一个 div 应该在第一个 div 下方,但在倒数第二个 div 上方。 css 可以吗?任何帮助将不胜感激。
请找到Codepen。
给出示例代码片段
<div class="frame">
<div class="lolly-pop__wrapper">
<div class="lollypop-top">
<div class="lollypop-top__item"></div>
<div class="lollypop-top__item"></div>
<div class="lollypop-top__item"></div>
<div class="lollypop-top__item"></div>
<div class="lollypop-top__item"></div>
<div class="lollypop-top__item"></div>
<div class="lollypop-top__item"></div>
<div class="lollypop-top__item"></div>
<div class="lollypop-top__item"></div>
<div class="lollypop-top__item"></div>
<div class="lollypop-top__item"></div>
<div class="lollypop-top__item"></div>
</div>
</div>
</div>
.frame {
position: absolute;
display: flex;
justify-content: center;
top: 50%;
left: 50%;
width: 400px;
height: 400px;
margin-top: -200px;
margin-left: -200px;
border-radius: 2px;
box-shadow: 4px 8px 16px 0 rgba(0,0,0,0.1);
overflow: hidden;
background: #F5CE51;
color: #333;
font-family: 'Open Sans', Helvetica, sans-serif;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
}
.lollypop-top {
position: relative;
height: 150px;
width: 150px;
background-color: #fff;
border-radius: 100%;
overflow: hidden;
.lollypop-top__item {
position: absolute;
height: 150px;
width: 150px;
top: -50%;
border-radius: 100%;
transform-origin: bottom;
background-color: #fff;
&:nth-child(odd) {
background-color: #D70606;
}
&:nth-child(1) {
transform: rotate(30deg);
}
&:nth-child(2) {
transform: rotate(60deg);
}
&:nth-child(3) {
transform: rotate(90deg);
}
&:nth-child(4) {
transform: rotate(120deg);
}
&:nth-child(5) {
transform: rotate(150deg);
}
&:nth-child(6) {
transform: rotate(180deg);
}
&:nth-child(7) {
transform: rotate(210deg);
}
&:nth-child(8) {
transform: rotate(240deg);
}
&:nth-child(9) {
transform: rotate(270deg);
}
&:nth-child(10) {
transform: rotate(300deg);
}
&:nth-child(11) {
transform: rotate(330deg);
}
&:nth-child(12) {
transform: rotate(360deg);
}
}
}
.frame {
position: absolute;
display: flex;
justify-content: center;
top: 50%;
left: 50%;
width: 400px;
height: 400px;
margin-top: -200px;
margin-left: -200px;
border-radius: 2px;
box-shadow: 4px 8px 16px 0 rgba(0, 0, 0, 0.1);
overflow: hidden;
background: #F5CE51;
color: #333;
font-family: 'Open Sans', Helvetica, sans-serif;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
}
.lollypop-top {
position: relative;
height: 150px;
width: 150px;
background-color: #fff;
border-radius: 100%;
overflow: hidden;
}
.lollypop-top .lollypop-top__item {
position: absolute;
height: 150px;
width: 150px;
top: -50%;
border-radius: 100%;
transform-origin: bottom;
background-color: #fff;
}
.lollypop-top .lollypop-top__item:nth-child(odd) {
background-color: #D70606;
}
.lollypop-top .lollypop-top__item:nth-child(1) {
transform: rotate(30deg);
}
.lollypop-top .lollypop-top__item:nth-child(2) {
transform: rotate(60deg);
}
.lollypop-top .lollypop-top__item:nth-child(3) {
transform: rotate(90deg);
}
.lollypop-top .lollypop-top__item:nth-child(4) {
transform: rotate(120deg);
}
.lollypop-top .lollypop-top__item:nth-child(5) {
transform: rotate(150deg);
}
.lollypop-top .lollypop-top__item:nth-child(6) {
transform: rotate(180deg);
}
.lollypop-top .lollypop-top__item:nth-child(7) {
transform: rotate(210deg);
}
.lollypop-top .lollypop-top__item:nth-child(8) {
transform: rotate(240deg);
}
.lollypop-top .lollypop-top__item:nth-child(9) {
transform: rotate(270deg);
}
.lollypop-top .lollypop-top__item:nth-child(10) {
transform: rotate(300deg);
}
.lollypop-top .lollypop-top__item:nth-child(11) {
transform: rotate(330deg);
}
.lollypop-top .lollypop-top__item:nth-child(12) {
transform: rotate(360deg);
}
<div class="frame">
<div class="lolly-pop__wrapper">
<div class="lollypop-top">
<div class="lollypop-top__item"></div>
<div class="lollypop-top__item"></div>
<div class="lollypop-top__item"></div>
<div class="lollypop-top__item"></div>
<div class="lollypop-top__item"></div>
<div class="lollypop-top__item"></div>
<div class="lollypop-top__item"></div>
<div class="lollypop-top__item"></div>
<div class="lollypop-top__item"></div>
<div class="lollypop-top__item"></div>
<div class="lollypop-top__item"></div>
<div class="lollypop-top__item"></div>
</div>
</div>
</div>
我会考虑两个元素(伪元素)和多个径向渐变来创建这个。您只需要创建两次形状的一半并旋转其中一个。
.box {
width:150px;
height:150px;
border-radius:100%;
border:1px solid;
position:relative;
overflow:hidden;
}
.box::before,
.box::after{
content:"";
position:absolute;
top:0;
bottom:0;
left:0;
right:50%;
background:
/*we rotate by 30deg so will use :
sin(30deg)*R = 0.5x75px = 37.5px
cos(30deg)*R = 0.866x75px = 64.95px
10.05px = 75px - 64.95px;
112.5px = 75px + 37.5px
139.95px = 75px + 64.95px
37.5px = 75px - 37.5px
*/
radial-gradient(circle 75px at 139.95px 37.5px,red 98%,transparent 100%),
radial-gradient(circle 75px at 112.5px 10.05px,white 98%,transparent 100%),
radial-gradient(circle 75px at 75px 0, red 98%,transparent 100%),
radial-gradient(circle 75px at 37.5px 10.05px,white 98%,transparent 100%),
radial-gradient(circle 75px at 10.05px 37.5px ,red 98%,transparent 100%),
radial-gradient(circle 75px at 0 75px, white 98%,transparent 100%),
radial-gradient(circle 75px at 10.05px 112.5px,red 98%,transparent 100%);
}
.box::after {
transform:rotate(180deg);
transform-origin:right;
}
<div class="box">
</div>
为了让事情更有趣,我们可以添加 CSS 变量来轻松控制形状:
.box {
--R:50px; /*Radius*/
--c1:red; /*first color*/
--c2:#fff; /*second color*/
--g1:var(--c1) 98%, transparent 100%;
--g2:var(--c2) 98%, transparent 100%;
width:calc(2*var(--R));
height:calc(2*var(--R));
border-radius:100%;
border:1px solid;
position:relative;
overflow:hidden;
display:inline-block;
vertical-align:middle;
}
.box::before,
.box::after{
content:"";
position:absolute;
top:0;
bottom:0;
left:0;
right:50%;
background:
/*we rotate by 30deg so will use :
sin(30deg)*R = 0.5xR
cos(30deg)*R = 0.866xR
*/
radial-gradient(circle var(--R) at calc(var(--R) + 0.866*var(--R)) calc(var(--R) - 0.5*var(--R)) ,var(--g1)),
radial-gradient(circle var(--R) at calc(var(--R) + 0.5*var(--R)) calc(var(--R) - 0.866*var(--R)),var(--g2)),
radial-gradient(circle var(--R) at var(--R) 0 ,var(--g1)),
radial-gradient(circle var(--R) at calc(var(--R) - 0.5*var(--R)) calc(var(--R) - 0.866*var(--R)),var(--g2)),
radial-gradient(circle var(--R) at calc(var(--R) - 0.866*var(--R)) calc(var(--R) - 0.5*var(--R)) ,var(--g1)),
radial-gradient(circle var(--R) at 0 var(--R) ,var(--g2)),
radial-gradient(circle var(--R) at calc(var(--R) - 0.866*var(--R)) calc(var(--R) + 0.5*var(--R)) ,var(--g1));
}
/*the same shape rotated*/
.box::after {
transform:rotate(180deg);
transform-origin:right;
}
<div class="box"></div>
<div class="box" style="--R:80px;--c1:blue"></div>
<div class="box" style="--R:100px;--c1:green;--c2:yellow"></div>
<div class="box" style="--R:150px;--c1:white;--c2:pink"></div>
请注意,Safari 不支持 at
的语法(在此处 进行了解释),因此这是另一种语法:
.box {
--R:50px; /*Radius*/
--c1:red; /*first color*/
--c2:#fff; /*second color*/
--g1:var(--c1) 98%, transparent 100%;
--g2:var(--c2) 98%, transparent 100%;
width:calc(2*var(--R));
height:calc(2*var(--R));
border-radius:100%;
border:1px solid;
position:relative;
overflow:hidden;
display:inline-block;
vertical-align:middle;
}
.box::before,
.box::after{
content:"";
position:absolute;
top:0;
bottom:0;
left:0;
right:50%;
background:
/*we rotate by 30deg so will use :
sin(30deg)*R = 0.5xR
cos(30deg)*R = 0.866xR
*/
radial-gradient(farthest-side,var(--g1)) calc(var(--R) + 0.866*var(--R) - var(--R)) calc(var(--R) - 0.5*var(--R) - var(--R)),
radial-gradient(farthest-side,var(--g1)) calc(var(--R) + 0.866*var(--R) - var(--R)) calc(var(--R) - 0.5*var(--R) - var(--R)),
radial-gradient(farthest-side,var(--g2)) calc(var(--R) + 0.5*var(--R) - var(--R)) calc(var(--R) - 0.866*var(--R) - var(--R)),
radial-gradient(farthest-side,var(--g1)) 0 calc(-1*var(--R)),
radial-gradient(farthest-side,var(--g2)) calc(var(--R) - 0.5*var(--R) - var(--R)) calc(var(--R) - 0.866*var(--R) - var(--R)),
radial-gradient(farthest-side,var(--g1)) calc(var(--R) - 0.866*var(--R) - var(--R)) calc(var(--R) - 0.5*var(--R) - var(--R)),
radial-gradient(farthest-side,var(--g2)) calc(-1*var(--R)) 0,
radial-gradient(farthest-side,var(--g1)) calc(var(--R) - 0.866*var(--R) - var(--R)) calc(var(--R) + 0.5*var(--R) - var(--R));
background-size:calc(2*var(--R)) calc(2*var(--R));
background-repeat:no-repeat;
}
/*the same shape rotated*/
.box::after {
transform:rotate(180deg);
transform-origin:right center;
}
<div class="box"></div>
<div class="box" style="--R:80px;--c1:blue"></div>
<div class="box" style="--R:100px;--c1:green;--c2:yellow"></div>
<div class="box" style="--R:150px;--c1:white;--c2:pink"></div>
这是一个 Codepen 代码演示
我的方法是一个可重复使用的 SVG <symbol>
,路径由 quadratic-bézier 曲线塑造:
#svg-lollipop path { transform-origin: 50% 50%; }
#svg-lollipop path:nth-child(2) { transform: rotateZ(60deg); }
#svg-lollipop path:nth-child(3) { transform: rotateZ(120deg); }
#svg-lollipop path:nth-child(4) { transform: rotateZ(180deg); }
#svg-lollipop path:nth-child(5) { transform: rotateZ(240deg); }
#svg-lollipop path:nth-child(6) { transform: rotateZ(300deg); }
.lollipop {
width: 30%;
display: inline-block;
overflow: hidden;
border-radius: 50%;
position: relative;
margin: 0 20px;
aspect-ratio: 1;
}
.lollipop svg {
position: absolute;
left: 0;
top: 0;
right: 0;
bottom: 0;
height: 100%;
fill: currentColor;
}
.lollipop--animated {
animation: rotate 10s linear 0s infinite;
}
@keyframes rotate {
0% { transform: rotateZ(0) }
100% { transform: rotateZ(1turn) }
}
<svg style="display: none;">
<symbol id="svg-lollipop">
<path d="M150,150 Q75,185 0,150 H0 V63.6 Q75,150 150,150 z" />
<path d="M150,150 Q75,185 0,150 H0 V63.6 Q75,150 150,150 z" />
<path d="M150,150 Q75,185 0,150 H0 V63.6 Q75,150 150,150 z" />
<path d="M150,150 Q75,185 0,150 H0 V63.6 Q75,150 150,150 z" />
<path d="M150,150 Q75,185 0,150 H0 V63.6 Q75,150 150,150 z" />
<path d="M150,150 Q75,185 0,150 H0 V63.6 Q75,150 150,150 z" />
</symbol>
</svg>
<div class="lollipop lollipop--animated"
style="background-color: #FFF; color:#E92120;">
<svg viewBox="0 0 300 300"><use xlink:href="#svg-lollipop"></use></svg>
</div>
<div class="lollipop"
style="background-color: #004991; color:#007BC1;">
<svg viewBox="0 0 300 300"><use xlink:href="#svg-lollipop"></use></svg>
</div>
工作原理
相同的形状被克隆了 6 次并旋转以填充整个 svg。在此示例中,每个彩色形状都有一个角度 α = 30deg
.
然后从三角学我们可以找到曲线原点的坐标:在路径中 y 坐标 63.6
获得为 150 - (150 * tan(α))
,所以如果你需要改变形状的数量和角度,你可以很容易地找到自己的原点(quadratic curves真的很容易画)。
最后,外包装有一个 border-radius
和一个隐藏的 overflow
以形成圆形。
最终结果也是响应式的,因为外包装保持其 1:1
纵横比。
可以在容器上设置 background-color
来更改白色区域,可以使用 color
属性(fill
属性 的 svg
元素被设置为 currentColor
为了您的方便)。
我后来注意到的东西
如果你在包装纸上添加一个 box-shadow: inset 0 0 20px #aaa;
图像看起来像一个充气的沙滩气球而不是棒棒糖。
机缘巧合。
也检查这个答案。Codepen
<div class="frame">
<div class="lolly-pop__wrapper">
<div class="lollypop-top">
<div class="first__half">
<div class="lollypop-top__item"></div>
<div class="lollypop-top__item"></div>
<div class="lollypop-top__item"></div>
<div class="lollypop-top__item"></div>
<div class="lollypop-top__item"></div>
<div class="lollypop-top__item"></div>
<div class="lollypop-top__item"></div>
<div class="lollypop-top__item"></div>
<div class="lollypop-top__item"></div>
<div class="lollypop-top__item"></div>
<div class="lollypop-top__item"></div>
<div class="lollypop-top__item"></div>
<div class="lollypop-top__item"></div>
<div class="lollypop-top__item"></div>
</div>
<div class="second__half">
<div class="lollypop-top__item"></div>
<div class="lollypop-top__item"></div>
<div class="lollypop-top__item"></div>
<div class="lollypop-top__item"></div>
<div class="lollypop-top__item"></div>
<div class="lollypop-top__item"></div>
<div class="lollypop-top__item"></div>
<div class="lollypop-top__item"></div>
<div class="lollypop-top__item"></div>
<div class="lollypop-top__item"></div>
<div class="lollypop-top__item"></div>
<div class="lollypop-top__item"></div>
<div class="lollypop-top__item"></div>
<div class="lollypop-top__item"></div>
</div>
</div>
</div>
</div>
.frame {
position: absolute;
display: flex;
justify-content: center;
top: 50%;
left: 50%;
width: 400px;
height: 400px;
margin-top: -200px;
margin-left: -200px;
border-radius: 2px;
box-shadow: 4px 8px 16px 0 rgba(0,0,0,0.1);
overflow: hidden;
background: #F5CE51;
color: #333;
font-family: 'Open Sans', Helvetica, sans-serif;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
}
.lollypop-top {
position: relative;
height: 150px;
width: 150px;
background-color: #ccc;
border-radius: 100%;
overflow: hidden;
.lollypop-top__item {
position: absolute;
height: 150px;
width: 150px;
top: -50%;
border-radius: 100%;
transform-origin: bottom;
background-color: #fff;
&:nth-child(odd) {
background-color: #D70606;
}
&:nth-child(1) {
transform: rotate(30deg);
}
&:nth-child(2) {
transform: rotate(60deg);
}
&:nth-child(3) {
transform: rotate(90deg);
}
&:nth-child(4) {
transform: rotate(120deg);
}
&:nth-child(5) {
transform: rotate(150deg);
}
&:nth-child(6) {
transform: rotate(180deg);
}
&:nth-child(7) {
transform: rotate(210deg);
}
&:nth-child(8) {
transform: rotate(240deg);
}
&:nth-child(9) {
transform: rotate(270deg);
}
&:nth-child(10) {
transform: rotate(300deg);
}
&:nth-child(11) {
transform: rotate(330deg);
}
&:nth-child(12) {
transform: rotate(360deg);
}
&:nth-child(13) {
transform: rotate(390deg);
}
&:nth-child(14) {
transform: rotate(420deg);
}
}
}
.first__half,
.second__half {
position: absolute;
left: 0;
top: 0;
height: 100%;
overflow: hidden;
}
.first__half {
width: 50%;
}
.second__half {
right: 0;
width: 50%;
transform: rotate(180deg);
transform-origin:right center;
}
如何以循环方式堆叠 div,其中最后一个 div 应该在第一个 div 下方,但在倒数第二个 div 上方。 css 可以吗?任何帮助将不胜感激。
请找到Codepen。 给出示例代码片段
<div class="frame">
<div class="lolly-pop__wrapper">
<div class="lollypop-top">
<div class="lollypop-top__item"></div>
<div class="lollypop-top__item"></div>
<div class="lollypop-top__item"></div>
<div class="lollypop-top__item"></div>
<div class="lollypop-top__item"></div>
<div class="lollypop-top__item"></div>
<div class="lollypop-top__item"></div>
<div class="lollypop-top__item"></div>
<div class="lollypop-top__item"></div>
<div class="lollypop-top__item"></div>
<div class="lollypop-top__item"></div>
<div class="lollypop-top__item"></div>
</div>
</div>
</div>
.frame {
position: absolute;
display: flex;
justify-content: center;
top: 50%;
left: 50%;
width: 400px;
height: 400px;
margin-top: -200px;
margin-left: -200px;
border-radius: 2px;
box-shadow: 4px 8px 16px 0 rgba(0,0,0,0.1);
overflow: hidden;
background: #F5CE51;
color: #333;
font-family: 'Open Sans', Helvetica, sans-serif;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
}
.lollypop-top {
position: relative;
height: 150px;
width: 150px;
background-color: #fff;
border-radius: 100%;
overflow: hidden;
.lollypop-top__item {
position: absolute;
height: 150px;
width: 150px;
top: -50%;
border-radius: 100%;
transform-origin: bottom;
background-color: #fff;
&:nth-child(odd) {
background-color: #D70606;
}
&:nth-child(1) {
transform: rotate(30deg);
}
&:nth-child(2) {
transform: rotate(60deg);
}
&:nth-child(3) {
transform: rotate(90deg);
}
&:nth-child(4) {
transform: rotate(120deg);
}
&:nth-child(5) {
transform: rotate(150deg);
}
&:nth-child(6) {
transform: rotate(180deg);
}
&:nth-child(7) {
transform: rotate(210deg);
}
&:nth-child(8) {
transform: rotate(240deg);
}
&:nth-child(9) {
transform: rotate(270deg);
}
&:nth-child(10) {
transform: rotate(300deg);
}
&:nth-child(11) {
transform: rotate(330deg);
}
&:nth-child(12) {
transform: rotate(360deg);
}
}
}
.frame {
position: absolute;
display: flex;
justify-content: center;
top: 50%;
left: 50%;
width: 400px;
height: 400px;
margin-top: -200px;
margin-left: -200px;
border-radius: 2px;
box-shadow: 4px 8px 16px 0 rgba(0, 0, 0, 0.1);
overflow: hidden;
background: #F5CE51;
color: #333;
font-family: 'Open Sans', Helvetica, sans-serif;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
}
.lollypop-top {
position: relative;
height: 150px;
width: 150px;
background-color: #fff;
border-radius: 100%;
overflow: hidden;
}
.lollypop-top .lollypop-top__item {
position: absolute;
height: 150px;
width: 150px;
top: -50%;
border-radius: 100%;
transform-origin: bottom;
background-color: #fff;
}
.lollypop-top .lollypop-top__item:nth-child(odd) {
background-color: #D70606;
}
.lollypop-top .lollypop-top__item:nth-child(1) {
transform: rotate(30deg);
}
.lollypop-top .lollypop-top__item:nth-child(2) {
transform: rotate(60deg);
}
.lollypop-top .lollypop-top__item:nth-child(3) {
transform: rotate(90deg);
}
.lollypop-top .lollypop-top__item:nth-child(4) {
transform: rotate(120deg);
}
.lollypop-top .lollypop-top__item:nth-child(5) {
transform: rotate(150deg);
}
.lollypop-top .lollypop-top__item:nth-child(6) {
transform: rotate(180deg);
}
.lollypop-top .lollypop-top__item:nth-child(7) {
transform: rotate(210deg);
}
.lollypop-top .lollypop-top__item:nth-child(8) {
transform: rotate(240deg);
}
.lollypop-top .lollypop-top__item:nth-child(9) {
transform: rotate(270deg);
}
.lollypop-top .lollypop-top__item:nth-child(10) {
transform: rotate(300deg);
}
.lollypop-top .lollypop-top__item:nth-child(11) {
transform: rotate(330deg);
}
.lollypop-top .lollypop-top__item:nth-child(12) {
transform: rotate(360deg);
}
<div class="frame">
<div class="lolly-pop__wrapper">
<div class="lollypop-top">
<div class="lollypop-top__item"></div>
<div class="lollypop-top__item"></div>
<div class="lollypop-top__item"></div>
<div class="lollypop-top__item"></div>
<div class="lollypop-top__item"></div>
<div class="lollypop-top__item"></div>
<div class="lollypop-top__item"></div>
<div class="lollypop-top__item"></div>
<div class="lollypop-top__item"></div>
<div class="lollypop-top__item"></div>
<div class="lollypop-top__item"></div>
<div class="lollypop-top__item"></div>
</div>
</div>
</div>
我会考虑两个元素(伪元素)和多个径向渐变来创建这个。您只需要创建两次形状的一半并旋转其中一个。
.box {
width:150px;
height:150px;
border-radius:100%;
border:1px solid;
position:relative;
overflow:hidden;
}
.box::before,
.box::after{
content:"";
position:absolute;
top:0;
bottom:0;
left:0;
right:50%;
background:
/*we rotate by 30deg so will use :
sin(30deg)*R = 0.5x75px = 37.5px
cos(30deg)*R = 0.866x75px = 64.95px
10.05px = 75px - 64.95px;
112.5px = 75px + 37.5px
139.95px = 75px + 64.95px
37.5px = 75px - 37.5px
*/
radial-gradient(circle 75px at 139.95px 37.5px,red 98%,transparent 100%),
radial-gradient(circle 75px at 112.5px 10.05px,white 98%,transparent 100%),
radial-gradient(circle 75px at 75px 0, red 98%,transparent 100%),
radial-gradient(circle 75px at 37.5px 10.05px,white 98%,transparent 100%),
radial-gradient(circle 75px at 10.05px 37.5px ,red 98%,transparent 100%),
radial-gradient(circle 75px at 0 75px, white 98%,transparent 100%),
radial-gradient(circle 75px at 10.05px 112.5px,red 98%,transparent 100%);
}
.box::after {
transform:rotate(180deg);
transform-origin:right;
}
<div class="box">
</div>
为了让事情更有趣,我们可以添加 CSS 变量来轻松控制形状:
.box {
--R:50px; /*Radius*/
--c1:red; /*first color*/
--c2:#fff; /*second color*/
--g1:var(--c1) 98%, transparent 100%;
--g2:var(--c2) 98%, transparent 100%;
width:calc(2*var(--R));
height:calc(2*var(--R));
border-radius:100%;
border:1px solid;
position:relative;
overflow:hidden;
display:inline-block;
vertical-align:middle;
}
.box::before,
.box::after{
content:"";
position:absolute;
top:0;
bottom:0;
left:0;
right:50%;
background:
/*we rotate by 30deg so will use :
sin(30deg)*R = 0.5xR
cos(30deg)*R = 0.866xR
*/
radial-gradient(circle var(--R) at calc(var(--R) + 0.866*var(--R)) calc(var(--R) - 0.5*var(--R)) ,var(--g1)),
radial-gradient(circle var(--R) at calc(var(--R) + 0.5*var(--R)) calc(var(--R) - 0.866*var(--R)),var(--g2)),
radial-gradient(circle var(--R) at var(--R) 0 ,var(--g1)),
radial-gradient(circle var(--R) at calc(var(--R) - 0.5*var(--R)) calc(var(--R) - 0.866*var(--R)),var(--g2)),
radial-gradient(circle var(--R) at calc(var(--R) - 0.866*var(--R)) calc(var(--R) - 0.5*var(--R)) ,var(--g1)),
radial-gradient(circle var(--R) at 0 var(--R) ,var(--g2)),
radial-gradient(circle var(--R) at calc(var(--R) - 0.866*var(--R)) calc(var(--R) + 0.5*var(--R)) ,var(--g1));
}
/*the same shape rotated*/
.box::after {
transform:rotate(180deg);
transform-origin:right;
}
<div class="box"></div>
<div class="box" style="--R:80px;--c1:blue"></div>
<div class="box" style="--R:100px;--c1:green;--c2:yellow"></div>
<div class="box" style="--R:150px;--c1:white;--c2:pink"></div>
请注意,Safari 不支持 at
的语法(在此处
.box {
--R:50px; /*Radius*/
--c1:red; /*first color*/
--c2:#fff; /*second color*/
--g1:var(--c1) 98%, transparent 100%;
--g2:var(--c2) 98%, transparent 100%;
width:calc(2*var(--R));
height:calc(2*var(--R));
border-radius:100%;
border:1px solid;
position:relative;
overflow:hidden;
display:inline-block;
vertical-align:middle;
}
.box::before,
.box::after{
content:"";
position:absolute;
top:0;
bottom:0;
left:0;
right:50%;
background:
/*we rotate by 30deg so will use :
sin(30deg)*R = 0.5xR
cos(30deg)*R = 0.866xR
*/
radial-gradient(farthest-side,var(--g1)) calc(var(--R) + 0.866*var(--R) - var(--R)) calc(var(--R) - 0.5*var(--R) - var(--R)),
radial-gradient(farthest-side,var(--g1)) calc(var(--R) + 0.866*var(--R) - var(--R)) calc(var(--R) - 0.5*var(--R) - var(--R)),
radial-gradient(farthest-side,var(--g2)) calc(var(--R) + 0.5*var(--R) - var(--R)) calc(var(--R) - 0.866*var(--R) - var(--R)),
radial-gradient(farthest-side,var(--g1)) 0 calc(-1*var(--R)),
radial-gradient(farthest-side,var(--g2)) calc(var(--R) - 0.5*var(--R) - var(--R)) calc(var(--R) - 0.866*var(--R) - var(--R)),
radial-gradient(farthest-side,var(--g1)) calc(var(--R) - 0.866*var(--R) - var(--R)) calc(var(--R) - 0.5*var(--R) - var(--R)),
radial-gradient(farthest-side,var(--g2)) calc(-1*var(--R)) 0,
radial-gradient(farthest-side,var(--g1)) calc(var(--R) - 0.866*var(--R) - var(--R)) calc(var(--R) + 0.5*var(--R) - var(--R));
background-size:calc(2*var(--R)) calc(2*var(--R));
background-repeat:no-repeat;
}
/*the same shape rotated*/
.box::after {
transform:rotate(180deg);
transform-origin:right center;
}
<div class="box"></div>
<div class="box" style="--R:80px;--c1:blue"></div>
<div class="box" style="--R:100px;--c1:green;--c2:yellow"></div>
<div class="box" style="--R:150px;--c1:white;--c2:pink"></div>
这是一个 Codepen 代码演示
我的方法是一个可重复使用的 SVG <symbol>
,路径由 quadratic-bézier 曲线塑造:
#svg-lollipop path { transform-origin: 50% 50%; }
#svg-lollipop path:nth-child(2) { transform: rotateZ(60deg); }
#svg-lollipop path:nth-child(3) { transform: rotateZ(120deg); }
#svg-lollipop path:nth-child(4) { transform: rotateZ(180deg); }
#svg-lollipop path:nth-child(5) { transform: rotateZ(240deg); }
#svg-lollipop path:nth-child(6) { transform: rotateZ(300deg); }
.lollipop {
width: 30%;
display: inline-block;
overflow: hidden;
border-radius: 50%;
position: relative;
margin: 0 20px;
aspect-ratio: 1;
}
.lollipop svg {
position: absolute;
left: 0;
top: 0;
right: 0;
bottom: 0;
height: 100%;
fill: currentColor;
}
.lollipop--animated {
animation: rotate 10s linear 0s infinite;
}
@keyframes rotate {
0% { transform: rotateZ(0) }
100% { transform: rotateZ(1turn) }
}
<svg style="display: none;">
<symbol id="svg-lollipop">
<path d="M150,150 Q75,185 0,150 H0 V63.6 Q75,150 150,150 z" />
<path d="M150,150 Q75,185 0,150 H0 V63.6 Q75,150 150,150 z" />
<path d="M150,150 Q75,185 0,150 H0 V63.6 Q75,150 150,150 z" />
<path d="M150,150 Q75,185 0,150 H0 V63.6 Q75,150 150,150 z" />
<path d="M150,150 Q75,185 0,150 H0 V63.6 Q75,150 150,150 z" />
<path d="M150,150 Q75,185 0,150 H0 V63.6 Q75,150 150,150 z" />
</symbol>
</svg>
<div class="lollipop lollipop--animated"
style="background-color: #FFF; color:#E92120;">
<svg viewBox="0 0 300 300"><use xlink:href="#svg-lollipop"></use></svg>
</div>
<div class="lollipop"
style="background-color: #004991; color:#007BC1;">
<svg viewBox="0 0 300 300"><use xlink:href="#svg-lollipop"></use></svg>
</div>
工作原理
相同的形状被克隆了 6 次并旋转以填充整个 svg。在此示例中,每个彩色形状都有一个角度 α = 30deg
.
然后从三角学我们可以找到曲线原点的坐标:在路径中 y 坐标 63.6
获得为 150 - (150 * tan(α))
,所以如果你需要改变形状的数量和角度,你可以很容易地找到自己的原点(quadratic curves真的很容易画)。
最后,外包装有一个 border-radius
和一个隐藏的 overflow
以形成圆形。
最终结果也是响应式的,因为外包装保持其 1:1
纵横比。
可以在容器上设置 background-color
来更改白色区域,可以使用 color
属性(fill
属性 的 svg
元素被设置为 currentColor
为了您的方便)。
我后来注意到的东西
如果你在包装纸上添加一个 box-shadow: inset 0 0 20px #aaa;
图像看起来像一个充气的沙滩气球而不是棒棒糖。
机缘巧合。
也检查这个答案。Codepen
<div class="frame">
<div class="lolly-pop__wrapper">
<div class="lollypop-top">
<div class="first__half">
<div class="lollypop-top__item"></div>
<div class="lollypop-top__item"></div>
<div class="lollypop-top__item"></div>
<div class="lollypop-top__item"></div>
<div class="lollypop-top__item"></div>
<div class="lollypop-top__item"></div>
<div class="lollypop-top__item"></div>
<div class="lollypop-top__item"></div>
<div class="lollypop-top__item"></div>
<div class="lollypop-top__item"></div>
<div class="lollypop-top__item"></div>
<div class="lollypop-top__item"></div>
<div class="lollypop-top__item"></div>
<div class="lollypop-top__item"></div>
</div>
<div class="second__half">
<div class="lollypop-top__item"></div>
<div class="lollypop-top__item"></div>
<div class="lollypop-top__item"></div>
<div class="lollypop-top__item"></div>
<div class="lollypop-top__item"></div>
<div class="lollypop-top__item"></div>
<div class="lollypop-top__item"></div>
<div class="lollypop-top__item"></div>
<div class="lollypop-top__item"></div>
<div class="lollypop-top__item"></div>
<div class="lollypop-top__item"></div>
<div class="lollypop-top__item"></div>
<div class="lollypop-top__item"></div>
<div class="lollypop-top__item"></div>
</div>
</div>
</div>
</div>
.frame {
position: absolute;
display: flex;
justify-content: center;
top: 50%;
left: 50%;
width: 400px;
height: 400px;
margin-top: -200px;
margin-left: -200px;
border-radius: 2px;
box-shadow: 4px 8px 16px 0 rgba(0,0,0,0.1);
overflow: hidden;
background: #F5CE51;
color: #333;
font-family: 'Open Sans', Helvetica, sans-serif;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
}
.lollypop-top {
position: relative;
height: 150px;
width: 150px;
background-color: #ccc;
border-radius: 100%;
overflow: hidden;
.lollypop-top__item {
position: absolute;
height: 150px;
width: 150px;
top: -50%;
border-radius: 100%;
transform-origin: bottom;
background-color: #fff;
&:nth-child(odd) {
background-color: #D70606;
}
&:nth-child(1) {
transform: rotate(30deg);
}
&:nth-child(2) {
transform: rotate(60deg);
}
&:nth-child(3) {
transform: rotate(90deg);
}
&:nth-child(4) {
transform: rotate(120deg);
}
&:nth-child(5) {
transform: rotate(150deg);
}
&:nth-child(6) {
transform: rotate(180deg);
}
&:nth-child(7) {
transform: rotate(210deg);
}
&:nth-child(8) {
transform: rotate(240deg);
}
&:nth-child(9) {
transform: rotate(270deg);
}
&:nth-child(10) {
transform: rotate(300deg);
}
&:nth-child(11) {
transform: rotate(330deg);
}
&:nth-child(12) {
transform: rotate(360deg);
}
&:nth-child(13) {
transform: rotate(390deg);
}
&:nth-child(14) {
transform: rotate(420deg);
}
}
}
.first__half,
.second__half {
position: absolute;
left: 0;
top: 0;
height: 100%;
overflow: hidden;
}
.first__half {
width: 50%;
}
.second__half {
right: 0;
width: 50%;
transform: rotate(180deg);
transform-origin:right center;
}