UNPKG

j2c

Version:

A tiny CSS in JS solution.

225 lines (178 loc) 5.71 kB
## `j2c.sheet(rules)` — for building a style sheet Everything found in the `inline` section applies here too, I recommend you read it first. To give you a taste of what can be done in j2c, here's a first, rather advanced example. ```JavaScript s = j2c.sheet({ "ul.foo": { "@media condition": { color: "red" }, // properties for the main ul.my_root_class elements font: { size: "2em", family: "sans-serif" }, // underscores in property names are converted to dashes. backgroundColor: "#44f", // CamelCase is also automatically handled. borderRadius:"2px", // sub-selector for children element, notice the mandatory initial space // signifying a child element. " li": { padding:{ left: "5px", top: "10px" }, // convenient $ shortcut. border: {left$right: {width: "2px"}} } } }) ``` ```CSS ul.foo_j2c_fgdl0s2a5fmle5g56rbuax71 li{ padding-left:5px; padding-top:10px; border-left-width:2px; border-right-width:2px; } ul.foo_j2c_fgdl0s2a5fmle5g56rbuax71{ font-size:2em; font-family:sans-serif; background-color:#44f; } @media condition{ ul.foo_j2c_fgdl0s2a5fmle5g56rbuax71{ color:red; } } ``` Were `s.foo === "foo_j2c_fgdl0s2a5fmle5g56rbuax71_0 "` #### Global class and animation names. You can define or refer to global names using the `@global{}` pseudo at-rule, and the `:global()` function. This will thus preserve the `.foo`, `.bar` and `baz` names: ```JavaScript s = j2c.sheet({ "@global": { "ul.foo": { font_size: "2em", } }, "p:global(.bar)" :{ color:"#f00", animation_name: ":global(baz)" }, "@keyframes :global(baz)": { // define the global "baz" animation here. } }) ``` `@global` blocks also globalize animation names (not shown above). #### Combining multiple selectors TODO: refactor this section to mention the SASS-like `&` placeholder (at any arbitrary position). Here's a excerpt from the `j2c` port of the [PocketGrid](https://github.com/arnaudleray/pocketgrid/blob/44aa1154a56b11a852f7252943f265028c28f056/pocketgrid.css). ```JavaScript j2c.sheet({"@global": { ".block,.blockgroup":{ ",:before,:after":{ // Notice the initial coma. box_sizing:"border-box" } } }}) ``` Nesting `",:before,:after"` inside the `".block,.blockgroup"` block combines `[".block", ".blockgroup"]` with `["", ":before", ":after"]`, giving ```CSS .block,.block:before,.block:after,.blockgroup,.blockgroup:before,.blockgroup:after{ box-sizing:border-box; } ``` Mathy folks call this as a Cartesian product. #### At-rules `j2c` handles @-rules out of the box, including nested ones. ```JavaScript j2c.sheet({ "@media screen": { " p": { foo:"bar", "@media (orientation: landscape)": { baz:"qux" } } } }) ``` becomes ```CSS @media screen { p { foo: bar; } @media (orientation: landscape) { p { baz: qux; } } } ``` For `@keyframes` rules, a `@-webkit-keyframes` block is automatically created with auto-prefixed property names. #### Mixins and `@coposes` Mixins and `@composes` make `j2c` sheets composable. Both techniques can be combined. ##### Mixins and source objects composition For mixins, arrays works the same way at the selector level as they do at the property/value one. You can therefore use the [method described in the "inline" section](#mixins) to create mixins, that can return either at-rules, selectors, properties or a mix thereof. ##### `@composes` `j2c` also supports `@composes`, which works a bit like the SASS`@extend`, more powerful in some regards, but more limited in others. The limitation is that it can only deal with classes. Specifically: ```JS sheet = j2c.sheet({ '.red': { color: '#f00' }, '.great': { fontSize: '3em' }, // `scarlet` here is the target of the composition, `great` and `red` are the sources. '.scarlet': { '@composes': ['.great', '.red'] // you can also pass a single class } }) ``` `sheet.scarlet` is now defined as `'great__j2c-xxx red__j2c-xxx scarlet__j2c-xxx'` (class names truncated for readability). The extra power comes from the fact that you can inherit from arbitrary classes, not just j2c-defined ones: ```JS sheet = j2c.sheet(namespace, { '.myButton': { '@composes': ':global(.button)', // coming, say, form Bootstrap color: theme.highlight } }) ``` Here, `sheet.myButton` is `'button myButton_j2c...'`. While the `@composes` sources can be arbitrary classes, the target must be a local one. It will not work in global context. `@composes` doesn't support nested selectors, and doesn't work in conditional at rules. Its target must lie at the first nesting level. #### CSS Hacks Since `j2c.sheet` only accepts property names that match `/^[-_0-9A-Za-z$]+$/`, it is not possible to express CSS hacks using objects. You can, however, work around the issue by using arrays and strings instead. Here's another modified excerpt from the PocketGrid port: ```JavaScript j2c.sheet({ ".blockgroup": [ "*zoom: 1; /* hackety hackery */", { "list-style-type":"none", padding:0, margin:0 } ] }) ``` Array elements are inserted in sequence, and string literals are treated as a list of properties, and inserted as is. Result: ```CSS .blockgroup{ *zoom: 1; /* hackety hackery */ } .blockgroup{ list-style-type:none; padding:0; margin:0; } ``` You can also pass th result of `j2c.inline` which is less picky about property names.