Can jQuery change css style definition? (not individual css of each element)

24,341

Solution 1

There is DOM access to stylesheets, but it's one of those things we tend to avoid because IE needs a load of compatibility cruft.

A better way would be typically be to trigger the change indirectly, using a simple class change on an ancestor:

td { padding: 0.2em 1.2em }
body.changed td { padding: 0.32em 2em }

Now just $('body').addClass('changed') and all the tds update.

If you really must frob the stylesheets:

var sheet= document.styleSheets[0];
var rules= 'cssRules' in sheet? sheet.cssRules : sheet.rules; // IE compatibility
rules[0].style.padding= '0.32em 2em';

This assumes that the td rule in question is the first rule in the first stylesheet. If not, you might have to go searching for it by iterating the rules looking for the right selectorText. Or just add a new rule to the end, overriding the old one:

if ('insertRule' in sheet)
    sheet.insertRule('td { padding: 0.32em 2em }', rules.length);
else // IE compatibility
    sheet.addRule('td', 'padding: 0.32em 2em', rules.length);

jQuery itself doesn't give you any special tools to access stylesheets, but it's possible there are plugins that might.

Solution 2

$('head').append('<style id="customCSS">td { padding: 0.32em 2em }</style>');

I added an id attribute so you can target and remove it when you no longer want that change to apply.

$('#customCSS').remove();

Solution 3

I ran into a problem where I didn't know the width I wanted a class until it was loaded and did this.

<script>
$(function() {
    calcWidth = CalculateWidth();

    $('body').prepend('<style> .dynamicWidth { width: ' + calcWidth + 'px } </style>');
}
</script>

Note: it may matter where you put the script (prepend, append) depending on how you want the rules to 'cascade'.

Solution 4

Nope, it just doesn't work this way...not sure any better way to explain it than that :)

jQuery was designed to work on elements...if you're doing this for testing, Firebug of the Chrome console are options though.

Something you could do, is have a server-side generated stylesheet, for example how ThemeRoller does it, and jQuery (or vanilla JS) dynamically adds that <link> into your header, something like:

<link rel="stylesheet" href="myCSS.php?tdPad=.32|2" type="text/css" /> 

If it was the last link, it'd override the previously defined style...in fact this is exactly how ThemeRoller works.

Solution 5

Now this is possible by using CSS Variables

CSS:

:root{
--my-padding: 0.2em 1.2em;
}

td{
padding:var(--my-padding)
}

jQuery:

let paddingX = 0.32
let paddingY = 2
$(':root').css('--my-padding',`${paddingX }em ${paddingY }em`)
Share:
24,341
nonopolarity
Author by

nonopolarity

I started with Apple Basic and 6502 machine code and Assembly, then went onto Fortran, Pascal, C, Lisp (Scheme), microcode, Perl, Java, JavaScript, Python, Ruby, PHP, and Objective-C. Originally, I was going to go with an Atari... but it was a big expense for my family... and after months of me nagging, my dad agreed to buy an Apple ][. At that time, the Pineapple was also available. The few months in childhood seem to last forever. A few months nowadays seem to pass like days. Those days, a computer had 16kb or 48kb of RAM. Today, the computer has 16GB. So it is in fact a million times. If you know what D5 AA 96 means, we belong to the same era.

Updated on April 05, 2021

Comments

  • nonopolarity
    nonopolarity about 3 years

    I haven't seen any docs saying jQuery can change any CSS definition such as changing

    td { padding: 0.2em 1.2em }
    

    to

    td { padding: 0.32em 2em }
    

    but either have to change a whole style sheet, or change class of each element, or change css of each element.

    Is changing the style definition possible?

  • Tomalak
    Tomalak over 11 years
    It's worth noting that IE (incl. IE10) does not preserve the original selectorText. Something written as .foo.bar in the CSS stylesheet might end up as .bar.foo in the DOM rule object. This makes "hunting for the right selector text" extraordinarily brittle.
  • Amit Patil
    Amit Patil over 11 years
    @Tomalak: Right - and indeed, there is no requirement in the spec for selectorText to contain exactly the same string as the original selector. It's the same as innerHTML - the parser converts the source into a bunch of objects, and then reading the property results in a serialisation that is the textual representation reflecting the information the browser is using, but a serialisation that is not in any way guaranteed to be the same as the source. Consequently searching for exact selectorText is inherently unreliable.
  • John Fisher
    John Fisher about 9 years
    The best part of this answer is: "A better way... class change on an ancestor"
  • j08691
    j08691 over 4 years
    This adds and removes, but doesn't change
  • Kevin Walker
    Kevin Walker about 2 years
    Very helpful! Nice to have a modern answer here.