2

This is (almost) what I want to create:

HTML

<div class="hexagon1">
  <div class="hexagon-in1">
    <div class="hexagon-in2">
    </div>
  </div>
</div>

CSS

.hexagon1 {
  overflow: hidden;
  visibility: hidden;
  -webkit-transform: rotate(120deg);
  -moz-transform: rotate(120deg);
  -ms-transform: rotate(120deg);
  -o-transform: rotate(120deg);
  transform: rotate(120deg);
  width: 400px;
  height: 200px;
  margin: 0 0 0 -80px;
}

.hexagon-in1 {
    overflow: hidden;
    width: 100%;
    height: 100%;
    -webkit-transform: rotate(-60deg);
    -moz-transform: rotate(-60deg);
    -ms-transform: rotate(-60deg);
    -o-transform: rotate(-60deg);
    transform: rotate(-60deg);
}

.hexagon-in2 {
    width: 100%;
    height: 100%;
    background-repeat: no-repeat;
    background-position: 50%;
    background-image: url(http://placekitten.com/240/240);
    visibility: visible;
    -webkit-transform: rotate(-60deg);
    -moz-transform: rotate(-60deg);
    -ms-transform: rotate(-60deg);
    -o-transform: rotate(-60deg);
    transform: rotate(-60deg);
}

The problem is, that I need a border on the hexagon and if possible I would like to place the picture inside an img-tag. I tried adding the border on either div but I only got a border on top and bottom of the hexagon because of the visibility-hidden or the overflow-hidden attribute.

This is what I've found so far while googling:

http://csshexagon.com/

https://www.queness.com/post/13901/create-beautiful-hexagon-shapes-with-pure-css3

https://github.com/web-tiki/responsive-grid-of-hexagons

I've also found some questions concerning this matter here on Stackoverflow but neither of them explained how exactly you could create a hexagon. Also the hexagons in the examples are all standing on an edge, which is not what I want (as demonstrated in the code). I only need one hexagon and not a grid as well.

When I tried to change the styles of the examples it always ended in a desastrous chaos. This is why I would like to know how to create and to calculate the divs which are used to create a hexagon with border and a picture inside.

Which rate does the width have to the height?

How can I create a border that has the same width on each side?

Where do I have to place the picture as background-image?

How big should the picture be (in percentage to the divs)?

What transformations do you really need to create the hexagon? (I saw an example which used scale, rotate and translate to get a picture inside)

How can the rotation be calculated?

How do I calculate the margin needed?

As I am quite the novice in web-designing can someone explain this as simple as possible? It would suffice if someone can show me according to the example-code above how the numbers are calculated. I know that a hexagon has an inner angle of 120° and that's about it.

Thanks for your help in anticipation. :)

EDIT

Another page I found about hexagons but only to create the shape and not really putting either an image in it nor having a border around it:

http://jtauber.github.io/articles/css-hexagon.html

Kathara
  • 1,226
  • 1
  • 12
  • 36
  • So you want a hexagon with a border and image in it? – Sahil Dhir Apr 03 '17 at 11:56
  • Did you refer this ? http://stackoverflow.com/questions/31854185/how-to-add-border-in-my-clip-path-polygon-css-style – Sahil Dhir Apr 03 '17 at 12:05
  • @SahilDhir yes, like the example http://csshexagon.com/ but turned for about 30 degrees (?) so it wouldn't stand on the edge but on a side. I looked over it just now and it seems quite complicated. Looking over it I don't really see an explanation on how to create it either. I will study it however and respond as soon as I have. Thanks for the hint. – Kathara Apr 03 '17 at 12:11
  • Yes its a bit complex for someone who is new to web designing.. Just do some research and you can master .. Happy coding ;) – Sahil Dhir Apr 03 '17 at 12:13
  • @SahilDhir Problem is I don't have too much time to research on this. I've got to complete a design in which I need this. Also it should be supported by all (most) browsers if possible. So the easier the better. Still it seems quite interesting and I'm looking into it. Thanks anyway. ;) If anyone else can explain me how to create a hexagon, I'd really appreciate it. – Kathara Apr 03 '17 at 12:23

3 Answers3

2

I will refer you to go with SVG approach to create this shape. Its really easy and also if you are considering a responsive web layout it can be achieved with this easily.

Reason for this approach -

1. You donot have to write much css.

2. Inline SVG is the modern web approach .

3. Scalable and durable. 4. Responsive

The polygon tag in the svg makes the shape that you want and with the css we can target the things we want to achieve like border in this case. Image has been linked using pattern.

Below is the snippet with example of what you need.

svg {
  width: 30%;
  margin: 0 auto;
}

