I'm working with a CMS that prevents us from editing the head section. I need to add css stylesheet to the site, right after the tag. Is there a way to do this with JS, where I can add a script to the bottom of the page (I have access to add script right before the tag) that would then inject the stylesheet into the head section?
-
2Literally a few questions down: http://stackoverflow.com/questions/11833325/css-hack-adding-css-in-the-body-of-a-website – Kwon Aug 06 '12 at 18:23
-
2what CMS are you using? There is usually at least some way provided to include them – John Kane Aug 06 '12 at 18:23
-
Inline or external stylesheet? – Šime Vidas Aug 06 '12 at 18:23
5 Answers
Update: According to specs, the link
element is not allowed in the body. However, most browsers will still render it just fine. So, to answer the questions in the comments - one really has to add link
to the head
of the page and not the body
.
function addCss(fileName) {
var head = document.head;
var link = document.createElement("link");
link.type = "text/css";
link.rel = "stylesheet";
link.href = fileName;
head.appendChild(link);
}
addCss('{my-url}');
Or a little bit easier with jquery
function addCss(fileName) {
var link = $("<link />",{
rel: "stylesheet",
type: "text/css",
href: fileName
})
$('head').append(link);
}
addCss("{my-url}");
Original answer:
You don't need necessarily add it to the head, just add it to the end of body tag.
$('body').append('<link rel="stylesheet" type="text/css" href="{url}">')
as Juan Mendes mentioned, you can insert stylesheet to the head instead
$('head').append('<link rel="stylesheet" type="text/css" href="{url}">')
And the same without jQuery (see code above)

- 3,916
- 2
- 38
- 62

- 17,449
- 6
- 44
- 82
-
3
-
@Juan Mendes, I know, but what I'm sayign is that it just can be inserted in the body – vittore Aug 06 '12 at 19:17
-
Hi vittore, I've added the second script you mentioned right before
tag, however, it doesn't seem to load the CSS within the head section... thoughts? The main problem, is we are creating a new stylesheet to overwrite the the stylesheet that the CMS forces us to use. So we created a NEW stylesheet to overwrite their settings. We woud like it to load RIGHT after they load theirs... otherwise, their stylesheet loads, and shows the site, and then a few seconds later, our changes show up...
– Rahil Pirani Aug 06 '12 at 19:39 -
Does anyone know, is there different between this two variant (dynamic css in head vs in body), as best practice or performance? – Rudolf Manusachi May 19 '16 at 19:08
-
I have attempted the method of appending the link element to the head and found that it works, however, this causes a very noticeable flash in the browser since everything is rerendered. I observed this on Google Chrome, but had users in all different browsers reporting it. I attempted this in two different products with the same result, and they both had very different HTML, indicating that the flash will occur regardless of what HTML is present. Long story short, I do not recommend adding the link to the head. – Trevor Oct 11 '17 at 16:56
-
@vittore according to me pure javascript is better as we can add the function in the head and call it in the head so when the page loads it shows proper to the user. – webdevanuj Mar 06 '21 at 07:01
This will do what you want in an intelligent way. Also using pure JS.
function loadStyle(href, callback){
// avoid duplicates
for(var i = 0; i < document.styleSheets.length; i++){
if(document.styleSheets[i].href == href){
return;
}
}
var head = document.getElementsByTagName('head')[0];
var link = document.createElement('link');
link.rel = 'stylesheet';
link.type = 'text/css';
link.href = href;
if (callback) { link.onload = function() { callback() } }
head.appendChild(link);
}

