UNPKG

cssx

Version:
341 lines (233 loc) 8.38 kB
# CSSX - CSS in JavaScript > Generate and/or apply CSS with JavaScript. --- ## Download * [cssx.js](http://krasimir.github.io/cssx/packages/cssx/lib/cssx.js) - CSSX library (uncompressed) * [cssx.min.js](http://krasimir.github.io/cssx/packages/cssx/lib/cssx.min.js) - CSSX library (compressed) * Or get the same file via CDN [cdnjs.com/libraries/cssx](https://cdnjs.com/libraries/cssx) (For source maps check [here](./lib)) --- ## API * [Top level](#top-level-api) * [Stylesheet](#stylesheet-api) * [Rule](#rule-api) --- ## How it works CSSX is a tiny library that provides a JavaScript API for defining CSS styles. We create a stylesheet and register rules same as we do with the regular CSS files. The library generates valid CSS and injects it into head of the page as a `<style>` tag. Every change in the stylesheet afterwards is translated into a change in the same `<style>` tag. *Why is this useful?*. Well, JavaScript is a rich language and it gives us more flexibility. There are parts of our applications that require different styles. In such cases we normally use different CSS classes. We add or remove them based on conditional logic. So we have to amend two different parts of our codebase - our CSS and our JavaScript. For example: ```js var updateStyles = function (size) { var stylesheet = cssx('my-styles'); var body = stylesheet.add({ body: { 'font-size': size + 'px' } }); body.descendant({ h1: { 'font-size': '2em' } }); body.descendant({ small: { 'font-size': '0.8em' } }); } updateStyles(18); /* results in the following <style> tag: <style id="my-styles" type="text/css"> body { font-size: 18px; } body h1 { font-size: 2em; } body small { font-size: 0.8em; } </style> */ ``` **Nota bene!** CSSX is not meant to be used for all the styles in our pages. Of course that we need a basic styles for typography, layout, coloring etc. It's purpose is to make the *dynamic* parts of our CSS more flexible and easy to control. --- ## Simple usage ```html <script src="cssx.min.js"></script> <script> var updateStyles = function (size) { var stylesheet = cssx('my-styles'); var body = stylesheet.add({ body: { 'font-size': size + 'px' } }); body.descendant({ h1: { 'font-size': '2em' } }); body.descendant({ small: { 'font-size': '0.8em' } }); } updateStyles(18); </script> ``` A demo JSBin here [http://jsbin.com/memera/edit?js,output](http://jsbin.com/memera/edit?js,output). --- ## Installation Drop `cssx.min.js` on your page or run `npm i cssx` in node. --- # API --- ## Top level API #### `cssx(<id>)` * `id` - an unique ID of your stylesheet. It's an optional parameter but we recommend setting it. Creates a **stylesheet** object which represents a single `<style>` tag. #### `cssx.clear()` It removes all added rules from all stylesheets. #### `cssx.plugins(<array>)` Accepts array of functions. More about plugins [here](https://github.com/krasimir/cssx/blob/master/docs/plugins.md). #### `cssx.getStylesheets()` Returns an array with all the CSSX stylesheets. #### `cssx.getCSS()` Returns the CSS generated by all the stylesheets. #### `cssx.domChanges(<boolean>)` * `boolean` - if set to `false` the library is not performing any DOM manipulations. Or in other words, it's NOT creating/updating a `<style>` tag. #### `cssx.minify(<boolean>)` * `boolean` - if set to `false` the generated CSS is NOT minified. #### `cssx.nextTick(<boolean>)` * `boolean` - CSSX library applies the CSS automatically by editing the content of a `<style>` tag. There is a mechanism that applies multiple changes at once. It's similar to what [`requestAnimationFrame`](https://developer.mozilla.org/en-US/docs/Web/API/window/requestAnimationFrame) is doing. It's not recommended setting it to `false`. --- ## Stylesheet API #### `<stylesheet>.add(<styles object>)` * `styles object` - JSON representation of your CSS styles It returns a **rule** object that represents a single CSS rule. If we pass an object with more then one rule then it returns an array of CSS rules. For example: ```js var sheet = cssx(); var header = sheet.add({ '.header': { margin: 0 } }); header.descendant({ h1: { 'font-size': '20px' } }); /* .header { margin: 0; } .header h1 { font-size: 20px; } */ ``` #### `<stylesheet>.update(<styles object>)` * `<styles object>` - JSON representation of your CSS styles That's basically an alias of the above `.add` method. Both methods first check if the rules exists and if yes then internally calls the [`update`](#ruleupdateselector-new-styles) method of the [CSSX rule object](#rule-api). Let's say that we have the following stylesheet: ```js var sheet = cssx(); sheet.add({ body: { margin: 0, padding: 0 }, 'body p': { 'font-size': '20px' } }); sheet.update({ 'body p': { 'font-size': '1em' } }); ``` The result will be: ```css body { margin: 0; padding: 0; } body p { font-size: 1em; } ``` #### `<stylesheet>.define(<prop name>, <func>)` * `prop name` - string defining the custom property * `func` - function that receives the value of the property and returns a new object containing valid CSS properties. This API is about creating custom properties. For example: ```js var sheet = cssx(); sheet.define('button', function (color) { return { 'color': color, 'border': 'solid 2px ' + color, 'display': 'block', 'padding-left': '1em' } }); sheet.add({ 'section > a': { button: '#00FF00' } }); /* produces section > a { color: #00FF00; border: solid 2px #00FF00; display: block; padding-left: 1em; } */ ``` #### `<stylesheet>.id()` Surprisingly, it returns the `id` of the stylesheet. #### `<stylesheet>.rules()` An array of all registered rules in a raw format. #### `<stylesheet>.compile()` Traverses the added rules and transforms them to CSS. At the end applies the result to the DOM. You DON'T have to call this function. It's automatically run by the library. #### `<stylesheet>.compileImmediate()` When `nextTick` is set to `true` (which is by default) calling `compile` does not update the CSS on the page immediate. It happens in the next tick. This function is helpful if we want to see the result right after the change. #### `<stylesheet>.clear()` or `<stylesheet>.destroy()` It clears the registered styles. #### `<stylesheet>.getCSS()` Returns the CSS based on the added rules. Under the hood calls `compileImmediate`. #### `<stylesheet>.scope(<selector>)` All the selectors inside the stylesheet are prefixed with the given `<selector>`. ``` var sheet = cssx(); sheet.scope('#component'); sheet.add({ 'p': { 'font-size': '10px' }, a: { margin: '10px' } }); /* produces #component p { font-size: 10px; } #component a { margin: 10px; } */ ``` --- ## Rule API #### `<rule>.descendant(<styles object>)` or `<rule>.d(<styles object>)` * `styles object` - JSON representation of your CSS styles Returns a **rule** object that represents a single CSS rule. *It calls `<stylesheet>.add` method internally.* #### `<rule>.nested(<styles object>)` or `<rule>.n(<styles object>)` * `styles object` - JSON representation of your CSS styles Returns a **rule** object that represents a single CSS rule. *It calls `<stylesheet>.add` method internally.*. This method produces nested rules (like media queries or `@keyframes` definitions) ```js var stylesheet = cssx(); var media = stylesheet.add({ '@media screen and (min-width: 200px)': {} }); media.nested({ p: { margin: '10px' } }); /* It produces the following CSS @media screen and (min-width: 200px) { p { margin: 10px; } } */ ``` In theory it could be used for producing nested rules which doesn't make any sense right now because they are not supported by the browsers. It may be useful though for generating SASS or LESS. ```js var stylesheet = cssx(); var body = stylesheet.add({ 'body': { 'font-size': '20px' } }); body.nested({ 'p': { margin: '10px' } }); /* It produces the following CSS body { font-size: 20px; p { margin: 10px; } } */ ``` #### `<rule>.update(<properties>)` * `properties` - JSON representation of your CSS properties --- # Where to go from here * [CSSX *language*](https://github.com/krasimir/cssx/blob/master/docs/cssx-lang.md) * [CSSX transpiler](https://github.com/krasimir/cssx/tree/master/packages/cssx-transpiler)