【问题标题】:Creating a flexible, space filling beehive using CSS使用 CSS 创建一个灵活的、填充空间的蜂箱
【发布时间】:2017-05-25 09:33:28
【问题描述】:

我正在尝试为我正在处理的网络创建某种热图。 我想为此使用一个蜂箱,因为它看起来很漂亮,并且可以很好地利用空间。

如果找到这个网站,我在该网站上找到了如何使用纯 CSS 的六边形。 但它严重依赖行和偏移量。我的整个 UI 都是 KnockoutJS 驱动的,并且在任何给定时间在网络上都有动态数量的 PC。 (主要是 docker 容器上升或下降)。

集群可以在 1 到 n+1 个节点之间变化。

我看了这个网站:CSS Hexagon 并找到了几种管理六边形的解决方案,但它们的动态使用都非常有限。

这是预期的代码:

 <div class="panel-body>
      {{noescape "<!-- ko foreach: { data: vm.dash().nodes, as: 'node' } -->" }}
          <span class="flex-span" data-bind="attr: { 'id': node.id }, css: { up: node.Status == 2, down: node.Status != 2 }">&#x2B22;</span>
      {{noescape "<!-- /ko -->"}}
 </div>

基于此,它会给六边形一个颜色来指示向上/向下

我已经对我的 flexbox 想法提出了一个非淘汰的小提琴,但我并不真正了解 flexbox,所以它显然不起作用:Fiddle

#container {
  max-width:400px;
  max-height:400px;
}

.hex:before {
    content: " ";
    width: 0; height: 0;
    border-bottom: 30px solid #6C6;
    border-left: 52px solid transparent;
    border-right: 52px solid transparent;
    position: absolute;
    top: -30px;
    flex-shrink: 1;
    flex-grow:1;
    flex-basis: 130px;
}

.hex {
    margin-top: 30px;
    width: 104px;
    height: 60px;
    background-color: #6C6;
    position: relative;
    float:left;
    margin-bottom:30px;
    flex-shrink: 1;
    flex-grow:1;
    flex-basis: 130px;
}

.hex:after {
    content: "";
    width: 0;
    position: absolute;
    bottom: -30px;
    border-top: 30px solid #6C6;
    border-left: 52px solid transparent;
    border-right: 52px solid transparent;
    flex-shrink: 1;
    flex-grow:1;
    flex-basis: 130px;
}
<div id="container">
  <div class=hex></div>
  <div class=hex></div>
  <div class=hex></div>
  <div class=hex></div>
  <div class=hex></div>
  <div class=hex></div>
  <div class=hex></div>
  <div class=hex></div>
  <div class=hex></div>
  <div class=hex></div>
</div>

我遇到的问题是:

  1. 如何动态缩放这些 div,而不考虑数量,并占用最大空间。
  2. 如何使用纯 CSS 解决方案来确保所有偶数“行”都偏移半个六边形。

!!更新!!

所以我添加了预定行的概念:fiddle 我仍在寻找一种方法来使行偏移量取决于“.hex”类宽度。并具有元素数量的十六进制类比例。但我认为网格本身现在看起来非常好。

【问题讨论】:

  • 理想情况下,我会使用 ::even-line 之类的东西,但我只能找到 ::first-line 来对六边形进行偏移。
  • 如果您已经在使用 Knockout,为什么还需要纯 CSS 解决方案?我建议制作一个淘汰组件并将您的 css 属性绑定到根据节点数计算缩放的计算属性。
  • 没有真正的原因,我只是想象 css 对 ui 加载时间更好。如果您的 ui 是响应式的,您将如何处理偶数/奇数行逻辑?
  • 这是你试图做的吗? jsfiddle.net/ndy71xos/1:nth-child(xn)适用于第 3 行)。要在大小变化时使六边形变大/缩小,请不要使用像素,但最终 % .Flex 不会有助于调整 .hex 的高度或伪元素
  • 这正是我想要的 GCyrillus,至于 % 这很好,但我想我必须制定一些关于何时使 % 更小的规则?这可以自动完成吗?假设我将其设置为 33%,所以我连续有 3 个。 CSS 是否知道行何时超过了父级的边界? % 应该缩小到 25%?

标签: html css knockout.js flexbox


【解决方案1】:

因此,如果您需要每行 3 个六边形:nth-​​child 可以帮助每 2 行设置一次边距。

