How to Create a <style> Tag with JavaScript
Dynamically adding CSS rules to a page is a powerful technique for creating responsive user interfaces, theming, or applying styles based on user actions. While you can manipulate individual element styles with element.style, a more efficient way to add a block of CSS rules is by creating a <style> element and appending it to the document's <head>.
This guide will teach you the standard and most secure method for creating a <style> tag. We will also cover the more advanced CSS Object Model (CSSOM) for programmatically inserting individual rules.
The Core Task: Dynamically Injecting CSS
The goal is to add new CSS rules to the current document at runtime. The best place to add a <style> tag is inside the document.head.
Consider this HTML code for next examples:
<div id="box">This is a box.</div>
The Standard Method (Recommended): createElement and textContent
This is the safest, most readable, and most common way to create a style tag.
The logic:
- Use
document.createElement('style')to create a new<style>element in memory. - Set its
.textContentproperty to a string containing all your CSS rules. - Append the new element to the
document.head.
Solution:
// 1. Create a <style> element
const styleElement = document.createElement('style');
// 2. Add the CSS rules to the style element
// Use a template literal (backticks) for easy multi-line strings
styleElement.textContent = `
body {
background-color: lightgray;
}
#box {
background-color: salmon;
color: white;
padding: 20px;
}
`;
// 3. Append the <style> element to the <head>
document.head.appendChild(styleElement);
This is the recommended best practice because it is safe and its intent is very clear. Using .textContent ensures the browser treats your string as plain text and does not try to parse it as HTML, which prevents potential security issues.
An Alternative Method: insertAdjacentHTML (and its Pitfalls)
You can also inject the <style> tag as a raw HTML string. While this works, it is generally less recommended for this task.
const styleString = `
<style>
body {
background-color: lightblue;
}
</style>
`;
// Insert the entire HTML string at the end of the <head>
document.head.insertAdjacentHTML('beforeend', styleString);
The Pitfall: The insertAdjacentHTML method parses the string as HTML. If the string content ever comes from user input, this could create a Cross-Site Scripting (XSS) vulnerability. For simply adding CSS text, the .textContent approach is inherently safer and more direct.
The Advanced Method: Using the CSS Object Model (.insertRule())
For more complex applications where you need to add or remove individual CSS rules programmatically, you should use the CSSOM. This is the API that CSS-in-JS libraries use under the hood.
The logic:
- Create an empty
<style>element and append it to thehead. - Access its
.sheetproperty to get a reference to the stylesheet object. - Use the
.insertRule()method to add individual rules.
Solution:
// 1. Create and append an empty style element
const styleElement = document.createElement('style');
document.head.appendChild(styleElement);
// 2. Get the stylesheet object
const stylesheet = styleElement.sheet;
// 3. Add rules programmatically
stylesheet.insertRule('#box { border: 2px solid blue; }', 0);
stylesheet.insertRule('body { font-family: sans-serif; }', 1);
This method is more verbose for a static block of CSS but is far more powerful and performant for managing dynamic rules one by one.
Conclusion
For dynamically adding CSS to a webpage, JavaScript provides several effective solutions.
- The recommended best practice is to use
document.createElement('style')and set its.textContent. This method is safe, readable, and highly effective for injecting a block of CSS. - The
insertAdjacentHTML()method is a functional alternative but is less direct and carries potential security risks if not used carefully. - For advanced, programmatic control over individual CSS rules, use the CSSOM by accessing the element's
.sheetproperty and calling.insertRule().