Last active
December 27, 2015 19:39
-
-
Save Integralist/7378674 to your computer and use it in GitHub Desktop.
JavaScript grid overlay
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
(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 | |
} | |
]); | |
}()); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
It's not pretty but then it's not supposed to be. This was A.) only meant for debugging and B.) this was an early prototype at that :-)