Skip to content

Instantly share code, notes, and snippets.

@pbrocks
Created January 14, 2015 01:32
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save pbrocks/e4e147765d42963960c5 to your computer and use it in GitHub Desktop.
Save pbrocks/e4e147765d42963960c5 to your computer and use it in GitHub Desktop.
GRG Responsive Grid

GRG Responsive Grid

Similar to Masonry, but with less heavy javascript. This particular version is limited to just square and 2:3 tall images, so it's definitely not as flexible as masonry, just snappier. All positioning is done in CSS, with just a single Javascript loop over the elements to update the classes. Note that bad images would expose the background.

A Pen by Olex on CodePen.

License.

<h1>GRG Responsive Grid</h1>
<h2>Responsive grid without masonry (light on Javascript). Requires square or 2:3 scale tiles ("tall" class).</h2>
<h2>By <a href="mailto:olex@bighuman.com">Olex</a>, formerly Señor Developer at <a href="http://bighuman.com">BIG HUMAN</a></h2>
<div class="grid">
<div class="item tall">
<a class="link" href="#">
<div class="hovercontent">
<h1>JETSETTER</h1>
<h3>Designed by Big Human</h3>
</div>
<img src="http://i.imgur.com/PMtLS.jpg" />
</a>
</div>
<div class="item">
<a class="link" href="#">
<div class="hovercontent">
<h1>FAME</h1>
<h3>This app got shut down by Twitter</h3>
</div>
<img src="http://static.squarespace.com/static/4f0b1540d09a72608d47a4e1/4f0b1e6ad09a72608d47b308/4f775a8e24aca2ac3c07e53b/1333492378258/bh_squarespace_project_tiles_01.jpg?format=700w" />
</a>
</div>
<div class="item tall">
<a class="link" href="#">
<div class="hovercontent">
<h1>TD Mobile Trader App</h1>
<h3>By Big Human</h3>
</div>
<img src="http://i.imgur.com/KArbX.jpg"/>
</a>
</div>
<div class="item">
<a class="link" href="#">
<div class="hovercontent">
<h1>JETSETTER for iPhone</h1>
<h3>Also by Big Human</h3>
</div>
<img src="http://static.squarespace.com/static/4f0b1540d09a72608d47a4e1/4f0b1e6ad09a72608d47b308/4f5ef162e4b03471ad2ca217/1348585961079/6.jpg?format=700w"/>
</a>
</div>
<div class="item tall">
<a class="link" href="#">
<div class="hovercontent">
<h1>The Date Report</h1>
<h3>Blog for How About We</h3>
</div>
<img src="http://i.imgur.com/FmSX7.png"/>
</a>
</div>
<div class="item">
<a class="link" href="#">
<div class="hovercontent">
<h1>TEAM SANS</h1>
<h3>Work In Progress</h3>
</div>
<img src="http://i.imgur.com/hCCpg.png" />
</a>
</div>
<div class="item tall">
<a class="link" href="#">
<div class="hovercontent">
<h1>VYou</h1>
<h3>Designed by Big Human</h3>
</div>
<img src="http://i.imgur.com/u9Z6r.png" />
</a>
</div>
<!--- Olex's Projects: --->
<div class="item">
<a class="link" href="#">
<div class="hovercontent">
<h1>T-Shirt Design Concept</h1>
<h3>By Olex</h3>
</div>
<img src="http://i.imgur.com/98RO1.png"/>
</a>
</div>
<div class="item">
<a class="link" href="#">
<div class="hovercontent">
<h1>FAME</h1>
<h3>An app that shut down by Twitter</h3>
</div>
<img src="http://static.squarespace.com/static/4f0b1540d09a72608d47a4e1/4f0b1e6ad09a72608d47b308/4f775a8e24aca2ac3c07e53b/1333492378258/bh_squarespace_project_tiles_01.jpg?format=700w" />
</a>
</div>
<div class="item tall">
<a class="link" href="#">
<div class="hovercontent">
<h1>JETSETTER</h1>
<h3>Designed by Big Human</h3>
</div>
<img src="http://i.imgur.com/PMtLS.jpg" />
</a>
</div>
<div class="item">
<a class="link" href="#">
<div class="hovercontent">
<h1>TEAM SANS</h1>
<h3>Work In Progress</h3>
</div>
<img src="http://i.imgur.com/hCCpg.png" />
</a>
</div>
<div class="item tall">
<a class="link" href="#">
<div class="hovercontent">
<h1>TD Mobile Trader App</h1>
<h3>By Big Human</h3>
</div>
<img src="http://i.imgur.com/KArbX.jpg"/>
</a>
</div>
</div>
$.gridSize = ()->
inWidth = window.innerWidth
if inWidth > 1200 then return 4
if inWidth > 900 then return 3
if inWidth > 600 then return 2
return 1
$.fillArray = (len, val)->
arr = []
while (len-- > -1)
arr[len] = val
return arr
$.resizeGrid = (columns)->
shifts = $.fillArray($(".grid .item").length, 0)
console.log("shifts before> " + shifts)
$(".grid .tall").each (_i, element)->
index = $(element).prevAll().length
# The first index we need to shift down is the one BELOW this tall element (index + columns)
index += columns
while( index < shifts.length )
shifts[index] += 1
index += columns
console.log("shifts after> " + shifts)
$(".grid .item").each (ind, element)->
$(element).removeClass("shift0 shift1 shift2 shift3 shift4 shift5")
$(element).addClass("shift#{shifts[ind]}")
console.log("Resizing to #{columns} columns")
$(window).resize ->
if $.currentGridSize?
if $.gridSize() != $.currentGridSize
$.resizeGrid($.gridSize())
$.currentGridSize = $.gridSize()
else
console.log 'no current grid size'
$ ()->
$.currentGridSize = $.gridSize()
console.log("Resizing to #{$.currentGridSize} columns")
$.resizeGrid $.currentGridSize
true
console.log("Reloaded")
###
The rest of this document was created for previous pens:
Description on hover:
http://codepen.io/tholex/pen/IxALf
"Pespective" image hover effect:
http://codepen.io/tholex/pen/gtEeq
###
pspZoom = (val, max) ->
(val / max) * (-25) + 12.5
if !Modernizr.touch
$(".grid .item")
.mouseenter (e) ->
@.delayStamp = new Date()
@.lastRatio = 0
$(@).find('img')
.css({
'-webkit-transform': "scale3D(1.5, 1.5, 1)"
'-moz-transform': "scale3D(1.5, 1.5, 1)"
'-ms-transform': "scale3D(1.5, 1.5, 1)"
'-o-transform': "scale3D(1.5, 1.5, 1)"
'transform': "scale3D(1.5, 1.5, 1)"
})
.mousemove (e) ->
timeDiff = (new Date() - @.delayStamp)
ratio = if timeDiff > 300 then 1.0 else (timeDiff / 300)
# the next is the "limiter" - basically just makes sure there's no jumps
# If I moved it around before zooming, the image would not fill the container
ratio = if (ratio - @.lastRatio) > 0.08 then @.lastRatio + 0.075 else ratio
@.lastRatio = ratio;
offset = $(@).offset();
x = pspZoom(e.pageX - offset.left, $(@).width())
y = pspZoom(e.pageY - offset.top, $(@).height())
$(@).find('img').css({
'left': "#{ratio * x}%"
'top': "#{ratio * 5 * y}px"
})
.mouseleave ->
$(@).find('img')
.attr("data-translate-delay-stamp", "-1")
.css({
'-webkit-transform': "scale3D(1, 1, 1)"
'-moz-transform': "scale3D(1, 1, 1)"
'-ms-transform': "scale3D(1, 1, 1)"
'-o-transform': "scale3D(1, 1, 1)"
'transform': "scale3D(1, 1, 1)"
'left': "0"
'top': "0"
})
###
if !Modernizr.touch
$(".grid .item")
.mousemove (e) ->
offset = $(@).offset();
x = -(e.pageX - offset.left) / 4;
y = -(e.pageY - offset.top) / 4;
$(@).find('img').css({
'-webkit-transform': "scale3D(1.5, 1.5, 1) translate3d(#{x}px, #{y}px, 0px)"
'-moz-transform': "scale3D(1.5, 1.5, 1) translate3d(#{x}px, #{y}px, 0px)"
'-ms-transform': "scale3D(1.5, 1.5, 1) translate3d(#{x}px, #{y}px, 0px)"
'-o-transform': "scale3D(1.5, 1.5, 1) translate3d(#{x}px, #{y}px, 0px)"
'transform': "scale3D(1.5, 1.5, 1) translate3d(#{x}px, #{y}px, 0px)"
})
.mouseleave ->
$(@).find('img').css({
'-webkit-transform': "scale3D(1, 1, 1)"
'-moz-transform': "scale3D(1, 1, 1)"
'-ms-transform': "scale3D(1, 1, 1)"
'-o-transform': "scale3D(1, 1, 1)"
'transform': "scale3D(1, 1, 1)"
})
###
/****
GRG RESPONSIVE GRID, goals:
1-2-3-4 column Responsive Grid with varying (but PRESET) height elements. Originally I was thinking "no javascript" but nth-next-selector is not something readily available in CSS. So now the strategy is to just do one calculation every time the # of columns in the grid changes, and reapply CSS styles. No heights or offsets are calculated in Javascript.
Edit:
There's no need to pre-determine which indecies are "tall", javascript simply interprets the CSS class "tall" now.
Technical Description:
This is a grid of inline-block elements spanning 100/50/33.333/25% of their container. By dropping font-size to 0 and bringing it back, spaces in the HTML don't alter the spacing.
To make the tall elements, the bottom is pushed out using a negative margin-bottom. Javascript determines the elements below this one in the grid, and applies "shift{1-5}" depending on the amount of "tall" tiles above each tile.
See bighuman.com for the old javascript version.
****/
.translate(@x: 0, @y: 0) {
-webkit-transform: translate(@x, @y);
-moz-transform: translate(@x, @y);
-ms-transform: translate(@x, @y);
-o-transform: translate(@x, @y);
transform: translate(@x, @y);
}
.shift_grid(@down, @right: 0) {
.translate(@right * 50%, @down * 50%);
}
.grid {
margin: 40px auto 40px;
font-size: 0;
text-align: left;
background: #222;
}
.item {
font-size: 12px;
display: inline-block;
vertical-align: top;
position: relative;
overflow: hidden;
line-height: 0;
-webkit-transition: -webkit-transform 0.2s ease-out;
-moz-transition: -moz-transform 0.2s ease-out;
-o-transition: -o-transform 0.2s ease-out;
transition: transform 0.2s ease-out;
}
/* 2-GRID */
@media screen and (min-width: 600px) {
.item {
width: 50%;
max-height: none;
> a { height: 50%; }
&.tall {
margin-bottom: -25.1%;
&.shift1 { .shift_grid(0.6666666); }
&.shift2 { .shift_grid(1.3333333); }
&.shift3 { .shift_grid(2); }
&.shift4 { .shift_grid(2.6666666); }
&.shift5 { .shift_grid(3.3333333); }
}
&.shift1 { .shift_grid(1); }
&.shift2 { .shift_grid(2); }
&.shift3 { .shift_grid(3); }
&.shift4 { .shift_grid(4); }
&.shift5 { .shift_grid(5); }
}
}
/* 3-GRID */
@media screen and (min-width: 900px) {
.item {
width: 33.33332%;
> a { height: 50%; }
&.tall {
margin-bottom: -16.7%;
}
}
}
/* 4-GRID */
@media screen and (min-width: 1200px) {
.item {
width: 25%;
> a { height: 25%; }
&.tall {
margin-bottom: -12.6%;
}
}
}
/*******
---- STYLE, HOVER EFFECTS AND SO FORTH
EVERYTHING BELOW IS PURE CSS
The rest of this was created for previous pens:
Description on hover:
http://codepen.io/tholex/pen/IxALf
"Pespective" image hover effect:
http://codepen.io/tholex/pen/gtEeq
********/
body { background: #333; }
h1, h2 {
color: whiteSmoke;
text-shadow: 1px 1px 2px black;
}
h1 {
font-family: "Gill Sans", sans-serif;
text-transform: uppercase;
font-size: 2em;
margin: 0.75em 0.75em 0.25em;
}
h2 {
font-family: "Gill Sans", sans-serif;
font-weight: 200;
margin-left: 1.5em;
margin-top: 0.33em;
}
a {
color: #aaa;
text-decoration: none;}
.hovercontent h1 {
color: white;
font-size: 1.5em;
margin-top: 40%;
}
.hovercontent h3 {
color: #a1a1a1;
font-weight: 100;
}
.grid {
display: block; /* my favorite display attribute */
box-shadow: 0 -1px 5px #111;
}
.item img {
position: relative;
z-index: 4;
width: 100%;
-webkit-transform-origin: 50% 50%;
-moz-transform-origin: 50% 50%;
-ms-transform-origin: 50% 50%;
-o-transform-origin: 50% 50%;
transform-origin: 50% 50%;
/* This is what was making it slow! booooooo */
-webkit-transition: opacity 0.3s ease-out, -webkit-transform 0.2s ease-out;
-moz-transition: opacity 0.3s ease-out, -moz-transform 0.2s ease-out;
-o-transition: opacity 0.3s ease-out, -o-transform 0.2s ease-out;
transition: opacity 0.3s ease-out, transform 0.2s ease-out;
}
.item .link {
display: block;
height: 100%;
}
.hovercontent {
position: absolute;
z-index: 5;
font-family: "Helvetica", Arial, sans-serif;
text-align: center;
width: 100%;
height: 100%;
background: #222222;
background: rgba(0,0,0,0.7);
opacity: 0;
line-height: 24px;
filter: alpha(opacity=0);
-ms-filter: "progid:DXImageTransform.Microsoft.Alpha(Opacity=0)";
-moz-transform: scale3d(1.3, 1.3, 1) translate3d(0, 10%, 0);
-o-transform: scale3d(1.3, 1.3, 1) translate3d(0, 10%, 0);
-webkit-transform: scale3d(1.3, 1.3, 1) translate3d(0, 10%, 0);
transform: scale3d(1.3, 1.3, 1) translate3d(0,10%,0);
-webkit-transition: opacity 0.2s ease-out, -webkit-transform 0.2s ease-in-out;
-moz-transition: opacity 0.2s ease-out, -moz-transform 0.2s ease-in-out;
-o-transition: opacity 0.2s ease-out, -o-transform 0.2s ease-in-out;
transition: opacity 0.2s ease-out, transform 0.2s ease-in-out;
}
.item .link:hover {
}
.item .link:hover .hovercontent {
opacity: 1;
filter: alpha(opacity=100);
-ms-filter: "progid:DXImageTransform.Microsoft.Alpha(Opacity=100)";
-moz-transform: scale3d(1, 1, 1) translate3d(0, 0, 0);
-o-transform: scale3d(1, 1, 1) translate3d(0, 0, 0);
-webkit-transform: scale3d(1, 1, 1) translate3d(0, 0, 0);
transform: scale3d(1, 1, 1) translate3d(0,0,0);
}
.item .link:hover img {
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment