【问题标题】:CSS Circle with fully interactive & accessible pie wedges? [duplicate]具有完全交互式和可访问的饼形楔形的 CSS Circle? [复制]
【发布时间】:2021-03-04 10:15:25
【问题描述】:

目标:

如何在不使用图表库的情况下在 CSS 中创建具有可访问的交互式饼形楔形的圆圈(通常会创建完全不可交互或不可访问的饼形楔形)

如果您需要将按钮创建为圆形楔形怎么办?

欢迎所有答案,但我写这个 Jeopardy style 问题是为了帮助其他人解决我的问题。

【问题讨论】:

  • SO 不是写文章的正确地方。您所说的问题过于宽泛,缺乏重点。
  • 怎么太宽泛了?它描述了特定要求的答案。
  • 请重新打开这个问题/答案 - 前两个“重复”问题不相关:第一个问题问得太差以至于你找不到它(至少我没有,也没有所以当我写这个问题时)第二个问题也被关闭了 - 因为它问得太差了!
  • 我添加了更多重复的,还有更多(不能添加超过 5 个)

标签: javascript html css geometry pie-chart


【解决方案1】:

解决方案:

我到处搜索,找到了很多解决方案——所有这些都非常肤浅,它们填充了设计方面,但最终没有给你任何可用或可访问的元素。

[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 楔形支撑,我在自己的项目中写了一些条件,我很乐意分享。

如果您有兴趣,这很可能很容易适应一个简单的饼图引擎 - 但我没有时间弄清楚细节。

希望有需要的人找到这个,它会有所帮助:-)

【讨论】:

猜你喜欢
  • 2021-10-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-05-04
  • 1970-01-01
  • 2011-02-01
  • 1970-01-01
相关资源
最近更新 更多