- 1,428
- 14
- 24
-
2I've edited to add missing `i` in the for loop: `if(document.styleSheets[i].href == href){` – cronoklee Mar 08 '16 at 11:47
-
I have attempted the method of appending the link element to the head and found that it works, however, this causes a very noticeable flash in the browser since everything is rerendered. I observed this on Google Chrome, but had users in all different browsers reporting it. I attempted this in two different products with the same result, and they both had very different HTML, indicating that the flash will occur regardless of what HTML is present. Long story short, I do not recommend adding the link to the head – Trevor Oct 11 '17 at 16:58
-
The solution is to control the rendering through JS as well. Like load the css before, what ever it is used for loads. You can add a callback argument and put an onload event inside the function. This will tell you when it is ready to be used. Same goes for other elements like frames, scripts, ect. – Eddie Dec 20 '17 at 22:12
-
upvote for considering the use case, where multiple style sheets could potientially be added. I used index of for my particular scenario for it to work, also had to check for null as for some reason one of the hrefs was null. ```if (document.styleSheets[i].href != null && document.styleSheets[i].href.indexOf(href) != -1)``` – chris c Nov 21 '19 at 05:57
I've modified Eddie's function to remove or toggle the stylesheet on or off. It will also return the current state of the stylesheet. This is useful for example, if you want to have a toggle button on your website for vision-impaired users and need to save their preference in a cookie.
function toggleStylesheet( href, onoff ){
var existingNode=0 //get existing stylesheet node if it already exists:
for(var i = 0; i < document.styleSheets.length; i++){
if( document.styleSheets[i].href && document.styleSheets[i].href.indexOf(href)>-1 ) existingNode = document.styleSheets[i].ownerNode
}
if(onoff == undefined) onoff = !existingNode //toggle on or off if undefined
if(onoff){ //TURN ON:
if(existingNode) return onoff //already exists so cancel now
var link = document.createElement('link');
link.rel = 'stylesheet';
link.type = 'text/css';
link.href = href;
document.getElementsByTagName('head')[0].appendChild(link);
}else{ //TURN OFF:
if(existingNode) existingNode.parentNode.removeChild(existingNode)
}
return onoff
}
Sample usage:
toggleStylesheet('myStyle.css') //toggle myStyle.css on or off
toggleStylesheet('myStyle.css',1) //add myStyle.css
toggleStylesheet('myStyle.css',0) //remove myStyle.css

- 6,482
- 9
- 52
- 80
-
2How about using the standard ``.disabled`` property on a StyleSheet to turn it on/off – Mr Allrood Feb 09 '17 at 10:54
-
Obviously that's an option and would be a little faster to turn on the second time, but this would require a third case in the function to handle the stylesheet already existing in a disabled state, so the function would be a little longer. – cronoklee Mar 14 '17 at 16:00
You can use pure javascript and still elegance in the modern browser.
const range = document.createRange()
const frag = range.createContextualFragment(`THE CONTENT IS THE SAME AS THE HTML.`)
document.querySelector("YOUR-NODE").append(frag)
It's very easy to add any HTML code.
Document
Example 1
Add the style on the head by javascript.
<head></head><body><button class="hover-danger">Hello World</button></body>
<script>
const range = document.createRange()
const frag = range.createContextualFragment(`
<style>
.hover-danger:hover{
background-color: red;
font-weight: 900
}
</style>
`
)
document.querySelector("head").append(frag)
</script>
Example 2
Import CSS, JS, and modify the existing stylesheet.
<head></head>
<body><button class="btn btn-primary hover-danger">Hello world</button></body>
<script>
const range = document.createRange()
const frag = range.createContextualFragment(`
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.0.2/dist/css/bootstrap.min.css" rel="stylesheet" crossorigin="anonymous">
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.0.2/dist/js/bootstrap.bundle.min.js"/>
`)
document.querySelector("head").append(frag)
window.onload = () => {
// If you don't want to import the new source, you can consider adding the data to exists source.
const nodeLink = document.querySelector(`link[href^="https://cdn.jsdelivr.net/npm/bootstrap@5.0.2/dist/css/bootstrap.min.css"]`) // ^: match begin with my input
if (nodeLink) { // !== null
const stylesheet = nodeLink.sheet
const myCSS = `
background-color:red;
font-weight: 900;
`
stylesheet.insertRule(`.hover-danger:hover{ ${myCSS} }`, stylesheet.cssRules.length)
}
}
</script>
You must have permission to modify the CSS directly
If you get the error:
Failed to read the 'cssRules' property from 'CSSStyleSheet': Cannot access rules,
then you can reference: https://stackoverflow.com/a/49994161/9935654

- 6,105
- 2
- 37
- 45
Here is a simple one-liner to add a stylesheet:
document.head.insertAdjacentHTML('beforeend', `<link typs="text/css" rel="stylesheet" href="<Source URL>">`);

- 1,062
- 8
- 10