Skip to content

Instantly share code, notes, and snippets.

@plugnburn
Last active October 16, 2016 03:23
Show Gist options
  • Save plugnburn/9229beaadbe23819f118 to your computer and use it in GitHub Desktop.
Save plugnburn/9229beaadbe23819f118 to your computer and use it in GitHub Desktop.
XS.js - an ultra-small CSS rule builder in 10 lines of JS

XS.js

This is an ultra-small library for dynamic CSS rules construction (accompanying DOM construction library XT.js). 244 bytes minified, under 200 bytes gzipped.

How to obtain

Download it here or include it into your HTML:

<script src="//cdn.rawgit.com/plugnburn/9229beaadbe23819f118/raw/4b90de880766024dbd7c2a2dde6ad007aba62f18/xs.min.js"></script>

Usage

Similarly to XT.js, XS.js has only one exposed function - XS(styleArray), where styleArray is an array that must obey the following syntax rules:

  • toplevel array must include arrays only;
  • for each array directly inside the toplevel array, the first element must be a selector string, and each following element must be a rule-definition array;
  • for each rule-definition array, the first element is a property name, and the second one is the property value.

XS function returns the reference to an already inserted <style> element responsible for holding created rules.

That's it.

Example

The following XS.js call:

XS([
	['body', 
		['background', 'skyblue'], 
		['font-family', 'sans-serif']
	],
	['h1', 
		['color', 'yellow'],
		['font-size', '3em']
	]
])

will insert and return a stylesheet with the following CSS representation:

body {
  background: skyblue;
  font-family: sans-serif;
}
h1 {
  color: yellow;
  font-size: 3em;
}

A more complex example: grid system

The following CoffeeScript code will create a completely usable grid system of arbitrary column number, allowing to auto-size col elements placed in a row and defining size-classes like col-5-12 to directly specify the width.

window.createGrid = (columns = 12, breakpointWidth = 700, w = window) ->
	matchCurrentMedia = -> w.matchMedia("(min-width:#{breakpointWidth}px)").matches 
	matchCache = false
	buildGrid = ->
		styles = [
			['.row, .col', ['box-sizing', 'border-box']] # reset sizing model
		]
		# styles for desktops and non-media-compliant obsolete browsers
		if !w.matchMedia? or matchCache = matchCurrentMedia()
			styles.push	['.row', 
				['display', 'table'],
				['width', '100%'],
				['table-layout', 'fixed']
			], ['.col', ['display', 'table-cell']]
			for i in [1...columns]
				styles.push [".col-#{i}-#{columns}", # define classes like col-5-12
					['width', "#{100*i/columns}%"], # fallback for non-calc browsers
					['width', "-webkit-calc( 100 * #{i} / #{columns} )"], # fallback for old webkits
					['width', "calc( 100 * #{i} / #{columns} )"] # standard way
				]
		else # styles for mobiles
			styles.push	['.row, .col', ['display', 'block'], ['width', '100%']]
		return XS(styles)
			
	styleElem = buildGrid()
	
	if w.matchMedia? # rebuild grid on resize if we are on a media-compliant browser
		w.addEventListener 'resize', -> 
			if matchCurrentMedia() isnt matchCache
				styleElem.parentNode.removeChild styleElem
				styleElem = buildGrid()
		, false
!function(d){
window.XS = function(arr, style, list, rule, ruleString) {
d.head.appendChild(style = d.createElement('style'))
for(list = arr.slice(); rule = list.shift();) {
for(ruleString = rule.shift()+'{';arr = rule.shift();) ruleString += arr[0] + ':' + arr[1] + ';'
style.sheet.insertRule(ruleString+'}', style.sheet.cssRules.length)
}
return style
}
}(document)
!function(d){window.XS=function(s,t,y,l,e){d.head.appendChild(t=d.createElement('style'));for(y=s.slice();l=y.shift();){for(e=l.shift()+'{';s=l.shift();)e+=s[0]+':'+s[1]+';';t.sheet.insertRule(e+'}',t.sheet.cssRules.length)}return t}}(document)
@Em0An
Copy link

Em0An commented Oct 16, 2016

good

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment