Created
January 14, 2012 20:14
-
-
Save miracle2k/1612729 to your computer and use it in GitHub Desktop.
Optional variations in CSS
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
The idea is two provide optional variations for your stylesheet, for | |
presentation purposes, and have a switcher built into the page to | |
enable/disable them. | |
Usage - include the Javascript code in your page: | |
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js"></script> | |
<script src="cssoptions.js"></script> | |
Note that jQuery >= 1.7 is required. | |
This will search all stylesheets for rules that match "html.opt*". If you | |
are using Sass, you can generate these sort of rules with particular ease: | |
header | |
ul | |
width: auto | |
html.opt-full-width-nav & | |
width: 100% | |
Pressing F9 in the browser will then bring up a switcher window: | |
http://michael.elsdoerfer.name/cssoptions/cssoptions.png | |
An example using Sass to generate multiple color variations: | |
$color-options: purple #8E73C7, pink #C25377, black #292929, blue #4F67B8 | |
@each $item in $color-options | |
html.opt-#{nth($item, 1)} & | |
border-color: darken(nth($item, 2), 10%) |
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($){ | |
function prettifyName(s) { | |
s = s.replace(/[-_]/g, ' '); // remove separator syntax | |
s = s.replace(/([a-z])([A-Z])/g, '$1 $2'); // split words at capitalization changes | |
// capitalize | |
s = s.replace( /(^|\s)([a-z])/g , function(m,p1,p2){ return p1+p2.toUpperCase(); } ); | |
return $.trim(s); | |
} | |
function getOptions() { | |
var options = {}; | |
$.each(document.styleSheets, function(index, stylesheet) { | |
var classes; | |
try { | |
classes = stylesheet.rules || stylesheet.cssRules; | |
} catch(error) { | |
// Firefox may throw SecurityError for external stylesheets | |
return; | |
} | |
if (!classes) return; | |
for (var x=0; x<classes.length; x++) { | |
if (!classes[x].selectorText) continue; | |
var sel = classes[x].selectorText; | |
var re = /(?:^|, )html\.(opt([^ ]+))/g; | |
while (match = re.exec(sel)) { | |
if (!(match[1] in options)) | |
options[match[1]] = prettifyName(match[2]); | |
} | |
} | |
}); | |
return options; | |
} | |
/** | |
* "Combos" provide buttons to enable a set of options in one go. | |
* The syntax is: {mycombo: ['fullnav', 'white']} | |
*/ | |
var _instanceCount = 0; | |
function OptionSwitcher(combos, keyCode) { | |
this.switcher = null; | |
this.combos = combos; | |
this.options = getOptions(); | |
this.id = 'cssoptions' + _instanceCount++; | |
// Show it when a certain key is pressed | |
// http://www.webonweboff.com/tips/js/event_key_codes.aspx | |
var self = this; | |
$(document).on('keyup.'+this.id, function(e) { | |
if (e.keyCode == (keyCode || 120)) // F9 key | |
self.toggle(); | |
}); | |
} | |
OptionSwitcher.prototype._generate = function() { | |
// Generate HTML for the switcher | |
var html = '<div>'; | |
$.each(this.options, function(clazz, name) { | |
html += '<input type="checkbox" name="'+clazz+'"><label title="'+clazz+'" for="'+clazz+'">'+name+'</label><br>'; | |
}); | |
// Add predefined combos | |
if (this.combos && !$.isEmptyObject(this.combos)) { | |
html += '<hr>'; | |
for (var key in this.combos) { | |
html += '<button name="'+key+'">'+key+'</button><br>'; | |
} | |
} | |
html += '</div>'; | |
// Convert to DOM, append styles | |
this.switcher = switcher = $(html); | |
switcher.css('position', 'fixed'); | |
switcher.css('left', '0px'); | |
switcher.css('top', '0px'); | |
switcher.css('margin', '0'); | |
switcher.css('z-index', '99999'); | |
switcher.css('height', 'auto'); | |
switcher.css('border', '1px solid black'); | |
switcher.css('background-color', 'white'); | |
switcher.css('padding', '10px'); | |
switcher.find('label').css('cursor', 'pointer'); | |
var self = this; | |
// Make functional | |
switcher.find('input').change(function() { | |
var clazz = $(this).attr('name'); | |
var isChecked = $(this).attr('checked'); | |
isChecked ? $('html').addClass(clazz) : $('html').removeClass(clazz); | |
}); | |
// Allow clicking on the label to select a single option | |
// and automatically deselect all others. | |
switcher.find('label').click(function() { | |
var clazz = $(this).attr('for'); | |
var clickedOne = switcher.find('input[name='+clazz+']'); | |
var currentlyChecked = clickedOne.is(':checked'); | |
self.disableAll(); | |
clickedOne.attr('checked', !currentlyChecked).change(); | |
}); | |
// Make the combo buttons work. | |
switcher.find('button').click(function() { | |
var clazz = $(this).attr('name'); | |
self.disableAll(); | |
for (var idx in self.combos[clazz]) { | |
var opt = self.combos[clazz][idx]; | |
var control = switcher.find('input[name='+opt+']'); | |
if (control.length) | |
control.attr('checked', true).change(); | |
else | |
alert('Unknown option: '+opt); | |
} | |
}); | |
// Append to document, hidden | |
switcher.hide(); | |
$('body').append(switcher); | |
} | |
/** | |
* Disable all options. | |
*/ | |
OptionSwitcher.prototype.disableAll = function() { | |
this.switcher.find('input').attr('checked', false).change(); | |
} | |
/** | |
* Show/hide the switcher. | |
*/ | |
OptionSwitcher.prototype.show = function() { | |
if (!this.switcher) | |
this._generate(); | |
this.switcher.show(); | |
} | |
OptionSwitcher.prototype.hide = function() { | |
if (this.switcher) | |
this.switcher.hide(); | |
} | |
OptionSwitcher.prototype.toggle = function() { | |
if (this.switcher && this.switcher.is(':visible')) | |
this.hide(); | |
else | |
this.show(); | |
} | |
/** | |
* Remove the switcher from the page. | |
*/ | |
OptionSwitcher.prototype.remove = function() { | |
if (this.switcher) | |
this.switcher.remove(); | |
$(document).off('keyup.'+this.id); | |
} | |
var GLOBAL_SWITCHER = false; | |
window.generateOptionSwitcher = function(combos, keyCode) { | |
if (GLOBAL_SWITCHER) { | |
GLOBAL_SWITCHER.remove(); | |
GLOBAL_SWITCHER = undefined; | |
} | |
return new OptionSwitcher(combos, keyCode); | |
} | |
$(function() { | |
GLOBAL_SWITCHER = generateOptionSwitcher(); | |
}); | |
})(jQuery); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment