@magic/css
@magic/css
parse/stringify/write css in js
NO dynamic css, css gets output as css file. whenever possible, use dynamic classes instead.
if there is absolute need for dynamic css, feel free to use the style property of the html tag / webcomponent you want to dynamically change, unfortunately, this library will not help you with that.
installation
npm install --save-exact @magic/cssusage:
cli:
@magic/css includes a cli script that can handle most usecases the internal javascript api allows.
to use this cli from any directory,
npm install -g @magic.css@magic/csscommands:stringify - convert css in js to cssparse - convert css in js to an array of key value pairsfull - get a full result object.flags:--minified - output minified css - alias: ["--m", "-m"]--help - alias: ["-h"]--out - directory to write output files to. omit to print to stdout - alias: ["--o", "-o"]--in - directory with source files, needs index.js to exist - alias: ["--i", "-i"]examples:mcss parse --in ./css --out ./cssmcss stringify --in ./styles --out ./css
import
import css from '@magic/css'api
css (full result)
import css from 'css'const style = {body: {color: 'green',},'.class': {color: 'orange',},'#id': {color: 'purple'},}const result = await css(style)// returnsObject {// nicely formatted css stringcss: 'body {\n color: green;\n}\n.class {\n color: orange;\n}\n#id{\n color: purple;\n}\n',// minimal whitespaceminified: 'body{color:green}.class{color:orange}#id{color:purple}',// array of used classes if anyclasses: ['.class'],// array of used ids if anyids: ['#id'],// array of used selectorsselectors: [],//ast of this css objectparsed: [],}
parse
const style = {'.className': {'#id': {color: 'orange',},},}const ast = css.parse(style)// ast[['.className #id', { color: 'orange' } ]]
stringify
const style = {'.className': {'#id': {color: 'white',},},}await css.stringify(style)// minified string`.className #id{color:white;}`
write to filesystem
const style = {'.className': {'#id': {color: opts.textColor,},},}// writes styles to ./out.csscss.write(style)// writes styles to ./outfile.csscss.write(style, { OUTFILE: './outfile.css' })
styles
styles are a javascript object. the keys are selectors and the values are nested objects of css rules, where the keys of the objects are assumed to be selectors unless the value associated with the key is not an object
const style = {'.className': {color: 'green',},}await css.stringify(style)// .className { color:green; }
pseudo classes: (:hover, :active)
css pseudo classes in nested css get found if their object key starts with a &
const style = {'div': {color: 'red','&:hover': {color: 'green',},},}await css.stringify(style)// div { color: red; }// div:hover { color: green; }
selector nesting
const style = {'div': {'p, &:hover': {color: 'red',},},}await css.stringify(style)// div p, div:hover { color: red; }
prefix without space
to prefix the parent of the selector using the child selectors, add a & at the end of any selectors but the last one.
const style = {'.class': {'p&, :hover': {color: 'orange',},},}await css.stringify(style)// p.class, .class:hover { color: orange; }
prefix all without space
if the & is at the end of a selector, the & will be applied to each of them.
const style = {'.class': {'div, p&': {color: 'orange';},},}await css.stringify(style)// div.class, p.class { color: orange; }
prefix with space
to prefix the parent with a space, use a double && instead of a single &
const style = {'#id': {'.class2&&, .class3': {color: 'orange';},},}await css.stringify(style)// .class2 #id, #id.class3 { color: orange; }
prefix all with space
if the && is at the end of a selector, the && will be applied to each of them.
const style = {'.class': {'div, p&&': {color: 'orange';},},}await css.stringify(style)// div .class, p .class { color: orange; }
media queries
Mediaqueries can use the vars.widths object to determine appropriate breakpoint sizes.
Default widths:
vars.widths = {tablet: '500px',laptop: '900px',desktop: '1200px',agency: '1600px',}
Usage of the vars.widths in media queries:
const style = {[`@media screen and(min-width: ${vars.widths?.tablet || '500px'})`]: {'#id': {color: opts.textColor,},},}await css.stringify(style)// css string`@media screen and (min-width: 500px) {#id {color: green;}}`
keyframes for animations
const style = {'@keyframes anim-name': {from: {opacity: 0,},to: {opacity: 1,}}await css.stringify(style)// css string`@keyframes anim-name {from {opacity: 0;}to {opacity: 1;}}`
webfonts
Font V2
This approach allows definition of font-style, font-weight, and local font names.
Pseudocode
@font-face: {family: 'name',url: '/fonts/',styles: {(normal|italic): {weight: ['LocalName', 'Local Name']}}}
const style = {'@font-face': {family: 'font-name',url: '/fonts/',styles: {normal: {400: ['FontName', 'Font Name'],600: ['FontNameBold', 'Font Name Bold']},italic: {400: ['FontNameItalic', 'Font Name Italic'],},},},}const out = await css.stringify(style)// out.css string@font-face {font-family: 'font-name';font-style: normal;font-weight: 400;src:local('FontName'),local('Font Name'),url('/fonts/font-name-400-normal.woff2') format('woff2');}@font-face {font-family: 'font-name';font-style: normal;font-weight: 600;src:local('FontNameBold'),local('Font Name Bold'),url('/fonts/font-name-600-normal.woff2') format('woff2');}@font-face {font-family: 'font-name';font-style: italic;font-weight: 400;src:local('FontNameItalic'),local('Font Name Italic'),url('/fonts/font-name-400-italic.woff2') format('woff2');}
Font V1 - DEPRECATED
This approach does not allow definition of local fonts to load, and therefore is deprecated.
const style = {'@font-face': {family: 'font-name',url: '/fonts/',styles: ['normal', 'italic'],weights: [400, 600],},}const out = await css.stringify(style)// out.css string@font-face {font-family: 'font-name';font-style: normal;font-weight: normal;src: url('/fonts/font-name-400-normal.eot');src: url('/fonts/font-name-400-normal.eot#iefix') format('embedded-opentype'),',url('/fonts/font-name-400-normal.ttf') format('truetype'),',url('/fonts/font-name-400-normal.woff') format('woff'),',url('/fonts/font-name-400-normal.woff2') format('woff2'),',url('/fonts/font-name-400-normal.svg#font-name') format('svg');',}// ... repeated for all styles and weights that were defined
css overload
Css allows overloads for props, to provide fallback values for old browsers
{body: {color: ['green', 'red'],},}
turns into
body {color: green;color: red;}
source
the source for this page is in the example directory and gets built and published to github using @magic/core