Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    text
    copied!<p>(Though Ana's answer came in months after mine, probably using mine as a base to "think from", the fact that she was able to come up with a method using a single <code>div</code> is worth promoting, so <a href="https://stackoverflow.com/a/13069271/369707"><strong>check out her answer too</strong></a>--but note that content in the hex is more limited.)</p> <p>This was a truly amazing question. Thank you for asking it. The great thing is the fact that:</p> <h2><a href="http://jsfiddle.net/mqyCb/154/" rel="nofollow noreferrer">This Fiddle Proves You Can Do It!</a></h2> <p><a href="http://jsfiddle.net/mqyCb/59/" rel="nofollow noreferrer">Original Fiddle Used</a> (modified in later edit to fiddle link above)--it utilized imgur.com images, which were not seeming to be very reliable in loading, so the new fiddle is using photobucket.com (<em>let me know if there are persistent image loading issues</em>). I've kept the original link because the explanation code below goes with that (there are a few differences in <code>background-size</code> or <code>position</code> to the new fiddle).</p> <p>The idea came to me almost instantly after reading your question, but took some time to implement. I originally tried getting a single "hex" with a single <code>div</code> and just pseudo elements, but as best I could tell, there was no way to just rotate the <code>background-image</code> (which I needed), so I had to add some extra <code>div</code> elements to get the right/left sides of the hex, so that I could then use the pseudo elements as a means of <code>background-image</code> rotation.</p> <p>I tested in IE9, FF, and Chrome. Theoretically any browser supporting CSS3 <code>transform</code> it should work in.</p> <p><strong>First Main Update (added explanation)</strong></p> <p>I have some time now to post some code explanation, so here goes:</p> <p>First, hexagons are defined by 30/60 degree relationships and trigonometry, so those will be the key angles involved. Second, we start with a "row" for the hex grid to reside in. The HTML is defined as (the extra <code>div</code> elements help build the hex):</p> <pre class="lang-html prettyprint-override"><code>&lt;div class="hexrow"&gt; &lt;div&gt; &lt;span&gt;First Hex Text&lt;/span&gt; &lt;div&gt;&lt;/div&gt; &lt;div&gt;&lt;/div&gt; &lt;/div&gt; &lt;div&gt; &lt;span&gt;Second Hex Text&lt;/span&gt; &lt;div&gt;&lt;/div&gt; &lt;div&gt;&lt;/div&gt; &lt;/div&gt; &lt;div&gt; &lt;span&gt;Third Hex Text&lt;/span&gt; &lt;div&gt;&lt;/div&gt; &lt;div&gt;&lt;/div&gt; &lt;/div&gt; &lt;/div&gt; </code></pre> <p>We are going to use <code>inline-block</code> for the hexagon <code>display</code>, but we don't want them to accidentally wrap to the next line and ruin the grid, so <code>white-space: nowrap</code> solves that issue. The <code>margin</code> on this row is going to depend on how much space you want between hex's, and some experimentation may be needed to get what you want.</p> <pre class="lang-css prettyprint-override"><code>.hexrow { white-space: nowrap; /*right/left margin set at (( width of child div x sin(30) ) / 2) makes a fairly tight fit; a 3px bottom seems to match*/ margin: 0 25px 3px; } </code></pre> <p>Using the immediate children of the <code>.hexrow</code> which are just <code>div</code> elements, we form the basis for the hex shape. The <code>width</code> will drive the horizontal of the top of the hex, the <code>height</code> is derived from that number since all the sides are equal length on a regular hexagon. Again, margin is going to depend on spacing, but this is where the "overlap" of the individual hexagons is going to occur to make the grid look occur. The <code>background-image</code> is defined once, right here. The shift left on it is to accommodate at least the added width for the left side of the hex. Assuming you want centered text, the <code>text-align</code> handles the horizontal (of course) but the <code>line-height</code> that matches the <code>height</code> is going to allow for a vertical centering.</p> <pre class="lang-css prettyprint-override"><code>.hexrow &gt; div { width: 100px; height: 173.2px; /* ( width x cos(30) ) x 2 */ /* For margin: right/left = ( width x sin(30) ) makes no overlap right/left = (( width x sin(30) ) / 2) leaves a narrow separation */ margin: 0 25px; position: relative; background-image: url(http://i.imgur.com/w5tV4.jpg); background-position: -50px 0; /* -left position -1 x width x sin(30) */ background-repeat: no-repeat; color: #ffffff; text-align: center; line-height: 173.2px; /*equals height*/ display: inline-block; } </code></pre> <p>Each <em>odd</em> number hex we are going to shift down in relation to the "row" and each <em>even</em> shift up. The shift calculation ( width x cos(30) / 2 ) is also the same as (height / 4).</p> <pre class="lang-css prettyprint-override"><code>.hexrow &gt; div:nth-child(odd) { top: 43.3px; /* ( width x cos(30) / 2 ) */ } .hexrow &gt; div:nth-child(even) { top: -44.8px; /* -1 x( ( width x cos(30) / 2) + (hexrow bottom margin / 2)) */ } </code></pre> <p>We are using 2 child <code>div</code> elements to create the "wings" of the hex. They are sized the same as the main hex rectangle, and then rotated, and pushed "below" the main hex. <code>Background-image</code> is inherited so that the image is the same (of course), because the image in the "wings" is going to be "lined up" to that in the main rectangle. The pseudo elements are used to generate the images, because they need to be "rerotated" back to horizontal (since we rotated the parent <code>div</code> of them to create the "wings").</p> <p>The <code>:before</code> of the first will translate its background the width of the negative amount equal to the main portion of the hex plus the original background shift of the main hex. The <code>:before</code> of the second will change the origin point of the translation and will shift the main width on the x-axis, and half the height on the y-axis.</p> <pre class="lang-css prettyprint-override"><code>.hexrow &gt; div &gt; div:first-of-type { position: absolute; width: 100%; height: 100%; top: 0; left: 0; z-index: -1; overflow: hidden; background-image: inherit; -ms-transform:rotate(60deg); /* IE 9 */ -moz-transform:rotate(60deg); /* Firefox */ -webkit-transform:rotate(60deg); /* Safari and Chrome */ -o-transform:rotate(60deg); /* Opera */ transform:rotate(60deg); } .hexrow &gt; div &gt; div:first-of-type:before { content: ''; position: absolute; width: 200px; /* width of main + margin sizing */ height: 100%; background-image: inherit; background-position: top left; background-repeat: no-repeat; bottom: 0; left: 0; z-index: 1; -ms-transform:rotate(-60deg) translate(-150px, 0); /* IE 9 */ -moz-transform:rotate(-60deg) translate(-150px, 0); /* Firefox */ -webkit-transform:rotate(-60deg) translate(-150px, 0); /* Safari and Chrome */ -o-transform:rotate(-60deg) translate(-150px, 0); /* Opera */ transform:rotate(-60deg) translate(-150px, 0); -ms-transform-origin: 0 0; /* IE 9 */ -webkit-transform-origin: 0 0; /* Safari and Chrome */ -moz-transform-origin: 0 0; /* Firefox */ -o-transform-origin: 0 0; /* Opera */ transform-origin: 0 0; } .hexrow &gt; div &gt; div:last-of-type { content: ''; position: absolute; width: 100%; height: 100%; top: 0; left: 0; z-index: -2; overflow: hidden; background-image: inherit; -ms-transform:rotate(-60deg); /* IE 9 */ -moz-transform:rotate(-60deg); /* Firefox */ -webkit-transform:rotate(-60deg); /* Safari and Chrome */ -o-transform:rotate(-60deg); /* Opera */ transform:rotate(-60deg); } .hexrow &gt; div &gt; div:last-of-type:before { content: ''; position: absolute; width: 200px; /* starting width + margin sizing */ height: 100%; background-image: inherit; background-position: top left; background-repeat: no-repeat; bottom: 0; left: 0; z-index: 1; /*translate properties are initial width (100px) and half height (173.2 / 2 = 86.6) */ -ms-transform:rotate(60deg) translate(100px, 86.6px); /* IE 9 */ -moz-transform:rotate(60deg) translate(100px, 86.6px); /* Firefox */ -webkit-transform:rotate(60deg) translate(100px, 86.6px); /* Safari and Chrome */ -o-transform:rotate(60deg) translate(100px, 86.6px); /* Opera */ transform:rotate(60deg) translate(100px, 86.6px); -ms-transform-origin: 100% 0; /* IE 9 */ -webkit-transform-origin: 100% 0; /* Safari and Chrome */ -moz-transform-origin: 100% 0; /* Firefox */ -o-transform-origin: 100% 0; /* Opera */ transform-origin: 100% 0; } </code></pre> <p>This <code>span</code> houses your text. The <code>line-height</code> is reset to make the lines of text normal, but the <code>vertical-align: middle</code> works since the <code>line-height</code> was larger on the parent. The <code>white-space</code> is reset so it allows wrapping again. The left/right margin can be set to negative to allow the text to go into the "wings" of the hex.</p> <pre class="lang-css prettyprint-override"><code>.hexrow &gt; div &gt; span { display: inline-block; margin: 0 -30px; line-height: 1.1; vertical-align: middle; white-space: normal; } </code></pre> <p>You can individual target rows and cells in those rows to change images, or <code>span</code> text settings, or opacity, or accommodate a larger image (to shift it to the place you want), etc. That is what the following do for the second row.</p> <pre class="lang-css prettyprint-override"><code>.hexrow:nth-child(2) &gt; div:nth-child(1) { background-image: url(http://i.imgur.com/7Un8Y.jpg); } .hexrow:nth-child(2) &gt; div:nth-child(1) &gt; span { /*change some other settings*/ margin: 0 -20px; color: black; font-size: .8em; font-weight: bold; } .hexrow:nth-child(2) &gt; div:nth-child(2) { background-image: url(http://i.imgur.com/jeSPg.jpg); } .hexrow:nth-child(2) &gt; div:nth-child(3) { background-image: url(http://i.imgur.com/Jwmxm.jpg); /*you can shift a large background image, but it can get complicated best to keep the image as the total width (200px) and height (174px) that the hex would be. */ background-position: -150px -120px; opacity: .3; color: black; } .hexrow:nth-child(2) &gt; div:nth-child(3) &gt; div:before { /*you can shift a large background image, but it can get complicated best to keep the image as the total width (200px) and height (174px) that the hex would be. */ background-position: -100px -120px; /* the left shift is always less in the pseudo elements by the amount of the base shift */ } .hexrow:nth-child(2) &gt; div:nth-child(4) { background-image: url(http://i.imgur.com/90EkV.jpg); background-position: -350px -120px; } .hexrow:nth-child(2) &gt; div:nth-child(4) &gt; div:before { background-position: -300px -120px; } </code></pre>
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload