228

How do you add CSS rules (eg strong { color: red }) by use of Javascript?

nickf
  • 537,072
  • 198
  • 649
  • 721
  • same question ( answer is crossbrowser jQuery ) http://stackoverflow.com/a/266110/341744 – ninMonkey Jul 06 '12 at 06:04
  • 25
    @monkey : That's a pretty poor solution, and doesn't actually do what was asked here. eg: what happens if a new `` element is added to the document. – nickf Jul 07 '12 at 18:22

17 Answers17

340

The simple-and-direct approach is to create and add a new style node to the document.

// Your CSS as text
var styles = `
    .qwebirc-qui .ircwindow div { 
        font-family: Georgia,Cambria,"Times New Roman",Times,serif;
        margin: 26px auto 0 auto;
        max-width: 650px;
    }
    .qwebirc-qui .lines {
        font-size: 18px;
        line-height: 1.58;
        letter-spacing: -.004em;
    }
    
    .qwebirc-qui .nicklist a {
        margin: 6px;
    }
`

var styleSheet = document.createElement("style")
styleSheet.innerText = styles
document.head.appendChild(styleSheet)
Madacol
  • 3,611
  • 34
  • 33
Ben Blank
  • 54,908
  • 28
  • 127
  • 156
  • 18
    Shouldn't it be appended to the document's head rather than body? – bobince Apr 01 '09 at 23:51
  • 3
    @bobince — According to the HTML specs, absolutely, but all browsers recognize them anywhere. `document.body` is also shorter to type and faster to execute than `document.getElementsByTagName("head")[0]` and avoids the cross-browser issues of insertRule/addRule. – Ben Blank Apr 02 '09 at 17:05
  • 1
    I get an "Unknown runtime error" in IE7/8, when I try to execute that code subsequently (after the page finished loading). – Šime Vidas May 22 '12 at 16:30
  • 7
    Solution should be followed by a long "duhhhh". Can't believe I didn't think of it. – George Mauer Dec 21 '12 at 16:34
  • 11
    In all recent browsers you can just use `document.head.appendChild`. – Gajus Apr 07 '14 at 13:06
  • 3
    This solution is far better! Imagine you have more than one stylesheets: With @bobince solution your newly added CSS might be overwritten by the second/third/etc. stylesheet on the page. Using `document.body.appendChild(css);` you make sure the new CSS always is the last rule. – AvL Aug 02 '16 at 14:33
  • 3
    This gives me `
    ` elements in the style tag after every newline, and the rules don't work.
    – Maximillian Laumeister Jan 28 '20 at 19:03
  • @MaximillianLaumeister Use `innerHTML` instead of `innerText`, I'll propose and edit to the answer as well. – Isti115 Feb 25 '21 at 00:08
  • None of the answers provided works dynamically. There should be a way to refresh the CSS without reloading the page. – Cybernetic Aug 31 '21 at 05:23
156

You can also do this using DOM Level 2 CSS interfaces (MDN):

var sheet = window.document.styleSheets[0];
sheet.insertRule('strong { color: red; }', sheet.cssRules.length);

...on all but (naturally) IE8 and prior, which uses its own marginally-different wording:

sheet.addRule('strong', 'color: red;', -1);

There is a theoretical advantage in this compared to the createElement-set-innerHTML method, in that you don't have to worry about putting special HTML characters in the innerHTML, but in practice style elements are CDATA in legacy HTML, and ‘<’ and ‘&’ are rarely used in stylesheets anyway.

You do need a stylesheet in place before you can started appending to it like this. That can be any existing active stylesheet: external, embedded or empty, it doesn't matter. If there isn't one, the only standard way to create it at the moment is with createElement.

Jonas Äppelgran
  • 2,617
  • 26
  • 30
bobince
  • 528,062
  • 107
  • 651
  • 834
31

Shortest One Liner

// One liner function:
const addCSS = css => document.head.appendChild(document.createElement("style")).innerHTML=css;

// Usage: 
addCSS("body{ background:red; }")
chickens
  • 19,976
  • 6
  • 58
  • 55
28

The solution by Ben Blank wouldn't work in IE8 for me.

However this did work in IE8

function addCss(cssCode) {
var styleElement = document.createElement("style");
  styleElement.type = "text/css";
  if (styleElement.styleSheet) {
    styleElement.styleSheet.cssText = cssCode;
  } else {
    styleElement.appendChild(document.createTextNode(cssCode));
  }
  document.getElementsByTagName("head")[0].appendChild(styleElement);
}
Chris Herring
  • 3,675
  • 3
  • 33
  • 50
  • 2
    You should append the element to the `head` _before_ setting `.cssText`, or IE6-8 will **crash** if the `cssCode` contains an @-directive, like `@import` or `@font-face`, see the Update to http://www.phpied.com/dynamic-script-and-style-elements-in-ie/ and http://stackoverflow.com/a/7952904 – Han Seoul-Oh May 14 '14 at 02:50
27

Here's a slightly updated version of Chris Herring's solution, taking into account that you can use innerHTML as well instead of a creating a new text node:

function insertCss( code ) {
    var style = document.createElement('style');
    style.type = 'text/css';

    if (style.styleSheet) {
        // IE
        style.styleSheet.cssText = code;
    } else {
        // Other browsers
        style.innerHTML = code;
    }

    document.getElementsByTagName("head")[0].appendChild( style );
}
Community
  • 1
  • 1
Husky
  • 5,757
  • 2
  • 46
  • 41
  • 3
    You should append the element to the `head` _before_ setting `.cssText`, or IE6-8 will **crash** if the `code` contains an @-directive, like `@import` or `@font-face`, see the Update to http://www.phpied.com/dynamic-script-and-style-elements-in-ie/ and http://stackoverflow.com/a/7952904 – Han Seoul-Oh May 14 '14 at 02:49
5

You can add classes or style attributes on an element by element basis.

For example:

<a name="myelement" onclick="this.style.color='#FF0';">text</a>

Where you could do this.style.background, this.style.font-size, etc. You can also apply a style using this same method ala

this.className='classname';

If you want to do this in a javascript function, you can use getElementByID rather than 'this'.

mingala
  • 284
  • 3
  • 7
  • 5
    Inline JavaScript using event handlers is a very bad idea. You should be separating your content from your functionality and binding event handlers in JavaScript - preferably in an external file. – Colonel Sponsz Nov 21 '12 at 15:30
4

This easy example of add <style> in head of html

var sheet = document.createElement('style');
sheet.innerHTML = "table th{padding-bottom: 0 !important;padding-top: 0 !important;}\n"
+ "table ul {    margin-top: 0 !important;    margin-bottom: 0 !important;}\n"
+ "table td{padding-bottom: 0 !important;padding-top: 0 !important;}\n"
+ ".messages.error{display:none !important;}\n"
+ ".messages.status{display:none !important;} ";

document.body.appendChild(sheet); // append in body
document.head.appendChild(sheet); // append in head

Source Dynamic style - manipulating CSS with JavaScript

DarckBlezzer
  • 4,578
  • 1
  • 41
  • 51
4

In modern browsers, you can use document.adoptedStyleSheets to add CSS.

const sheet = new CSSStyleSheet();
sheet.replace("strong { color: red; }");
document.adoptedStyleSheets = [...document.adoptedStyleSheets, sheet];

One advantage of this approach is that you do not have to wait for the <head> element to even become available, which may be a concern in browser extension code that runs very early.

a cat
  • 654
  • 1
  • 10
  • 17
3

This is my solution to add a css rule at the end of the last style sheet list:

var css = new function()
{
    function addStyleSheet()
    {
        let head = document.head;
        let style = document.createElement("style");

        head.appendChild(style);
    }

    this.insert = function(rule)
    {
        if(document.styleSheets.length == 0) { addStyleSheet(); }

        let sheet = document.styleSheets[document.styleSheets.length - 1];
        let rules = sheet.rules;

        sheet.insertRule(rule, rules.length);
    }
}

css.insert("body { background-color: red }");
Martin Wantke
  • 4,287
  • 33
  • 21
3

YUI just recently added a utility specifically for this. See stylesheet.js here.

itsmysterybox
  • 2,748
  • 3
  • 21
  • 26
Russell Leggett
  • 8,795
  • 3
  • 31
  • 45
  • I'm currently using YUI for my work and was trying to figure out how to edit external style sheets of existing css rules. Didn't know about this utility, it seems perfect! Thanks Russell. – Jaime Dec 14 '09 at 20:59
2

if you know at least one <style> tag exist in page , use this function :

CSS=function(i){document.getElementsByTagName('style')[0].innerHTML+=i};

usage :

CSS("div{background:#00F}");
1

Another option is to use JQuery to store the element's in-line style property, append to it, and to then update the element's style property with the new values. As follows:

function appendCSSToElement(element, CssProperties)
        {
            var existingCSS = $(element).attr("style");

             if(existingCSS == undefined) existingCSS = "";

            $.each(CssProperties, function(key,value)
            {
                existingCSS += " " + key + ": " + value + ";";
            });

            $(element).attr("style", existingCSS);

            return $(element);
        }

And then execute it with the new CSS attributes as an object.

appendCSSToElement("#ElementID", { "color": "white", "background-color": "green", "font-weight": "bold" });

This may not necessarily be the most efficient method (I'm open to suggestions on how to improve this. :) ), but it definitely works.

XtraSimplicity
  • 5,704
  • 1
  • 28
  • 28
1

Here's a sample template to help you get started

Requires 0 libraries and uses only javascript to inject both HTML and CSS.

The function was borrowed from the user @Husky above

Useful if you want to run a tampermonkey script and wanted to add a toggle overlay on a website (e.g. a note app for instance)

// INJECTING THE HTML
document.querySelector('body').innerHTML += '<div id="injection">Hello World</div>';

// CSS INJECTION FUNCTION
//https://stackoverflow.com/questions/707565/how-do-you-add-css-with-javascript
function insertCss( code ) {
    var style = document.createElement('style');
    style.type = 'text/css';
    if (style.styleSheet) {
        // IE
        style.styleSheet.cssText = code;
    } else {
        // Other browsers
        style.innerHTML = code;
    }
    document.getElementsByTagName("head")[0].appendChild( style );
}

// INJECT THE CSS INTO FUNCTION
// Write the css as you normally would... but treat it as strings and concatenate for multilines
insertCss(
  "#injection {color :red; font-size: 30px;}" +
  "body {background-color: lightblue;}"
)
Vincent Tang
  • 3,758
  • 6
  • 45
  • 63
0

Here's my general-purpose function which parametrizes the CSS selector and rules, and optionally takes in a css filename (case-sensitive) if you wish to add to a particular sheet instead (otherwise, if you don't provide a CSS filename, it will create a new style element and append it to the existing head. It will make at most one new style element and re-use it on future function calls). Works with FF, Chrome, and IE9+ (maybe earlier too, untested).

function addCssRules(selector, rules, /*Optional*/ sheetName) {
    // We want the last sheet so that rules are not overridden.
    var styleSheet = document.styleSheets[document.styleSheets.length - 1];
    if (sheetName) {
        for (var i in document.styleSheets) {
            if (document.styleSheets[i].href && document.styleSheets[i].href.indexOf(sheetName) > -1) {
                styleSheet = document.styleSheets[i];
                break;
            }
        }
    }
    if (typeof styleSheet === 'undefined' || styleSheet === null) {
        var styleElement = document.createElement("style");
        styleElement.type = "text/css";
        document.head.appendChild(styleElement);
        styleSheet = styleElement.sheet;
    }

    if (styleSheet) {
        if (styleSheet.insertRule)
            styleSheet.insertRule(selector + ' {' + rules + '}', styleSheet.cssRules.length);
        else if (styleSheet.addRule)
            styleSheet.addRule(selector, rules);
    }
}
Jon
  • 952
  • 1
  • 11
  • 17
