0

I need to create a function that parses a CSS string, that will be used on a inline js style.

E.g: what I get is something like const styles = "background-color:#FFFFFF;color:#000000" and I need to transform in:

      <h1
        className={classes}
        style={{ color: fontColor, background: backgroundColor }}
      >
        {copy}
      </h1>

what I do for now is this

const [backgroundColor, setBackgroundColor] = useState();
  const [fontColor, setFontColor] = useState();
  const colors = styles?.match(/(#)([^;]*)/g);

  useEffect(() => {
    if (colors) {
      if (colors.length > 1) {
        setBackgroundColor(colors[0]);
        setFontColor(colors[1]);
      }

      if (colors.length === 1) {
        setFontColor(colors[0]);
      }
    }
  }, [colors]);

But I was asked to create pure seperate function that parses the styles string.

So I was wondering if there's a solution where I don't need to "regex" each specific selector and then its value. If there's something like whatever is before the colon is the selector than after that until the semicolon is its value.

Any tips?

Thanks

1
  • yes its possible Commented Nov 27, 2020 at 14:36

2 Answers 2

2

You can do it like this and after that map your function with it

const styles = "background-color:#FFFFFF;color:#000000";

const css = styles.split(';').map(cur => cur.split(':'));

console.log(css);

const cssInObject = styles.split(';').map(cur => cur.split(':')).reduce((acc, val) => {
    let [key, value] = val;
    key = key.replace(/-./g, css => css.toUpperCase()[1])
    acc[key] = value;
    return acc;
}, {});

console.log(cssInObject);

Sign up to request clarification or add additional context in comments.

4 Comments

I added react way of css, look out
your solution works also on Safari!.. Great! Thanks! :)
I glad you like my answer, Thanks :)
Be careful when using this for more complex CSS, as url and others may contain :/; e.g. background-image: url("data:image/svg+xml;charset=UTF-8,%3Csvg%20...%3E");
2

Maybe something like this (which converts the css string to an object) (doesn't work on Safari):

const convertCssToObject = value => {
    
  const regex = /(?<=^|;)\s*([^:]+)\s*:\s*([^;]+)\s*/g, o = {};
  value.replace(regex, (m,p,v) => o[p] = v);
  return o;
    
}

console.log( convertCssToObject("background-color:#FFFFFF;color:#000000;") )

I've edited the regex so it works also on Safari:

const convertCssToObject = value => {
  // Without the look behind
  const regex = /([\w-.]+)\s*:([^;]+);?/g, o = {}; // Heck I think this should also work for Chrome as well
  value.replace(regex, (m,p,v) => o[p] = v);
  return o;
}

console.log( convertCssToObject("background-color:#FFFFFF;color:#000000;") )





2 Comments

unfortunately, I was just flagged that your solution does not work on Safari. I really liked cause it is very concise, but in the end, I won't be able to use it. Thanks anyway
Ah I guess Safari doesn't like to "look back". I'll update my comment

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.