Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Creating a flexible, space filling beehive using CSS

I'm trying to create some sort of heat map for the network I'm working on. I wanted to use a beehive for this as it looks fancy and gives me great space utilization.

if found this website where i figured out how to use hexagons with pure CSS. but it was heavily reliant rows and offsets. my entire UI is KnockoutJS-driven and has dynamic number of PCs on the network at any given time. (mostly docker containers going up or down).

Clusters can vary between 1 and n+1 nodes.

I looked at this website: CSS Hexagon and found several solutions to manage the hexagons but all of them are REALLY limited in their dynamic use.

This is the intended code:

 <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>

Based on that it would give the hexagon a color that would indicate up / down

I've whipped up a non knockout fiddle with my flexbox idea, but I don't truly understand flexbox that well so it's obviously not working: 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>

The problems I'm running into are:

  1. How do I scale these divs dynamically regardless of number, and occupying maximum space.
  2. How do I use a pure CSS solution to make sure that all even "rows" are offset by half a hexagon.

!! UPDATE !!

So i've added the concept of pre-determined rows: fiddle I'm still looking for a way to make the row offset depend on the ".hex" class width. and have the hex class scale with the amount of elements. but i think the grid itself looks really good now.

like image 636
Puzzle84 Avatar asked Jan 10 '17 19:01

Puzzle84


Video Answer


1 Answers

So if you need 3 hexagons per row :nth-child can help to set the margin once every 2 rows.

To size your elements, you may use percentage, but you will have to use pseudo without borders , but a background and a rotation instead.

example:

#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>
like image 158
G-Cyrillus Avatar answered Oct 05 '22 15:10

G-Cyrillus