DEV Community

Yusuff, Olawumi Qauzeem
Yusuff, Olawumi Qauzeem

Posted on • Updated 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" 😉 - 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

Latest 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.