Create a flexible, space-filling hive using CSS

I am trying to create some kind of heat map for the network I'm working on. I wanted to use the hive for this because it looks fancy and gives me more freedom to use.

if I found this site where I figured out how to use hexagons with pure CSS. but these were highly dependent lines and offsets. My entire user interface is powered by KnockoutJS and has a dynamic number of PCs on the network at any given time. (mostly docker containers go up or down).

Clusters can vary from 1 to n + 1 nodes.

I looked at this site: CSS Hexagon and found several solutions for managing hexagons, but all of them are REALLY limited in their dynamic use.

This is the assigned 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 this, it will give a hexagon color that points up / down

I hacked a knockout script with my idea of โ€‹โ€‹flexbox, but I really don't understand flexbox, so it obviously doesn't work: 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 issues I am facing are as follows:

  • How to scale these divs dynamically regardless of number and occupy maximum space.
  • How to use a pure CSS solution to make sure that all even "lines" are offset by half the hexagon.

!! UPDATE !!

So, I added the concept of predefined lines: fiddle I'm still looking for a way to make the line offset dependent on the width of the ".hex" class. and have a hex class scale with the number of elements. but I think the grid itself looks really good.

+6
source share
2 answers

So, if you need 3 hexagons per line: nth-child can help set the margin once every 2 lines.

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

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> 
+2
source

I donโ€™t think you can apply style in flex container based on line number (even / odd).

So, I set the hexagons overlapping on the same line, and guaranteed that there would always be an even number of hexagons in the line (even of them do not have space requirements due to negative fields, so they will always fit).

Here is my solution. Hover over the container to change the width.

 #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> 
+1
source

Source: https://habr.com/ru/post/1013954/


All Articles