How to convert a JSON style object to a CSS string?

Use https://www.npmjs.com/package/json-to-css. Note it will not add a semicolon to the last property to fix it you can beautify it with https://www.npmjs.com/package/cssbeautify Example


    const cssbeautify = require('cssbeautify')

    const Css = require('json-to-css')

    const json = {
        "h1": {
            "font-size": "18vw",
            "color": "#f00"
        },
        ".btn": {
            "font-size": "18vw",
            "color": "#f00"
        }
    }


    const r = Css.of(json)
    console.log(r)

    const beautified = cssbeautify(r, {
        autosemicolon: true
    })

    console.log(beautified)

Result


  console.log src/utils/playground/index.spec.ts:22 // json-to-css
    h1{font-size:18vw;color:#f00}
    .btn{font-size:18vw;color:#f00}

  console.log src/utils/playground/index.spec.ts:29 // cssbeautify
    h1 {
        font-size: 18vw;
        color: #f00;
    }
    
    .btn {
        font-size: 18vw;
        color: #f00;
    }
   

Adding to the great answer of @Artem Bochkarev

I'm adding a snippet to do the opposite conversion as well (string to object) which may come in handy to anyone stumbling here

const style = {
  width: '1px',
  height: '1px',
  backgroundColor: 'red',
  transform: 'rotateZ(45deg)',
};
const styleToString = (style) => {
  return Object.keys(style).reduce((acc, key) => (
    acc + key.split(/(?=[A-Z])/).join('-').toLowerCase() + ':' + style[key] + ';'
  ), '');
};
const stringToStyle = (style) => {
  const styles = {};
  style.split(';').forEach((s) => {
    const parts = s.split(':', 2);
    if (parts.length > 1) {
      styles[parts[0].trim().replace(/-([a-z])/ig, (_, l) => l.toUpperCase())] = parts[1].trim();
    }
  });
  return styles;
};

console.log(styleToString(style));
// output - "width:1px;height:1px;background-color:red;transform:rotateZ(45deg);"

console.log(stringToStyle(styleToString(style)));

this solution works in IE and handles camelCase keys like backgroundColor

const style = {
    width: '1px',
    height: '1px',
    backgroundColor: 'red',
    transform: 'rotateZ(45deg)',
}
const styleToString = (style) => {
    return Object.keys(style).reduce((acc, key) => (
        acc + key.split(/(?=[A-Z])/).join('-').toLowerCase() + ':' + style[key] + ';'
    ), '');
};

console.log(styleToString(style));
// output - "width:1px;height:1px;background-color:red;transform:rotateZ(45deg);"

A performant answer is to map and join the Object.entries with semicolons:

const style = {
  ...this.props.style,
  background: 'blue',
};

const styleString = (
  Object.entries(style).map(([k, v]) => `${k}:${v}`).join(';')
);

It unwraps background:'blue', to background:blue; which works well for CSS


To replace any capital letter with dash lowercase letter

k = k.replace(/[A-Z]/g, match => `-${match.toLowerCase()}`);