Hia folks, so for today I’ll be looking into making some hexagons with borders created with only CSS, HTML and a bit of jquery.
In the old days, we had to use images to get some decent looking shapes. Which also lead to static and hard to update designs.
Now we can have this :
Now there is a few hexagon tutorials out there but most of them have solid hexagons which are hell to get borders on and even worse to add text to. So this is the idea
The hexagon shape and how to add borders
- We take a rectangle with some special dimentions :
2) we duplicate it 2 times and add a rotation of -60° and 60°
3) We have a hexagon. And more important, we have the left and right borders of each of our rectangles making up the hex. This enables us to add a bit of CSS to color the borders and add any width we want.
The HTML and CSS Code
So, to keep things clean, we will create a Wrapper with a set size and then some some inner divs to calculate our dimentions :
To keep things managable, I also added a page container to take care of the top of the screen and a row container for the diffrent rows :
1 2 3 4 5 6 7 8 |
<div id="container"> <div class="row fullWidth" id="firstRow"> <div class="hexWrapper"> <div class="hexagon"> </div> </div> </div> </div> |
We also need some CSS FOO to take care of all of it .
To create our 2 other rectangles, we will use the CSS property “before” and “after”. This makes things a bit more fiddly with objects being displayed one over the other but makes the html code much more readable. and the layers are nothing that a bit of manual z-indexing can’t fix.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 |
.hexWrapper { text-align: center; margin: 0px; position: relative; display: inline-block; width: 150px; height: 150px; min-width: 150px; min-height: 150px; float:left; } .hexagon { height: calc(100%/1.732050807); width: 100%; background-color: #ffffff; display:inline-block; } .hexagon:before, .hexagon:after { content: ""; position: absolute; background-color: inherit; height: inherit; width: inherit; left: -1px; right: -1px; top: 0; bottom: 0; } .hexagon:before { transform: rotateZ(60deg); } .hexagon:after { transform: rotateZ(120deg); } .hexagon, .hexagon:before, .hexagon:after { box-sizing: content-box; border: solid 2px #B2C944; border-top-width: 0; border-bottom-width: 0; z-index: -1; /*We need to force the z-index so we can put some text over*/ } #container{ padding-top: 60px; width:100%; min-width:910px; /* so the page doesn't get too small. This should be done better with media queries*/ } .row{ clear:both; /*to reset all the configs*/ float:left; display: flex; /* using some flex to aline to center */ justify-content: center; overflow:hidden; /*this is for after, when we add more hex's*/ padding-top:45px; /* To take care of the top part of the hex, needs changing if we change the size on the wrapper*/ position:relative; } .fullWidth{ width: 100%; } |
and we get this :
the best part is that we can change the size in the wrapper. Then all is left to do is a bit of placement with the row padding-top.
Hexagons with borders inside hexagons with borders :
We can also use the same idea to add some inner hexes and some text:
1 2 3 4 5 6 7 8 9 10 |
<div id="container"> <div class="row fullWidth" id="firstRow"> <div class="hexWrapper"> <div class="hexagon"> <div class="hexagon inner"></div> </div> <div class="text"><p>Texte</p></div> </div> </div> </div> |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 |
.hexWrapper { text-align: center; margin: 0px; position: relative; display: inline-block; width: 150px; height: 150px; min-width: 150px; min-height: 150px; float:left; } .hexagon { height: calc(100%/1.732050807); width: 100%; background-color: #ffffff; display:inline-block; } .hexagon:before, .hexagon:after { content: ""; position: absolute; background-color: inherit; height: inherit; width: inherit; left: -1px; right: -1px; top: 0; bottom: 0; } .hexagon:before { transform: rotateZ(60deg); } .hexagon:after { transform: rotateZ(120deg); } .hexagon, .hexagon:before, .hexagon:after { box-sizing: content-box; border: solid 2px #B2C944; border-top-width: 0; border-bottom-width: 0; z-index: -1; /*We need to force the z-index so we can put some text over*/ } #container{ padding-top: 60px; width:100%; min-width:910px; /* so the page doesn't get too small. This should be done better with medai queries*/ } .row{ clear:both; /*to reset all the configs*/ float:left; display: flex; /* using some flex to aling to center */ justify-content: center; overflow:hidden; /*this is for after, when we add more hex's*/ padding-top:45px; /* To take care of the top part of the hex, needs changing if we change the size on the wrapper*/ position:relative; } .fullWidth{ width: 100%; } .hexagon.inner{ height: 100%; transform: scale(.8, .8); position: relative; /*this is needed to make z-index work*/ margin:0; margin-left:-2px; /*taking back the border pixels*/ } .hexagon.inner, .hexagon.inner:before, .hexagon.inner:after{ z-index:10; } .text{ z-index: 50; position: absolute; margin-left: 15%; margin-right: 15%; top: 0; left: 0; width:70%; height:60%; display: flex; justify-content: center; align-items: center; } |
Adding some text
The text is in the wrapper div so it will follow the layout nicely. We just need to position it properly depending on the size of the hexes. If you look on the inspector, the wrapper is aligned with the 1st rectangle so we just play around to get the width, height and padding of the textbox to the right size :
Just chuck in a flexbox to get the centering sorted and we have hexagons with borders we can duplicate to our heat’s content.
Pingback: Hexagones part 2 – StarbugStone's Dev Blog