CSSOBJ
CSS in JS solution, create CSSOM and CSS rules from js, features:
- CSS Rules create and diff
- Conditional apply CSS (good for SPA)
- CSS modules with local class
- Auto vendor prefixer
- Media query for old browsers
- Dynamically change CSS
Light weight (3K gzipped), Well Tested, Easy to use (example in Wiki)
Why?
For a long time, dynamicly change CSS is via DOM.style, like below:
document.getElementById('domID').style.color = 'red'
document.getElementById('domID').style.fontSize = '14px'
or jQuery (or similar lib):
$('div').css({color:'red', fontSize:'14px'})
But the first way is poor, the second way need jQuery lib, interactive with DOM, and have performance issues.
But ALL of them is not updating css rules.
CSSOM is the base stone of browser, and it have good javascript API, why not using it?
cssobj is the modern CSSOM generate and diff engine, see below:
/* script in your <head> */
var obj = {div: {color:'red', fontSize:'12px'}}
var ret = cssobj(obj)
Then all div
will have color: red;
, currently and future!
Want to dynamicly update?
/* script in your <head> */
obj.div.color = 'blue'
ret.update()
Then all div
will update css color: blue;
. No jQuery, no wait for DOM, no window.onload
!
The cool thing is:
-
You never need to wait for DOM any more
-
cssobj will only update changed value, good for performance!
Install:
npm install cssobj
Quick Start:
Including dist/cssobj.min.js into <head>
, using as below:
- Conditional apply CSS
var obj = {
p: [{
$test: function(){return true},
color: 'blue'
}, {
$test: function(){return false},
color: 'red'
}]
}
var result = cssobj(obj)
The CSS is: p {color: blue;}
- local class names
var obj = {
body: {
color:'red'
},
'.item': {
fontSize: '12px',
span: { color: 'blue' }
}
}
var result = cssobj(obj, {local:true})
This will generate CSSOM in your <head>
, with below css:
body {
color: red;
}
._1jkhrb92_item {
font-size: 12px;
}
._1jkhrb92_item span {
color: blue;
}
Class names will add a random prefix, you can get class name using below:
result.mapSel('.item') // === ._1jkhrb92_item (with dot)
result.mapClass('.item') // === _1jkhrb92_item (without dot)
- Dynamicly update you css rule
var obj = {
div: {fontSize:'12px'}
}
var css = cssobj(obj)
If you want to update the rule later:
... ...
obj.div.fontSize = '14px'
css.update()
- @media rule work in old Browsers
Just try this demo, in IE 5,6,7,8!
- Auto vendor prefixer
cssobj will detect current browser's vendor prefix
, and auto prefix when the property is invalid for style.
var obj = {
button: {
// will prefix for current browser
appearance: 'none',
borderImage: 'url(border.png)'
}
}
var css = cssobj(obj)
Test Demo - BrowserStack Snapshot
How it worked?
-
cssobj first parse js object into Virtual CSSOM middle format.
-
The internal plugin-cssom will create stylesheet dom, and apply rules from middle format.
-
When the js object changed, cssobj will diff CSSOM rules (add/delete/change) accordingly. (see demo)
Benefit
What's the benefit?
1. Live update
obj.div.fontSize = '16px'
result.update()
Then the actual style sheet will update the div
selector rule, set font-size
to 16px
.
2. Dynamic caculation
obj.div.width = function(){ return window.innerWidth / 3 + 'px' }
obj.div.height = function(){ return this.width }
result.update()
Then all the div
will have same width & height, as 1/3 of window width, magicly!
3. Hot replacement
obj.div.span = {color:'green', marginLeft: '20px'}
result.update()
Then the old span
selector will be replaced by the new rule.
4. @media support in old browsers
cssobj({
div:{ color:'red' },
'@media (max-width: 768px)':{
div:{ color:'green' },
'@media (min-width: 480px)':{
div:{ color:'blue' }
}
}
})
Then div
will have color as red, green and blue accordingly, in ALL BROWSERS (tested Modern & IE5+)
Demo here for @media (min-width), (max-width) support for old browsers.
Below is the screencast with @media rule response support in IE 5 (oh my!)
5. Localized class names
var ret = cssobj({
body:{ color:'red' },
'.item':{ color:'blue' }
}, {local : true} )
will get CSSOM as below:
body { color: red; }
._1c0b3bn4_nav { color: red; }
There's no class name conflict. You can customize the prefix
as you need, or turn off this feature.
6. Small and smart
Only one js file with no dependencies, 3K gzipped.
Easy to plugin, and there're plenty of them.
Virtual CSSOM middle format is JS object, thus can avoid the differences of CSS engines, dynamicly caculated.
API
var result = cssobj(obj, options)
parse obj, generate virtual css, then render <style>
tag into <head>
PARAMS
obj
Type: {object|array}
Nothing special, just plain js Object
, or Array
of Object
, with below rules:
-
non-object(
string|number
) value act as css value. -
if value is object, key will act as css selector.
-
if value is non-object, key will act as css property.
options
Type: {object}
name | type | default | description |
---|---|---|---|
local | Boolean or Object | false | true to localize class names, using options.local.prefix as prefix. |
local.prefix | String | random string | prefix for localized names, will using random() function in cssobj-helper if not specified or as falsy. |
local.localNames | Object | { } | predefined key - val to control each class name when localized. |
plugins | Object | { } | supported plugin is post , value , selector , each must be function or array of functions. |
RETURN
cssobj RESULT
object
RESULT
OBJECT
The return value of cssobj()
and result.update()
, it's a js object with below keys:
name | type | description |
---|---|---|
obj | Object | The source js object for cssobj() function call. |
root | Object | Virtual CSSOM object parsed from obj , mainly used for value functions and plugins. |
nodes | Array | Array of virtual css nodes, for the convinence of filter or map etc. |
mapSel | Function | Get localized class name from selector string. Function signature is function({string} selector){ return {string} mappedSel } . |
mapClass | Function | Get localized class name from class list string. Function signature is function({string} classList){ return {string} mappedClassList } . |
ref | Object | Key/value pairs for named objects. Named objects is objects with $id string value in obj . |
update | Function | Update the RESULT object from obj , generate diff , update CSSOM and all relevent data. Function signature is function updater ([{object} data]) { return {object} result } |
- | updater param:
data | [optional] Passed toupdate()
function, and set toRESULT
data
value, for later use. diff | Object | Set fromupdate()
function, withadded
,removed
,changed
nodes and props. data | Object | Store for data parameter ofupdate()
function, can be referenced and changed in object functions and plugins. options | Object | Store forcssobj()
options
parameter, can be referenced and changed in object functions and plugins. cssdom | Stylesheet
Element | Style sheet element generated bycssobj()
function. Each call ofcssobj()
will generate a new cssdom.update()
function only update cssdom withdiff
result.
Plugins
-
cssobj-plugin-localize Localize class names in selector
-
cssobj-plugin-default-unit Add default unit to numeric values, e.g. width / height
-
cssobj-plugin-gencss Generate css text from virtual css
-
cssobj-plugin-cssdom Add style dom to head and update rules from virtual css diff result
-
cssobj-plugin-stylize Add style dom to head then update css from gencss plugin, small in size
-
cssobj-plugin-csstext Display cssText from CSSOM
More plugins welcome!
Demos
Tools
cssobj-converter Try Online Version
Helpers
cssobj-mithril Help cssobj to work with mithril
More helper welcome!
Test
Using phantom 2.0 to test with CSSOM. Please see test/ folder.
Remark
cssobj is wrapper for cssobj-core, plugin-localize and plugin-cssom.
Contribute
Yes! We need you! Think below way:
-
Please use cssobj in your project.
-
Please tell your friend about cssobj.
-
Please post issues for your idea and for bug.
-
Please read source, improve it!
License
MIT © James Yang