#hex {
  stroke-width: 2;
  stroke: red;
}
<svg viewbox="0 0 100 100" version="1.1" xmlns="http://www.w3.org/2000/svg">
  <defs>
    <pattern id="img" patternUnits="userSpaceOnUse" width="100" height="100">
      <image xlink:href="https://dummyimage.com/600x400/red/fff" x="-25" width="150" height="100" />
    </pattern>
  </defs>
  <polygon id="hex" points="50 1 95 25 95 75 50 99 5 75 5 25" fill="url(#img)"/>
</svg>

<svg viewbox="0 0 200 200" version="1.1" xmlns="http://www.w3.org/2000/svg">
    <defs>
      <pattern id="img" patternUnits="userSpaceOnUse" width="100" height="100">
        <image xlink:href="https://farm4.staticflickr.com/3165/5733278274_2626612c70.jpg" x="-40" width="150" height="100" />
      </pattern>
    </defs>
    <polygon id="hex" points="25 8 75 8 100 50 75 92 25 92 0 50" fill="url(#img)" />
  </svg>
Sahil Dhir
  • 4,162
  • 1
  • 13
  • 33
  • I've never used an SVG before and I think it's really a nice solution although I have to say I'll have to look into SVGs a little further as I don't understand exactly how it works yet. When trying to enter another picture without background and which maybe is either bigger or smaller than the one you used in your example it gets positioned quite awkwardly. What is interesting as well is that when you change the numbers in the viewbox attribute to bigger numbers the polygon gets smaller ^^ I will play around a little with it but thanks already :) – Kathara Apr 04 '17 at 07:03
  • Can you maybe explain to me how I can get the picture to be centered in the polygon? Is there a trick to it? I've achieved it with trying but maybe it can be calculated??! – Kathara Apr 04 '17 at 07:14
  • Sadly I won't be able to use the svg tag, as the images inside the hexagon are being provided by a backend and my boss just told me that it will be unable to provide the needed structure, unfortunately. But I will definately learn more about SVG as I find it really interesting and it might be useful in the future. :) – Kathara Apr 04 '17 at 08:07
  • 1
    For centering the image you can set x,y cordinates or play with transform:translate(x,y) property.. – Sahil Dhir Apr 04 '17 at 09:53
  • Thats sad to hear that you cannot use this .. I can understand the back end logic trouble with this.. There are other solutions but for that you will have to write a lot of css codes. – Sahil Dhir Apr 04 '17 at 09:55
  • The CSS-Codes aren't really a problem. It just really has to work with the backend which with SVG it won't. I'll just have to find another way of getting a hexagon shape with an img inside. I'll probably have to search a little further on google. Maybe I'll come across a good solution... – Kathara Apr 04 '17 at 11:28
  • Let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/139846/discussion-between-sahil-dhir-and-kathara). – Sahil Dhir Apr 04 '17 at 11:58
1

Important Note

Be informed that this solution does not work for those who want to create something similar supported by all browsers as for the time being IE does not support the clip-path-property used in this example!!


I've found a way to do it thanks to @SahilDhir although it's more of a workaround:

HTML

<div class="poligon">
  <img src="http://lorempixel.com/g/600/400/">
</div>

CSS

.poligon {
  display: inline-block;
  position: relative;
  width: 200px;
  height: 180px;
  background: red;
  box-sizing: border-box;
  -webkit-clip-path: polygon(0% 50%, 25% 0%, 75% 0%, 100% 50%, 75% 100%, 25% 100%);
  -moz-clip-path: polygon(0% 50%, 25% 0%, 75% 0%, 100% 50%, 75% 100%, 25% 100%);
}

.poligon img {
  position: absolute;
  top: 2px; /* equal to border thickness */
  left: 2px; /* equal to border thickness */
  width: 196px; /* container height - (border thickness * 2) */
  height: 176px; /* container height - (border thickness * 2) */
  -webkit-clip-path: polygon(0% 50%, 25% 0%, 75% 0%, 100% 50%, 75% 100%, 25% 100%);
  -moz-clip-path: polygon(0% 50%, 25% 0%, 75% 0%, 100% 50%, 75% 100%, 25% 100%);
}

Note that I did not calculate much here, but rather tried achieving a six-sided figure.

I will have the problem that my picture will have a transparent background, but I thought that I might produce a linear gradient to fill the background polygon. I will have to try that out first though ^^

I will not mark this as the final answer as my questions have not yet been answered truly. I still want to be able to create a hexagon as the one in the example I gave above where I would be able to adapt the heights and widths as well as the border thicknesses the way I want.

EDIT

As I did not find a better solution I have improved the one here and figured out the calculations needed:

HTML

<div class="poligon">
  <div class="hex-background">
    <img src="https://img.clipartfest.com/953d8641fe933437bbc41d48e6fc8492_yellow20stars20clipart-christmas-stars-clipart-without-background_532-506.png">
  </div>
</div>

CSS

.poligon {
  display: inline-block;
  position: relative;
  width: 120px;
  height: 103.92px; /* width * 0.866 */
  background: red;
  box-sizing: border-box;
  -webkit-clip-path: polygon(0% 50%, 25% 0%, 75% 0%, 100% 50%, 75% 100%, 25% 100%);
  -moz-clip-path: polygon(0% 50%, 25% 0%, 75% 0%, 100% 50%, 75% 100%, 25% 100%);
}

.hex-background {
  position: absolute;
  background-color: white;
  top: 2px; /* equal to border thickness */
  left: 2px; /* equal to border thickness */
  width: 116px; /* container width - (border thickness * 2) */
  height: 99.92px; /* container height - (border thickness * 2) */
  -webkit-clip-path: polygon(0% 50%, 25% 0%, 75% 0%, 100% 50%, 75% 100%, 25% 100%);
  -moz-clip-path: polygon(0% 50%, 25% 0%, 75% 0%, 100% 50%, 75% 100%, 25% 100%);
}

.poligon img {
  position: absolute;
  width: 116px; /* container width - (border thickness * 2) */
  height: 99.92px; /* container height - (border thickness * 2) */
  -webkit-clip-path: polygon(0% 50%, 25% 0%, 75% 0%, 100% 50%, 75% 100%, 25% 100%);
  -moz-clip-path: polygon(0% 50%, 25% 0%, 75% 0%, 100% 50%, 75% 100%, 25% 100%);
}

The clip-path part is correct if you want a same-sided hexagon.

Same-sided hexagon in colors

With the picture above you can see how I found those numbers ;) If you have further questions about this, don't hesitate to ask. I'll try to explain it the best I can.

Kathara
  • 1,226
  • 1
  • 12
  • 36
0

I needed something similar, and the easiest way to do it is with two hexagons, one on top of the other.

Using the shapes provided by The Shapes of CSS:

#hexagon1 {
    width: 100px;
    height: 55px;
    background: red;
    position: absolute;
  z-index: 2;
}
#hexagon1:before {
    content: "";
    position: absolute;
    top: -25px;
    left: 0;
    width: 0;
    height: 0;
    border-left: 50px solid transparent;
    border-right: 50px solid transparent;
    border-bottom: 25px solid red;
}
#hexagon1:after {
    content: "";
    position: absolute;
    bottom: -25px;
    left: 0;
    width: 0;
    height: 0;
    border-left: 50px solid transparent;
    border-right: 50px solid transparent;
    border-top: 25px solid red;
}

#hexagon2 {
    width: 101px;
    height: 56px;
    background: black;
    position: relative;
  z-index: 1;
}
#hexagon2:before {
    content: "";
    position: absolute;
    top: -26px;
    left: 0;
    width: 0;
    height: 0;
    border-left: 51px solid transparent;
    border-right: 51px solid transparent;
    border-bottom: 26px solid black;
}
#hexagon2:after {
    content: "";
    position: absolute;
    bottom: -26px;
    left: 0;
    width: 0;
    height: 0;
    border-left: 51px solid transparent;
    border-right: 51px solid transparent;
    border-top: 26px solid black;
}

Here's a CodePen I made for you: http://codepen.io/vogelbeere/pen/peYjNe

Yvonne Aburrow
  • 2,602
  • 1
  • 17
  • 47
  • This is the 12-pointed star with a border that I made for my mobile app: http://codepen.io/vogelbeere/pen/peYgOq – Yvonne Aburrow Apr 03 '17 at 16:02
  • It's not a bad approach but I realised with the code from above that putting one div on top of another doesn't result in a constant border meaning that the border doesn't have the same thickness on each side. I don't why exactly this happens, but I can imagine it's because of the resolution or the rendering of the browser. – Kathara Apr 04 '17 at 07:00
  • yes, I am not quite sure why it does it. For my twelve-pointed star, it gave a slightly embossed effect, which I liked, so that was OK. – Yvonne Aburrow Apr 04 '17 at 16:08
  • 1
    Yes, with the star it looks like it was 3d. I have another problem with that kind of solution as the picture inside might or might not have transparent background. If it has I would have to put 3 hexagons on top of each other, one for the border, one to set the inside to the same color as the background and the third with the picture which is quite complicated... Thank you very much though for your response. :) – Kathara Apr 05 '17 at 07:15
  • yes I realised afterwards that it would not quite work with putting an image in the hexagon – Yvonne Aburrow Apr 05 '17 at 12:06