DEV Community

Yusuff, Olawumi Qauzeem
Yusuff, Olawumi Qauzeem

Posted on • Edited on

Convert HTML Inline Styles to a Style Object for React Components

I once found myself having to copy some HTML elements and convert into JSX. The elements were accompanied with inline styles that React was evidently not happy with 😡.

JSX with inline style string attribute error

Erm... React is not happy with this 😒

React expects an object, with property names unhyphenated but in camel case, to be passed into the style attribute. I could do it manually but it gets boring and error prone with time. So I decided to write a Javascript function that automates the conversion.

Main function is "getStyleObjectFromString" while "formatStringToCamelCase" is a helper function.

Given a string "display: flex; flex-direction: column; align-items: center; -webkit-align-items: center" passed into getStyleObjectFromString as an argument, an empty object literal is created. On line 15 the string is split around all semicolons resulting in an array of strings ```["display:

flex", "flex-direction: column", "align-items: center", "-webkit-align-items: center", ""]


The array of string is then looped over using the Array's `forEach` method. `forEach` takes a callback function that receives each element of the array per iteration as argument. Our callback function splits each element around the colon (":"), separating the CSS property name and value. It assigns these to `property` and `value` variable names.

Given `"display: flex"`, property will equal `"display"` while value equals `" flex"`. Given an empty string (the last element in the array), property will equal `""` while value equals `undefined` (both falsy values).

On line 17, the function returns if `property` is falsy. On line 19, the trimmed property name - cuz "edge cases" :wink: - is passed into `formatStringToCamelCase` which splits the string parameter around every occurence of an hyphen ("-") then changes the first letter in every other word besides the first to an uppercase letter. It then joins every word together. If `"align-items"` was passed, this operation will give `"alignItems"`.

The result from `formatStringToCamelCase` is our property name, in the right format, to be used in our style object to point to the trimmed `value` string.

At the end of the day, `"display: flex; flex-direction: column; align-items: center; align-items: center; -webkit-align-items: center"` gives `{ display: "flex", flexDirection: "column", alignItems: "center", WebkitAlignItems: "center" }`.

You can check out the demo on [Code Sandbox](https://codesandbox.io/s/react-inline-css-to-style-object-drc0r)
Enter fullscreen mode Exit fullscreen mode

Top comments (3)

Collapse
 
neoscrib profile image
Tanner Jepsen • Edited

There's a far simpler way to do this while leveraging the browser to do all the work for us:

function parseInlineStyle(style) {
    const template = document.createElement('template');
    template.setAttribute('style', style)
    return Object.entries(template.style)
        .filter(([ key ]) => !/^[0-9]+$/.test(key))
        .filter(([ , value ]) => Boolean(value))
        .reduce((acc, [ key, value ]) => ({ ...acc, [key]: value }), {});
}
Enter fullscreen mode Exit fullscreen mode
Collapse
 
samselfridge profile image
samselfridge

Thanks for this! just had to convert a html template to react and this was a timesaver!

Might be good to tweak it so it allows whitespace at the end. Most strings would always be: style=" color: red; " with white space after the last ; because of auto-formatting and I had to keep deleting it. Looking back, probably would have been faster to tweak the code myself, but I thought it was only a few that had that issue, not most of them.

Collapse
 
qausim profile image
Yusuff, Olawumi Qauzeem

I'm glad it helped. Thanks for the suggestion, I'll work on it.