Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Indent even rows of hexagons in CSS

Tags:

html

css

web

I currently have a list of hexagons (images) that I have wrap to the next line when the browser width decreases. However, when this happens, they form even lines as seen in the first image, each starting at the same point on the x axis.

Current solution where each row starts at the same point on the x axis

Here is the JS Fiddle (albeit, the hexes don't flow right because they aren't images). The real code for this is:

<div class="container">
    <span>
        <img class="hex" src="img/hex.png">
    </span>
    ...
</div>

And the CSS is:

.container {
    padding-top: 80px;
    width: 50%;
    margin-left: auto;
    margin-right: auto;
}

.container span {
    line-height: 129px;
    display: inline-block;
}

.container .hex {
    display: block;
    margin-left: auto;
    margin-right: auto;
}

What I would like to do is alternate the rows such that every other row starts at an offset of the hexagon size as seen in figure two. It should also be noted that this example also has a negative y position relative to the respective position as determined from the first image.hexagon rows interlocking, with an offset for even rows

Is there a way to do this with just CSS? I'd like to avoid using a library if at all possible.

This is similar to the question asked here, but I need the entire structure to be able to have an undetermined number of rows, so the solution where I specify which items are in which rows isn't feasible for my application.

like image 402
JTate Avatar asked Dec 30 '14 23:12

JTate


2 Answers

Solution in JS Fiddle Demo :

Demo 1 :

http://jsfiddle.net/mkginfo/bhxohocv/

HTML Code :

<div class="container">
     <!-- odd line -->
    <span>
        <div class="hexagon"> </div>
    </span>
    <span>
        <div class="hexagon"> </div>
    </span>
    <span>
        <div class="hexagon"> </div>
    </span>
    <!-- even line -->
     <span class="odd">
        <div class="hexagon"> </div>
    </span>
     <span>
        <div class="hexagon"> </div>
    </span>
    <!-- odd line -->
    <span>
        <div class="hexagon"> </div>
    </span>
    <span>
        <div class="hexagon"> </div>
    </span>
    <span>
        <div class="hexagon"> </div>
    </span>
</div>

CSS Code :

.container {
    padding-top: 80px;
    width: 65%;
    margin-left: auto;
    margin-right: auto;
}

.container span {
    line-height: 129px;
    display: inline-block;
    position: relative;
    margin-bottom: 25px;
}
.container span.odd {
    line-height: 129px;
    display: inline-block;
    position: relative;
    margin-bottom: 25px;
    margin-left: 52px;
    margin-top: -20px;
}

.container .hex {
    display: block;
    margin-left: auto;
    margin-right: auto;
}

.hexagon {
    width: 100px;
    height: 55px;
    background: red;
    position: relative;
}

.hexagon: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;
}

.hexagon: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;
}

Demo 2 :

http://jsfiddle.net/mkginfo/wnsjfwt0/

like image 200
Mohit Kumar Gupta Avatar answered Nov 14 '22 12:11

Mohit Kumar Gupta


Here's a solution that uses javascript to add the necessary transformations to the elements.

CSS:

.container {
    padding-top: 80px;
    width: 65%;
    margin-left: auto;
    margin-right: auto;
}

.floatBox {
    margin-left: 15px;
    margin-right: 15px;
}

.floatBox div {
    display: inline-block;

}
.floatBox div.odd {
    margin-left: 67px;
}

JS:

var floatBox = $(".floatBox");
var elements = floatBox.children();
var numElements = elements.length;

//reset all styles so they don't compound
elements.removeClass("odd");
elements.css("transform", "translateY(0)");
elements.css("-ms-transform", "translateY(0)");
elements.css("-webkit-transform", "translateY(0)");

var width = $(window).width() *.65;
var evenRowWidth = Math.floor(width / 135);
var oddRowWidth = Math.max(evenRowWidth - 1, 1);
var numberOfRows = 0;

var floatBoxWidth = evenRowWidth *138;
var delta = Math.floor((width-floatBoxWidth)/2);
floatBox.css("margin-left", delta);
floatBox.css("margin-right", delta);

var test = numElements;
var j = 2;
while (test > 0)
{
    if (j % 2 == 0)
    {
        test -= evenRowWidth;
    }
    else
    {
        test -= oddRowWidth;
    }
    numberOfRows++;
    j++;
}

j = 0;
var actionRow = 2;
var rowCount = 1;
var first = true;
for (var i = evenRowWidth; i < numElements; i++)
{
    var translationAmt = -37*(actionRow-1);
    if (actionRow % 2 == 0 && first)
    {
        first = true;
    }
    if (first)
    {
        $(elements.get(i)).addClass("odd");
        first = false;
    }
    $(elements.get(i)).css("transform", "translateY(" + translationAmt + "px)");
    $(elements.get(i)).css("-ms-transform", "translateY(" + translationAmt + "px)");
    $(elements.get(i)).css("-webkit-transform", "translateY(" + translationAmt + "px)");

    if (actionRow % 2 == 0)
    {
        if (rowCount == oddRowWidth)
        {
            actionRow++;
            rowCount = 0;
        }
    }
    else
    {
        if (rowCount == evenRowWidth)
        {
            actionRow++;
            rowCount = 0;
            first = true;
        }
    }
    rowCount++;
}

HTML:

<div class="container">
    <div class="floatBox">

        <div>
            <span>
                <img src="image.png">
            </span>
        </div>
        ...
    </div>
</div>
like image 44
JTate Avatar answered Nov 14 '22 13:11

JTate