« Back to Index
JavaScript grid overlay
View original Gist on GitHub
Grid-Overlay.js
(function(){
var boundaryInserted, grid12, grid24, boundary, firstTimeVisible, magicNumber = 126;
function getDocHeight(){
var body = document.body,
elem = document.documentElement;
return Math.max(
Math.max(body.scrollHeight, elem.scrollHeight),
Math.max(body.offsetHeight, elem.offsetHeight),
Math.max(body.clientHeight, elem.clientHeight)
);
}
function insertBoundary(){
if (!boundaryInserted) {
boundaryInserted = true;
var styles = '<style>\
.boundary { background-color: #CCC; color: black; margin: auto; max-width: 1028px; padding-bottom: .5em; padding-top: .5em; position: relative; text-align: center; z-index: 9999; }\
.boundary__border { background-color: #CCC; position: absolute; top: 0; width: 1px; }\
.boundary__border--left { left: 0; }\
.boundary__border--right { right: 0; }\
</style>';
var overlay = document.createElement('div');
overlay.id = 'js-overlay';
var overlay24 = document.createElement('div');
overlay24.id = 'js-overlay-24';
var boundary = document.createElement('div');
boundary.className = 'boundary';
boundary.innerHTML = 'This element indicates the outer margins (which *used* to be incorporated into the Grid, but not any more)<br><br><b>\
Press:<br>\
"a" to toggle everything<br>\
"b" to toggle boundary box<br>\
"g" key to toggle 12 column grid visibility<br>\
"f" key to toggle 24 column grid visibility</b>';
var wrapper = document.querySelector('.wrapper');
wrapper.parentNode.insertBefore(boundary, wrapper);
var borderLeft = document.createElement('div');
borderLeft.className = 'boundary__border boundary__border--left';
var borderRight = document.createElement('div');
borderRight.className = 'boundary__border boundary__border--right';
boundary.appendChild(borderLeft);
boundary.appendChild(borderRight);
document.body.appendChild(overlay);
document.body.appendChild(overlay24);
$(boundary).before($(styles));
}
}
function setUpKeyBindings(){
var visible = false;
$(document).on('keyup', function (e) {
// Toggle 12 column grid (g)
if (e.keyCode === 71) {
grid12.toggle();
}
// Toggle 24 column grid (f)
if (e.keyCode === 70) {
grid24.toggle();
}
// Toggle outer boundary (b)
if (e.keyCode === 66) {
boundary.toggle();
}
// Toggle everything (a)
if (e.keyCode === 65) {
if (visible) {
boundary.hide();
grid12.hide();
grid24.hide();
visible = false;
} else {
// If it's the first time we're displaying the boundary and grids then ensure their height is set
if (!firstTimeVisible) {
$('.boundary__border, #gridpak, #gridpak24').each($.proxy(function (index, item) {
item.style.height = getDocHeight() + magicNumber + 'px';
}, this));
firstTimeVisible = true;
}
boundary.show();
grid12.show();
grid24.show();
visible = true;
}
}
});
}
function Gridpak (numberOfColumns, userProvidedGrids) {
this.$container = {};
this.append = (numberOfColumns === 24) ? '#js-overlay-24' : '#js-overlay'; // DOM element to append the Gridpak too
this.columnNumber = numberOfColumns;
this.injectCSSName = (numberOfColumns === 24) ? 'gridpak24' : 'gridpak';
this.hideOnSmallerScreens = (numberOfColumns === 24) ? true : false;
this.css = '';
this.userProvidedGrids = userProvidedGrids;
this.gridpakWrapper = '';
this.numberOfColumns = numberOfColumns;
this.init();
}
Gridpak.prototype.init = function(){
insertBoundary();
var grids = this.userProvidedGrids,
numGrids = grids.length - 1,
i = 0;
this.css += '<style type="text/css"> ' +
'#' + this.injectCSSName + ' { ' +
'width:100%; ' +
'height:100%; ' +
'display:block; ' +
'position:absolute; ' +
'top:0; ' +
'left:0; ' +
'z-index:9998; ' +
'} ' +
'#' + this.injectCSSName + ' .' + this.injectCSSName + '_wrapper { ' +
'max-width:996px; ' +
'height:100%; ' +
'margin:auto; ' +
'padding-left:16px; ' +
'padding-right:16px; ' +
'} ' +
'#' + this.injectCSSName + ' .' + this.injectCSSName + '_wrapper.' + this.injectCSSName + '_wrapper--smallerOuterMargins { ' +
'padding-left:8px; ' +
'padding-right:8px; ' +
'} ' +
'#' + this.injectCSSName + ' .' + this.injectCSSName + '_grid { ' +
'height:100%; ' +
'display:none; ' +
'} ' +
'#' + this.injectCSSName + ' .' + this.injectCSSName + '_col { ' +
'border-left:0 solid rgba(255,255,255,0); ' +
'border-right:0 solid rgba(255,255,255,0); ' +
'-moz-background-clip: padding; -webkit-background-clip: padding-box; background-clip: padding-box;' +
'padding:0; ' +
'-webkit-box-sizing:border-box; -moz-box-sizing:border-box; box-sizing:border-box; ' +
'display:block; ' +
'float:left; ' +
'height:100%; ' +
'background-color:rgba(153,0,0,0.2); ' +
'} ' +
'#' + this.injectCSSName + ' .' + this.injectCSSName + '_visible { ' +
'width:100%; ' +
'height:100%; ' +
'display:block; ' +
'background:rgba(255,255,255,0.3); ' +
'} ';
this.markup = '<div id="' + this.injectCSSName + '"><div class="' + this.injectCSSName + '_wrapper">';
// Put the grids on the screen
for (i; i<=numGrids; i++) {
this.drawGrid(grids[i], i);
}
this.markup += '</div></div>';
this.css += '</style>';
if (this.columnNumber === 24) {
grid24 = this.$container = $(this.markup);
} else {
grid12 = this.$container = $(this.markup);
}
this.topLevelContainerElement = $(this.append);
this.topLevelContainerElement.prepend(this.css);
this.topLevelContainerElement.append(this.$container);
boundary = this.boundary = $('.boundary');
this.gridpakWrapper = $('.' + this.injectCSSName + '_wrapper');
this.checkOuterMargins();
// Hide the boundary and the grids on load
this.boundary.hide();
this.$container.hide();
$(window).on('resize', $.proxy(this.checkOuterMargins, this));
};
Gridpak.prototype.checkOuterMargins = function(){
if (this.columnNumber === 24) {
this.hideOnSmallerScreens = true;
}
if (document.documentElement.clientWidth < 600) {
if (this.hideOnSmallerScreens) {
this.topLevelContainerElement.hide();
}
} else {
if (this.hideOnSmallerScreens) {
this.topLevelContainerElement.show();
}
}
if (document.documentElement.clientWidth < 400) {
this.gridpakWrapper.addClass(this.injectCSSName + '_wrapper--smallerOuterMargins');
} else {
this.gridpakWrapper.removeClass(this.injectCSSName + '_wrapper--smallerOuterMargins');
}
};
Gridpak.prototype.drawGrid = function (grid, num) {
var new_markup = '',
i = 1,
gutter_pc = (grid.gutter_type === '%') ? grid.gutter_width : 0,
gutter_px = (grid.gutter_type === 'px') ? grid.gutter_width : 0,
width = 0;
if (grid.gutter_type === 'px') {
width = 100 / grid.col_num;
} else {
width = (100 - (gutter_pc * (grid.col_num - 1))) / grid.col_num;
}
new_markup = '<div class="' + this.injectCSSName + '_grid ' + this.injectCSSName + '_grid_' + num + '">';
this.css += '#' + this.injectCSSName + ' .' + this.injectCSSName + '_grid_' + num + ' { ' +
'margin-left:-' + gutter_px + 'px; ' +
'} ' +
'#' + this.injectCSSName + ' .' + this.injectCSSName + '_grid_' + num + ' .' + this.injectCSSName + '_col { ' +
'width:' + width + '%; ' +
'margin-left:' + gutter_pc + '%; ' +
'border-left-width:' + gutter_px + 'px; ' +
'padding-left:' + grid.padding_width + grid.padding_type +'; ' +
'padding-right:' + grid.padding_width + grid.padding_type + '; ' +
'} ';
if (grid.gutter_type === '%') {
this.css += '#' + this.injectCSSName + ' .' + this.injectCSSName + '_grid_' + num + ' .' + this.injectCSSName + '_col:first-child { ' +
'margin-left:0;' +
'} ';
}
this.css += '@media screen and (min-width: ' + grid.min_width + 'px) ';
if (grid.upper !== false) {this.css += 'and (max-width: ' + grid.upper + 'px) ';}
this.css += ' { ' +
'#' + this.injectCSSName + ' .' + this.injectCSSName + '_grid_' + num + ' { ' +
'display: block; ' +
'} ' +
'} ';
for(i; i<=grid.col_num; i++) {
new_markup += '<div class="' + this.injectCSSName + '_col"><div class="' + this.injectCSSName + '_visible"></div></div>';
}
new_markup += '</div>';
this.markup += new_markup;
};
setUpKeyBindings();
// 12 Column Grid
var grid = new Gridpak(12, [
{
min_width: 0,
col_num: 12,
gutter_type: 'px',
gutter_width: 8,
padding_type: 'px',
padding_width: 0,
upper: 419
},
{
min_width: 400,
col_num: 12,
gutter_type: 'px',
gutter_width: 16,
padding_type: 'px',
padding_width: 0,
upper: 599
},
{
min_width: 600,
col_num: 12,
gutter_type: 'px',
gutter_width: 16,
padding_type: 'px',
padding_width: 0,
upper: 1000
},
{
min_width: 1001,
col_num: 12,
gutter_type: 'px',
gutter_width: 16,
padding_type: 'px',
padding_width: 0,
upper: false
}
]);
// 24 Column Grid
var grid_24 = new Gridpak(24, [
{
min_width: 600,
col_num: 24,
gutter_type: 'px',
gutter_width: 16,
padding_type: 'px',
padding_width: 0,
upper: 1000
},
{
min_width: 1001,
col_num: 24,
gutter_type: 'px',
gutter_width: 16,
padding_type: 'px',
padding_width: 0,
upper: false
}
]);
}());