Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to dynamically change a class css styling?

Goal

In my program I want to do both things with jquery/javascript:

  1. Change styling of css classes dynamically
  2. Add/remove classes to elements

Problem

To do the first thing I use $(".className").css() method, but it changes style only for those elements that already have className class, i.e. if I later add className to an element its style won't be new. How can I solve this?

Example

See it also at jsfiddle.

$("p").addClass("redclass");
$(".redclass").css("color", "darkRed");
$("span").addClass("redclass");
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<p>I want to be red! And I am.</p>
<span>I want to be red too but I'm not :'(</span>

Result:

enter image description here

like image 779
Philip Voronov Avatar asked Oct 01 '16 12:10

Philip Voronov


People also ask

How do I change a dynamic class in CSS?

How to apply/change CSS dynamically? The following is the Javascript function that accepts a parameter and then gets the id of the element and compares the name of the class using className property and depending on the value it assigns a new value to the element.

How do I change CSS properties of a class?

Set Style Using element. One can use element. className to change various style parameters of an HTML element by clubbing those as a class and assigning the class name to the selected element with element. className .

Can we make CSS dynamic?

It is worth noting that while pre/postprocessor variables are only used at compilation-time, CSS variables can be used and updated dynamically. What does this mean? It means that they are preserved in the actual CSS stylesheet. So the notion that they are variables will remain even after the stylesheets are compiled.


Video Answer


3 Answers

A more shorten format:

$("<style/>", {text: ".redclass {color: darkRed;}"}).appendTo('head');

The snippet:

$("<style/>", {text: ".redclass {color: darkRed;}"}).appendTo('head');


$("p").addClass("redclass");

$("span").addClass("redclass");
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>


<p>I want to be red! And I am.</p>
<span>I want to be red too but I'm not :'(</span>
like image 166
gaetanoM Avatar answered Oct 26 '22 18:10

gaetanoM


While other (working) answers have been supplied, they don't actually answer your question - namely, they don't change the specified css class, but instead override it by adding another rule later in the document.

They achieve this, basically:

Before

.someClass
{
  color: red;
}

After

.someClass
{
  color: red;
}

.someClass
{
  color: white;
}

When in many cases, a better option would see the color attribute of the existing rule altered.

Well, as it turns out - the browser maintains a collection of style-sheets, style-sheet rules and attributes of said rules. We may prefer instead, to find the existing rule and alter it. (We would certainly prefer a method that performed error checking over the one I present!)

The first console msg comes from the 1 instance of a #coords rule. The next three come from the 3 instances of the .that rule

function byId(id){return document.getElementById(id)}

window.addEventListener('load', onDocLoaded, false);

function onDocLoaded(evt)
{
	byId('goBtn').addEventListener('click', onGoBtnClicked, false);
}

function onGoBtnClicked(evt)
{
	alterExistingCSSRuleAttrib('#coords', 'background-color', 'blue');
	alterExistingCSSRuleAttrib('.that', 'color', 'red');
}

// useful for HtmlCollection, NodeList, String types (array-like types)
function forEach(array, callback, scope){for (var i=0,n=array.length; i<n; i++)callback.call(scope, array[i], i, array);} // passes back stuff we need

function alterExistingCSSRuleAttrib(selectorText, tgtAttribName, newValue)
{
	var styleSheets = document.styleSheets;
	forEach(styleSheets, styleSheetFunc);

	function styleSheetFunc(CSSStyleSheet)
	{
		forEach(CSSStyleSheet.cssRules, cssRuleFunc);
	}

	function cssRuleFunc(rule)
	{
		if (selectorText.indexOf(rule.selectorText) != -1)
		forEach(rule.style, cssRuleAttributeFunc);

		function cssRuleAttributeFunc(attribName)
		{
			if (attribName == tgtAttribName)
            {
				rule.style[attribName] = newValue;
                console.log('attribute replaced');
            }
		}
	}
}
#coords
{
    font-size: 0.75em;
	width: 10em;
	background-color: red;
}
.that
{
	color: blue;
}
<style>.that{color: green;font-size: 3em;font-weight: bold;}</style>

<button id='goBtn'>Change css rules</button>
	<div id='coords' class='that'>Test div</div>

<style>.that{color: blue;font-size: 2em;font-weight: bold;}</style>
like image 33
enhzflep Avatar answered Oct 26 '22 18:10

enhzflep


@synthet1c has described the problem. My solution is:

$("head").append('<style></style>');
var element = $("head").children(':last');
element.html('.redclass{color: darkred;}');
like image 35
Alec von Barnekow Avatar answered Oct 26 '22 16:10

Alec von Barnekow