0

I use the following code to make all text red in a webpage:

var myCss = document.createElement("style");
myCss.type = "text/css";
myCss.innerHTML = " * {color: red !important} ";
document.body.appendChild(myCss);

This code works but I need a way to insert a few rows of CSS code, instead just one.

I tried this instead, but didn't work:

var cssArray = ["
   * {color: blue !important}
   * {background: white !important}
   #myId {display: block}
   .myClass {display: inline-block}
"];

var myCss = document.createElement("style");
myCss.type = "text/css";
myCss.innerHTML = cssArray;
document.body.appendChild(myCss);

I went through many SE QA sessions and all I found deals with adding a single CSS row as I used above. If there is no way to inject several CSS rows in one command, is there any "dirty" workaround you know?

user8551674
  • 173
  • 1
  • 2
  • 13
  • did you try appending it to `head` instead of `body`? – Shiran Dror Sep 02 '17 at 12:49
  • Shiran Dror, I didn't - What difference should it make? NewToJS, why do we need the [0]? Thanks, – user8551674 Sep 02 '17 at 13:10
  • I think there is some kind of misunderstanding: I know what is an array in JS and that to access a certain array item we need an item reference like `[0]`, but I miss why you say there is only one item? I want to use all items whatsoever. – user8551674 Sep 02 '17 at 13:54
  • Oh I know understand what you meant. Sorry. I didn't think of strings this why "array with string". I putted each new line without quote marks because I thought it's okay syntactically but of course, I was wrong. Your nickname here is NewToJS but I'm even newer. Thx. – user8551674 Sep 02 '17 at 14:19
  • use backticks `` for multiline strings – caub Sep 02 '17 at 14:41

5 Answers5

2

You can do multiple lines of css within a string if you want. You don't need an array to do this.

For readability purposes, you can set your multiline style string using an ES6 template literal:

// ES6 template literal `backtick` syntax
var myCss = `
  * {background: blue;}
  h2 {background: #333; color: red;}`,

  head = document.head || document.getElementsByTagName("head")[0],
  style = document.createElement("style");

style.type = "text/css";
style.styleSheet ? style.styleSheet.cssText = myCss : style.appendChild(document.createTextNode(myCss));

head.appendChild(style);
<h2>Styled with js</h2>

See also this CodePen Demo.


Note: If you want to support IE or obscure browsers, you might not want to use es6 template literals.

If that's the case, you can simply make a string of css:

var myCss = "* {background: blue;} h2 {background: #333; color: red;}";

or you can concatenate the string on multiple lines.

var myCss = 
  "* {background: blue;} " +
  "h2 {background: #333; color: red;}";

You could use your original code as well and set your css string in the backtick syntax.

The problem is that your code will insert the styles into the body. This can produce a flash of unstyled content - see this answer for more information.

Therefore I recommend inserting the styles into the head, which the code above does.


Dan Kreiger
  • 5,358
  • 2
  • 23
  • 27
  • Much thanks. Can you please edit the answer to do it only with ES6, and keep only the code relevant for the list of CSS and running it)? I believe it could improve the answer and grant more thumb ups. – user8551674 Sep 02 '17 at 13:35
  • No problem! I'm a bit long winded today. I shortened the answer. However, if you want good IE support, you could just use a normal string. ES6 template literals are syntactical sugar for multiline strings. – Dan Kreiger Sep 02 '17 at 14:10
  • Thx for the nice response! AAMOF, I really don't care for IE support as long as Edge is supported. – user8551674 Sep 02 '17 at 14:15
  • I learned so much from this answer. Would thumb up if I could but for now I can't. I learned that `cssText` is a property of the `styleSheet` object, which (as I understand) is the internal stylesheet of HTML webpage, hence should be categorized as an HTML element. – user8551674 Sep 02 '17 at 16:02
  • Also I understand the ternary operation says this: `// IF... style tag has a styleSheet, put its myCss as its code. ELSE... createTextNode with the contents of myCSS for later use. ` – user8551674 Sep 02 '17 at 16:08
  • Put myCss as its cssText* – user8551674 Sep 02 '17 at 19:22
  • Dan can you pelase only change `css` to `myCss`? I changed that in the question, only that. Thanks again!!! – user8551674 Sep 02 '17 at 19:23
  • Sure - I updated `css` to `myCSS` - [`cssText`](https://developer.mozilla.org/en-US/docs/Web/API/CSSRule/cssText) is a JS property, so that can't be changed. But of course we can rename the variable `css` as `myCss`. – Dan Kreiger Sep 02 '17 at 20:16
  • Sure I meant that the `cssText` will include the code available in `myCss`. Thanks for the update. – user8551674 Sep 03 '17 at 00:26
0

Try myCss.setAtrribute("style","color: blue !important; background: white !important; display: block;");

  • But this will just add the style attribute with inline styles. The Op is wanting to create a style tag so the styles will apply to multiple elements... – NewToJS Sep 02 '17 at 13:00
  • Then, i think you can simply set all of your style you need as a string variable like `var MyStyle = "color: blue !important; background: white !important; display: block;"` then you can use this variable with any element in your Dom like `myId.setAttribute("style",MyStyle); myClass.setAttribute("style",MyStyle);` and so on. – mohamed maher Sep 02 '17 at 13:08
  • @mohamedmaher but that would mean looping/iterating through all of those elements. I think the idea behind creating the new `style` tag and applying styles within it is to avoid having to run a loop on those elements. – NewToJS Sep 02 '17 at 13:34
0

As you are using array of string to set innerHTML, so you will require array index. Try using: myCss.innerHTML = cssArray[0];

Kaal
  • 1
  • 2
0

Just join the array strings before passing it to innerHTML.

var cssArray = ["
   * {color: blue !important}
   * {background: white !important}
   #myId {display: block}
   .myClass {display: inline-block}
"];

var myCss = document.createElement("style");
myCss.type = "text/css";
myCss.innerHTML = cssArray.join('');
document.body.appendChild(myCss);
user8551674
  • 173
  • 1
  • 2
  • 13
felixmosh
  • 32,615
  • 9
  • 69
  • 88
0

Please don't thumb up this answer. Thumb up Dan Kreiger's answer instead.

The following code is based on Dan Krieger's answer and is actually 99% like Dan's answer (I tried to suggest this as edit by my edit was rejected by the SE team so I publish in an answer).

It works fine also:


let myCss =`
   .site_mainTable > tbody:nth-child(1) > tr:nth-child(1) > td:nth-child(4) {display: none}
   .site_mainTable > tbody:nth-child(1) > tr:nth-child(1) > td:nth-child(5) {display: none}
   gallery-banner, .gallery-banner-gl {display: none}
`;

style = document.createElement("style");
style.type = "text/css";
style.styleSheet ? style.styleSheet.cssText = myCss : style.appendChild(document.createTextNode(myCss) );
   // IF... style tag has a styleSheet, put its cssText as myCSS. ELSE... createTextNode with the contents of myCSS for later use. 

head = document.head || document.getElementsByTagName("head")[0];
head.appendChild(style);

All credit to Dan Kreiger.

user8551674
  • 173
  • 1
  • 2
  • 13