解决方案:
我到处搜索,找到了很多解决方案——所有这些都非常肤浅,它们填充了设计方面,但最终没有给你任何可用或可访问的元素。
[tl;dr]Codepen
以最简单的形式创建一个容器,并确保它的溢出是隐藏的,并且它与border-radius: 50% 是一个完美的圆圈
在标记中,您可以添加内部元素 - 它们可以是按钮、div、带有列表的 ul/ol 等...您在其中放入什么并不重要,重要的是 CSS 计算。这是我的示例 HTML
<div class="pie">
<button>
<span class="text">1</span>
</button>
<button>
<span class="text">2</span>
</button>
<button>
<span class="text">3</span>
</button>
</div>
在我的示例中,我将容器命名为 .pie,这是重要的 CSS:
.pie {
border-radius: 50%;
height: 150px;
overflow: hidden;
position: relative;
width: 150px;
}
高度和宽度显然只需要相互匹配,但可以是任何东西。
然后你给内部元素 CSS 以使它们最初都显示为饼图容器的第一季度象限。
button {
bottom: 50%;
height: 100%;
left: 50%;
position: absolute;
transform-origin: bottom left;
width: 100%;
}
你可以将你所拥有的概念化为:
transform-origin 可能在那里看起来不合适,但稍后它是有意义的,并且是整个事情的关键......
制作楔形的最后一个关键是计算将每个正方形转换为楔形。这是通过使用以下的有序组合来完成的:
transform: rotate()
transform: skeyY()
为了进行计算,我们需要知道每个楔子在圆中的度数。比方说
share = 120
这对于我们的 3 个相等份额的示例是正确的,我们需要一个迭代器,让我们使用
i = 0
(我相信你可以看到这将如何转化为任意数量的楔形的动态 JS 函数......)
现在每个楔子按出现顺序计算如下:
rotate = (i * share)deg
skeyY = (share - 90)deg
i++
减去 90,因为楔形开始于正方形
基本上,旋转将其左下角(即饼图的中心)上的楔形旋转为其前面所有楔形的度数。 skewY 将楔形从矩形倾斜到正确度数的楔形。
然后我们必须抵消内部元素上的 skewY 和旋转(特别是如果你想要文本在那里),计算是:
rotate = (share / 2)deg
skewY(-(share - 90)deg
这将反转转换并将文本旋转到出现相对于包含“楔形”的 45 度。
现在您的标记将如下所示:
<div class="pie">
<button style="transform: rotate(0deg) skewY(30deg)">
<span style="transform: skewY(-30deg) rotate(60deg)" class="text">1</span>
</button>
<button style="transform: rotate(120deg) skewY(30deg)">
<span style="transform: skewY(-30deg) rotate(60deg)" class="text">2</span>
</button>
<button style="transform: rotate(240deg) skewY(30deg)">
<span style="transform: skewY(-30deg) rotate(60deg)"class="text">3</span>
</button>
</div>
公平警告
顺序或变换属性很重要。换个顺序试试,不行。我没有足够的时间来弄清楚这一点,所以如果这里有人想解释,那就去吧!
这是它最终的样子,有一点额外的 CSS,所以你可以更好地看到结果。
.pie {
background-color: rgba(0,0,0,0.5);
position: relative;
width: 150px;
height: 150px;
border-radius: 50%;
overflow: hidden;
}
.pie button,
.pie button:focus {
outline: none;
background-color: lightgreen;
border: thin solid white;
position: absolute;
cursor: pointer;
width: 100%;
height: 100%;
left: 50%;
bottom: 50%;
transform-origin: bottom left;
transition: all 200ms ease-out;
}
.pie button:hover,
.pie button:focus:hover {
box-shadow: 0px 0px 10px 5px #515151;
z-index: 1;
}
.pie button .text,
.pie button:focus .text {
position: absolute;
bottom: 30px;
padding: 0px;
color: #333;
left: 30px;
}
<div class="pie">
<button style="transform: rotate(0deg) skewY(30deg)">
<span style="transform: skewY(-30deg) rotate(60deg)" class="text">1</span>
</button>
<button style="transform: rotate(120deg) skewY(30deg)">
<span style="transform: skewY(-30deg) rotate(60deg)" class="text">2</span>
</button>
<button style="transform: rotate(240deg) skewY(30deg)">
<span style="transform: skewY(-30deg) rotate(60deg)"class="text">3</span>
</button>
</div>
如果你有兴趣让它动态化,这里有一个非常简单的实现:
codepen
响应能力
是的 - 您只需要更改饼图的宽度和高度。可以是 css var,也可以是媒体查询...
@media (min-width: 1920px) {
.pie {
height: 350px;
width: 350px;
}
}
注意事项和想法...
唯一真正需要注意的是,您只能使用至少三个楔形。最大值实际上取决于楔形的内部内容以及“馅饼”的整体大小...
如果您确实需要 1 和 2 楔形支撑,我在自己的项目中写了一些条件,我很乐意分享。
如果您有兴趣,这很可能很容易适应一个简单的饼图引擎 - 但我没有时间弄清楚细节。
希望有需要的人找到这个,它会有所帮助:-)