If I've added styles with CSSOM using insertRule
I've noticed two things.
The added styles don't appear in the html while viewing in Firebug ever.
The added styles don't work if the style tag is appended (ex: moved from head to body) to another element (Happens in Firefox, and Chrome).
If the styles are added after the tag is appended then they do work. They still don't show in Firebug. When appending the sheet has to be reassigned (regetted?) which makes it appear even stranger.
For not showing in Firebug it could be a quirk with Firebug, but regular styles that are not added dynamically show up.
For the styles not working after the append I'm wondering if this is the standard because this happens in Firefox, and Chrome. Looking at the standards I didn't see anything about this. Unless I just don't understand them.
var style = document.createElement('style'),
sheet = style.sheet;
document.head.appendChild(style);
//When line 6 is un-commented the styles work
//if line 8 is also commented out.
//document.querySelector('.container').appendChild(style);
//Get the sheet when line 6 is un-commented
sheet = style.sheet
sheet.insertRule('.test{color: red}');
document.querySelector('.container').appendChild(style);
//styles don't apply after the previous line
Edit for clarity:
If you append a <style></style>
tag to the <head></head>
of html you can apply styles with style.sheet.insertRule(styleString)
, and added styles will apply for the document.
If you have already appended that <style></style>
to the <head></head>
like <head><style></style></head>
, and attempt to append <style></style>
somewhere else like <div><style></style></div>
all the styles are lost, and do not apply again.
Is this normal?
The code flow:
Works:
- append
<style>
any where - add styles with
style.sheet.insertRule(styleString)
Doesn't work:
- append
<style>
any where - add styles with
style.sheet.insertRule(styleString)
to<style>
- append same
<style>
somewhere else
My other issue is that styles added to <style></style>
don't show up in Firebug
even if they have applied to the document.
Edit more clarity:
If I reappend the style
element without having modified the stylesheet, the styles remain:
var style = document.querySelector('style');
document.head.appendChild(style);
* {color: red}
<p>Hello world</p>
But if I have altered the stylesheet with JS, the changes are undone:
var style = document.querySelector('style'),
sheet = style.sheet;
sheet.insertRule('* {color: red}', 0);
document.head.appendChild(style); //Comment this line out, and this works.
/* CSS rules will be inserted with JS */
<p>Hello world</p>
div{color:green};div{color:blue}
blue
would becolor
set atdiv
as it is last declaration. See #1043501 – Stroy<style>
by hand to the html then move it withappendChild
then the hand written styles in that tag apply. – Copepodstyle
attribute athtml
element should take precedence. Did you read all of the answers at linked Question? See also https://mcmap.net/q/81290/-how-are-the-points-in-css-specificity-calculated , w3.org/TR/CSS2/cascade.html#specificity – StroyinsertRule
requires 2 arguments. And usingquerySelector('style')
makes no sense if you don't have any<style>
element (here it worked because stack snippets insert a stylesheet). – Quetzalstyle
element, a new stylesheet is created from the text contents of thestyle
, not from the old one. Not sure if this is standardised, you can try looking at CSS Object Model, Document Object Model and maybe HTML5 specs. – QuetzalinsertRule
once without the second argument still works even in a local webpage without stack snippits. – Copepod<style>
already in<head>
to<head>
? – Stroy<body>
. – Quetzal