要调整元素的大小,您可以使用百分比,但您必须使用不带边框的伪,而是使用背景和旋转。

示例:

#container {
  max-width: 400px;
  max-height: 400px;
  border: solid;padding:1px;
}
/* demo*/
#container:hover {

  max-width: 600px;
  max-height: 600px;
 }/* */
.hex {
  margin-top: 8%;
  width: 28%;
  padding: 8% 0;
  background-color: #6C6;
  position: relative;
  margin-bottom: 3px;
  margin-right: 0px;
  display: inline-flex;
  position: relative;
  align-items: center;
  justify-content: center;
}
.hex:after,
.hex:before {
  content: "";
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0%;
  background: inherit;
  transform: rotate(60deg);
}
.hex:after {
  transform: rotate(-60deg)
}
.hex:nth-child(6n+1) {
  margin-left: 14%;
}
<div id="container">
  <div class=hex></div>
  <div class=hex></div>
  <div class=hex></div>
  <div class=hex></div>
  <div class=hex></div>
  <div class=hex></div>
  <div class=hex></div>
  <div class=hex></div>
  <div class=hex></div>
  <div class=hex></div>
</div>

【讨论】:

  • 几乎完美,但当更多元素添加到容器时,它不会缩小。它溢出而不是使六边形变小。
  • @Puzzle84 恐怕这部分无法通过 CSS 实现,对于这种行为,canvas 和 javascript 会更合适:(除非你可以混合使用 vh 和 vw 。 ...
  • @vals 它总是发生在我身上 :)
  • 好吧,我会接受这个答案作为获胜的答案,然后看看我是否可以用 javascript 稍微优雅地解决它:)
  • jsfiddle.net/sdwttp31/1 是我想要的样子。试图找出一种方法来使用 hex 元素来使整个事物规模化。
【解决方案2】:

我认为基于行号(偶数/奇数)在 flex 容器中应用样式是不可能的。

所以,我将六边形设置在同一行重叠,并确保在一行中总是有偶数个六边形(由于负边距,偶数没有空间要求,所以它们会总是合适的)。

这是我的解决方案。将鼠标悬停在容器上以更改宽度。

#container {
  max-width: 410px;
  max-height: 400px;
  display: flex;
  flex-wrap: wrap;
  border: solid 1px green;
  transition: max-width 6s;
}
#container:hover {
  max-width: 800px;
}
.hex {
  margin-top: 30px;
  height: 60px;
  background-color: #6C6;
  position: relative;
  margin-bottom: 90px;
  flex-shrink: 0;
  flex-grow: 0;
  flex-basis: 104px;
}
.hex:nth-child(even) {
  background-color: blue;
  transform: translateY(90px);
  margin-left: -52px;
  margin-right: -52px;
}
.hex:before {
  content: " ";
  width: 0;
  height: 0;
  border-bottom: 30px solid #6c6;
  border-left: 52px solid transparent;
  border-right: 52px solid transparent;
  position: absolute;
  top: -30px;
  flex-shrink: 1;
  flex-grow: 1;
  flex-basis: 130px;
}
.hex:after {
  content: "";
  width: 0;
  position: absolute;
  bottom: -30px;
  border-top: 30px solid #6c6;
  border-left: 52px solid transparent;
  border-right: 52px solid transparent;
  flex-shrink: 1;
  flex-grow: 1;
  flex-basis: 130px;
}
.hex:nth-child(even):before {
  border-bottom-color: blue;
}
.hex:nth-child(even):after {
  border-top-color: blue;
}
<div id="container">
  <div class="hex"></div>
  <div class="hex"></div>
  <div class="hex"></div>
  <div class="hex"></div>
  <div class="hex"></div>
  <div class="hex"></div>
  <div class="hex"></div>
  <div class="hex"></div>
  <div class="hex"></div>
  <div class="hex"></div>
  <div class="hex"></div>
</div>

【讨论】:

  • 从包装的角度来看,几乎正是我想要的。但不应该限制绿色和蓝色具有相同数量的元素。基本上,第 2 行蓝色应该是上面一行中剩余的 2 个绿色
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-05-09
  • 1970-01-01
  • 1970-01-01
  • 2011-02-05
  • 1970-01-01
  • 2012-11-26
相关资源
最近更新 更多