简体   繁体   中英

CSS in JS for vanilla Javascript class

If I create a vanilla JS component like this:

class TestComponent {
  constructor(el) {
    this.render(el);
  }

  render(el) {
    var html = `
      <div>
        <p>Some dummy content</p>
      </div>
    `;
    document.getElementById(el).innerHTML = html;
  }
}

Can I add CSS in JS for it? I mean something like:

const styles = {
  backgroundColor: 'palevioletred',
  color: 'papayawhip',
};

so the above render method will look like this:

render(el) {
  var html = `
    <div style={styles}>
      <p>Some dummy content</p>
    </div>
  `;
  document.getElementById(el).innerHTML = html;
}

is that possible to do outside of frameworks like Angular / React ?

You are using a JS object into HTML (a String). So you have to convert your object into a valid HTML String:

const styles = {
  // CSS key is `background-color` instead of `backgroundColor`
  'background-color': 'palevioletred', 
  color: 'papayawhip',
}


render(el) {
  // Loop every keys, and create an array contain every
  // key:value
  // join every items on array to create a single String.
  var string_styles = Object.keys(styles).map(s => { 
    return s + ":" + styles[s]
  }).join(';')

  // Or
  string_styles = JsToCss(styles)  


  var html = '<div style="' + string_styles + '">' +
      '<p>Some dummy content</p>' +
    '</div>';
  document.getElementById(el).innerHTML = html;
}

// Decomposed function:
let JsToCss = (styles) => {
  let keys = Object.keys(styles) 
  // keys = [ 'background-color', 'color']

  let css_values = keys.map(key => {
    return key + ":" + styles
  })
  // css_values = [
  //     'background-color:palevioletred', 
  //     'color:papayawhip'
  // ]

  return css_values.join(';') 
  // return "background-color:palevioletred;color:papayawhip;" 
}

Code not tested but this is the idea

You would need to convert the object to valid CSS.

<div style={styles}> won't work because you are asking for an object to be converted to a string here and the conversion won't yield the result you want.

 const styles = { backgroundColor: 'palevioletred', color: 'papayawhip', }; console.log(styles.toString()); 

You could use JSON.stringify() , but even then, you'd need to remove the braces, convert commas to semi-colons, remove the excess quotes, and convert camel cased names to hyphenated names.

I've done all this below and broken it up into individual steps to show what has to be done, but it could be condensed into a single statement and even made more compact with a regular expression. But, this should give you the idea.

FYI : You need a $ in front of your template literal to identify it as such.

 const styles = { backgroundColor: 'palevioletred', color: 'papayawhip', }; let cssString = JSON.stringify(styles); console.log(cssString); // Remove the braces cssString = cssString.replace("{","").replace("}",""); console.log(cssString); // Remove the quotes cssString = cssString.replace(/"/g, "") console.log(cssString); // Change comma to semi-colon and add trailing semi-colon cssString = cssString.replace("," ,";") + ";"; console.log(cssString); // Convert camel case to hyphen cssString = cssString.replace("backgroundColor", "background-color"); console.log(cssString); class TestComponent { constructor(el) { this.render(el); } render(el) { var html = ` <div style=${cssString}> <p>Some dummy content</p> </div> `; document.getElementById(el).innerHTML = html; } } let tc = new TestComponent("test"); 
 <div id="test"></div> 

I made a simple genCSS function which takes CSS in the javascript object and converts into CSS string and generated CSS applied to style tag.

const genCSS = (style) => {
  let result = '';
  for (props in style) {
     let keyValuePair = `${props}:${style[props]};`;
     result += keyValuePair;
   }
   return result;
};

const styles = {
  background: '#2196f3',
  color: 'white',
  padding: '5px 10px'
};

class TestComponent {
  constructor(el) {
    this.render(el);
  }

  render(el) {
    const genStyle = genCSS(styles);

    var html = `
      <div style="${genStyle}">
        <p>Some dummy content</p>
      </div>
    `;
    document.getElementById(el).innerHTML = html;
  }
}

const test = new TestComponent('root');

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM