62

I have a somewhat unusual issue. I've done something like this many times:

$('#selector').css('color','#00f');

My problem is that I create a <div id="selector">, and I call the command above and it works fine.

Now, on another event, later, I remove that element from the DOM and add it again at a later time with the same id. This element now doesn't have color:#00f.

Is there a way that I can add a rule in CSS, such that it will affect items that are created in the future with that same id/class? I like jQuery, but anything with plain JavaScript would be fine as well.

It has to be dynamic, and I don't know the classes to put in a CSS file. Also, I plan on changing a single attribute a few different times through the course of the application. For example, setting the color to black, to blue, to red, and back to black.



I went with the answer from @lucassp, and this is what I ended up with:

function toggleIcon(elem, classname)
{
    if($(elem).attr('src')=='img/checkbox_checked.gif')
    {
        $(elem).attr('src', 'img/checkbox_unchecked.gif')
        //$('.'+classname).hide();//this was the old line that I removed
        $('html > head').append($('<style>.'+classname+' { display:none; }</style>'));
    }
    else
    {
        $(elem).attr('src', 'img/checkbox_checked.gif')
        //$('.'+classname).show();//this was the old line that I removed
        $('html > head').append($('<style>.'+classname+' { display:block; }</style>'));
    }
}

I also want to say that @Nelson is probably the most "correct", though it would require more work to go into application code that always works fine, and that's not effort I want to spend at the moment.

If I had to rewrite this (or write something similar) in the future, I would look into detach().

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Landon
  • 4,088
  • 3
  • 28
  • 42
  • `.css()` sets style attribute of the `$('#selector')`. It does not create a css rule. – Zefiryn Oct 25 '12 at 19:40
  • 1
    I know that, that's exactly what I'm asking, I want to create a rule, not just adjust an attribute – Landon Oct 25 '12 at 19:59
  • I was just pointing it out as you seemed to be surprised with the result of `.css()` method. The responses are giving you some direction how to handle this. – Zefiryn Oct 25 '12 at 20:01
  • No, I'm not surprised by it. I'm quite familiar with `css()`, and I know it just edits the matched DOM elements and doesn't make a permanent rule – Landon Oct 25 '12 at 20:04

12 Answers12

94

This should work:

var style = $('<style>.class { background-color: blue; }</style>');
$('html > head').append(style);
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
lucassp
  • 4,133
  • 3
  • 27
  • 36
12

When you plan to remove elements from the DOM to re-insert them later, then use .detach() instead of .remove().

Using .detach() will preserve your CSS when re-inserting later. From the documentation:

The .detach() method is the same as .remove(), except that .detach() keeps all jQuery data associated with the removed elements. This method is useful when removed elements are to be reinserted into the DOM at a later time.

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Nelson
  • 49,283
  • 8
  • 68
  • 81
  • 2
    You first detach and save the element in a variable: `var p = $("#myelement").detach();` then later you can insert your element again with `$('#somediv').append(p);` or the equivalent `p.appendTo('#somediv');` – Nelson Oct 25 '12 at 22:56
8

In case this style section suppose to be changed several times, you can set in the html file a style tag with id:

<style id="myStyleTag">
</style>

then you can refer it with js, edit or remove content like:

var style = $('#myStyleTag');
styl.html('.class { background-color: blue; }');

in this way the style section will not become bigger if you change it several times because you don't just append it to the head but edit it as needed.

TylerH
  • 20,799
  • 66
  • 75
  • 101
amichai
  • 718
  • 9
  • 19
  • @kokociel please do not make changes to other authors' code. If you think the code is wrong or has a typo in it, leave a comment! – TylerH Sep 14 '18 at 15:27
  • 1
    Hmm isn't this asserting that we'd be undermining the author's intent? That maybe an author wanted to write code with subtle mistakes? I wonder what purpose the 3rd-party editing functionality is supposed to offer, if not for the correction of minor mistakes. – kokociel Sep 15 '18 at 16:31
7

Here is some JavaScript code I wrote before to let me add, remove and edit CSS:

function CSS(sheet) {

    if (sheet.constructor.name === 'CSSStyleSheet' )
        this.sheet = sheet;
    else if (sheet.constructor.name === 'HTMLStyleElement')
        this.sheet = sheet.sheet;
    else
        throw new TypeError(sheet + ' is not a StyleSheet');
}

CSS.prototype = {
    constructor: CSS,
    add: function( cssText ) {
        return this.sheet.insertRule(cssText, this.sheet.cssRules.length);
    },
    del: function(index) {
        return this.sheet.deleteRule(index);
    },
    edit: function( index, cssText) {
        var i;
        if( index < 0 )
            index = 0;
        if( index >= this.sheet.cssRules.length )
            return this.add(cssText);
        i = this.sheet.insertRule(cssText, index);
        if (i === index)
            this.sheet.deleteRule(i + 1);
        return i;
    }
};

And then if a new stylesheet is required, construct as

var myCss = new CSS(document.head.appendChild( document.createElement('style')));
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Paul S.
  • 64,864
  • 9
  • 122
  • 138
1

The best option would be to add a class:

.selected {
    color : #00f ;
}

$('#elemId').addClass('selected')
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Sushanth --
  • 55,259
  • 9
  • 66
  • 105
1

You can use livequery plugin.

$('#selector').livequery(function() { $(this).css('color', '#00f'); });
Almir Sarajčić
  • 1,520
  • 3
  • 16
  • 19
1

This is an old question with a chosen answer, but adding dynamic CSS to accomplish the goal is not necessary and is likely sending people in the wrong direction.

If you want to dynamically set styles on an element using jQuery, it is best to use .addClass() and .removeClass() with classes that affect the required style.

Given the function in the question:

function toggleIcon(elem, classname)
    {
      if($(elem).attr('src')=='img/checkbox_checked.gif')
    {
        $(elem).attr('src', 'img/checkbox_unchecked.gif');
        $("." + classname).addClass("hidden");
    }
    else
    {
        $(elem).attr('src', 'img/checkbox_checked.gif');
        $("." + classname).removeClass("hidden");
    }
}

And then just add this to your CSS:

.hidden {display: none;}

This would also work to change color, as also mentioned in the question:

.checkbox-red {color: red;}
.checkbox-blue {color: blue;}
Khan
  • 2,912
  • 3
  • 21
  • 21
1

There is nothing wrong with the accepted answer. But if you wanted to do this in just one line, you could do something like this:

$('<style>').append('.'+classname+'{display:none}').appendTo('head')
PHP Guru
  • 1,301
  • 11
  • 20
0

Create a CSS rule in your CSS file

.yourclass{
    color: #00f;
}

Add yourclass whenever you're creating the element:

$("#selector").addClass("yourclass");
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Anoop
  • 23,044
  • 10
  • 62
  • 76
0

Just use a class, for example:

CSS:

.setcolor { color: #fff; }

JavaScript:

$('#selector').addClass('setcolor');

Then remove it when needed:

$('#selector').removeClass('setcolor');
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
gregwhitworth
  • 2,136
  • 4
  • 22
  • 33
0

If you already have a style element in your document, you can just add another rule to it with vanilla js:

document.styleSheets[0].addRule('#selector', 'color: #00f');
Protector one
  • 6,926
  • 5
  • 62
  • 86
-1

Try this

var style = $('<style>.class { background-color: blue !important; }</style>');
$('html > head').append(style);
codemirror
  • 3,164
  • 29
  • 42