-1

A recent alternative approach to generate CSS with Javascript would be panda-css (GitHub project: chakra-ui/panda), initiated in July 2022.
See "Panda CSS – CSS-in-JS without Runtime Overhead" by Ivica Batinić

Assuming the right set up (See "Get started with Panda"), the quickest way to use Panda from scratch is by using the Panda CLI tool.

Install Panda

npm install -D @pandacss/dev
npx panda init

Configure the content

Add the paths to all of your JavaScript or TypeScript code where you intend to use panda.

import { defineConfig } from '@pandacss/dev'

export default defineConfig({
  preflight: true,
  include: ['./src/**/*.{ts,tsx,js,jsx}', './pages/**/*.{ts,tsx,js,jsx}'],
  exclude: [],
  outdir: 'styled-system'
})

Import the generated CSS

For each Panda run, it emits the generated CSS at the styled-system/styles.css file path. Import this file at the root component of your project.

import './styled-system/styles.css'

export function App() {
  return <div>Page</div>
}

Start the Panda build process

Run the CLI tool to scan your JavaScript and TypeScript files for style properties and call expressions.

# Run it once
npx panda

# Run it in watch mode
npx panda --watch

Start using Panda

Use the generated style utilities in your code and panda will extract them to the generated CSS file.

import { css } from './styled-system/css'

export function App() {
  return <div className={css({ bg: 'red.400' })} />
}
VonC
  • 1,262,500
  • 529
  • 4,410
  • 5,250
-2

I always forget how to add a class to an HTML element and this SO comes up early in Google, but no one has added the modern way of doing this so here goes.

To add a CSS style you can select the element and call .classList.add(<className>)

for example: document.querySelector("#main").classList.add("bg-primary");

You may also need to remove other class(es) which clash with the one you add. To do so: document.querySelector("#main").classList.remove("bg-secondary");

That's it. Run the sample and you'll see the setInterval() method add & remove the styles every 3 seconds.

let useSecondary = false;

setInterval(changeBgColor, 3000);

function changeBgColor(){
  if (useSecondary){
    document.querySelector("#main").classList.remove("bg-primary");
    document.querySelector("#main").classList.add("bg-secondary");
  }
  else{
    document.querySelector("#main").classList.remove("bg-secondary");
    document.querySelector("#main").classList.add("bg-primary");
  }
  useSecondary = !useSecondary;
}
* {
    transition: all 0.5s ease-in-out;
}

.bg-primary {
   background-color: green;
}

.bg-secondary{
   background-color: yellow;
}
<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width">
  <title>JS Bin</title>
</head>
<body>
<div >
    <div id="main" >
        Example text has background color changed every 3 seconds by adding / removing CSS styles.
    </div>
</div>
</body>
</html>
raddevus
  • 8,142
  • 7
  • 66
  • 87
  • I think perhaps you have misinterpreted the original question-- the user isn't asking how to apply existing style rules to elements, they are asking how to dynamically insert _new_ style rules into the document. – Alexander Nied May 13 '22 at 14:58
  • 1
    Google brings me to this question every time I search for adding styles to an element. Plus the original question is very poor so this is how I (and Google) interpret the question. Did you vote the original question down too & suggest OP update it to be more clear? That would probably be the most helpful. But for now, lot's of people searching for adding style to element will find this. – raddevus May 14 '22 at 15:51
-3

use .css in Jquery like $('strong').css('background','red');

$('strong').css('background','red');
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<strong> Example
</strong> 
Zain Ali
  • 65
  • 13