Dynamically change CSS rules in JavaScript or jQuery - javascript

I'm looking for a way to change the CSS rules of my stylesheet imported in the document. So I have an external stylesheet and some class and div attributes inside. I want to change one of the rules with JavaScript or jQuery.
Here is an example :
.red{
color:red;
}
So the idea is to do something in JavaScript and the HTML knows that now the color is another color like this:
.red{
color:purple;
}
But I want to have this rule for every element that I add in the future by the way of append. So if I add a span with the CSS class .red, the text has to be purple and not red.
I hope I made it clear.

You can inject style declarations into the DOM.
$("head").append('<style>.red { color: purple }</style>');

You jQuery .css() method to do that.
$('.red').css('color', 'purple');
For multiple rules:
$('.red').css({
'color': 'purple',
'font-size': '20px'
});
When you add dynamic element in future to DOM by the way of append, just give those element some class or id and write CSS rules like above after appending them and they will applied for all dynamically created element.
Working sample
Note
Add dynamic rules is not a good solution in my point of view. Instead of the you can load some external CSS file.
But if you need something like dynamic rules add method then:
$('head').append(
$('<style/>', {
id: 'mystyle',
html: '.red {color: purple }'
})
);
And for future use:
$('#mystyle').append(' .someother { color: green; font-size: 13px } ');
Working sample

If you want to add a rule, instead of editing each element's style directly, you can use CSSStyleSheet.insertRule(). It takes two parameters: the rule as a string, and where to insert the rule.
Example from the above link:
// push a new rule onto the top of my stylesheet
myStyle.insertRule("#blanc { color: white }", 0);
In this case, myStyle is the .sheet member of a style element.
As far as I can tell, the style element must be inserted into the document before you can grab its sheet, and it can't be an external sheet. You can also grab a sheet from document.styleSheets, e.g.
var myStyle = document.styleSheets[1]; // Must not be a linked sheet.
myStyle.insertRule("#blanc { color: white }", 0);
Note: The page recommends modifying elements by changing their classes, instead of modifying the rules.

Related

Override .css stylesheet file (not inline)

Is it possible to somehow override the default (in this case liquid) CSS stylesheet, but without using inline styles?
Also I want that style to apply only to that specific page, and not any others.
Yes, I can use !important inside <style> tag on that specific page, but I would need to reset a lot of things. It just too much work, and looks very messy.
So is there any way I could reset ALL elements to default property values, and use my own style just on that one page?
Well you can't modify your .css files, but you can replace files dynamically using js.
function replaceFile(newFile, fileLink) {
var oldcss = document.getElementsByTagName("link").item(fileLink);
var newcss = document.createElement("link");
newcss.setAttribute("rel", "stylesheet");
newcss.setAttribute("type", "text/css");
newcss.setAttribute("href", newFile);
document.getElementsByTagName("head").item(0).replaceChild(newcss, oldcss);
}
Another solution, would be to add the desired styles using jQuery or js.
$('.demo').css({'background-color':'red','color':'white');
css stands for Cascading Style Sheets so once you've added a style you can only change or remove it by using another style. to answer your question specifically no you can not. or as mentioned in the comments just remove the stylesheet from that specific page.
You can select all elements inside a wrapper with * and override:
Example:
.mylink{
color: red;
}
.mylink:hover{
color: black;
}
.reset *{
color: orange;
}
.reset *:hover{
color: silver;
}
This is the link without reset:
Link
<div class="reset">
This is the link with reset:
Link
</div>

Add differing CSS rules to a set of generated elements

I want to loop and add several multicolored spans to a div container. To do this efficiently, I simply alter the css, instead of adding a new color class to the element:
var colorEn = ["RoyalBlue", "LawnGreen", "red", "orange", "yellow", "black", "white", "MediumOrchid"];
for ( i = 0; i < colorEn.length; i++ ) {
var $span = $('<span />').attr('class', 'coloratorSquare');
$span.css({background : colorEn[i]});
$("#colorator").append($span);
}
Generating, for example:
<span class="coloratorSquare active" style="background: rgb(65, 105, 225);"></span>
Then, when I select (click) a certain span, it will change color to Silver show it has been selected, and set all other sibling spans back to their original colors. Here's a snippet:
$(this).addClass("active").siblings().removeClass("active");
The problem is, if I alter the css of the span elements ($span.css(...)), it doesn't apply the CSS changes on add/remove class. But if I comment out changing the css of the span, the multiple colors aren't added, but the active class add/removal of selected/deselected span changes colors as expected:
// $span.css({background : colorEn[i]});
CSS:
.active {
background-color: Silver;
color: black;
}
I would simply not alter .css of a span at all, but don't think it makes sense to add classes to each span during generation, and have to add CSS class rules for each color to replicate that .css functionality.
My question: How can I add multiple different css rules (ex: multicolors) to randomly generated elements without a) having to generate all those rules manually in the CSS file, and b) altering the .css with jQuery such that it causes problems with adding/removing CSS class rules.
Sorry if this is unclear.
Thanks!
You could use !important on the silver color to have it override the locally set attributes of your elements, but that technique is frowned upon.
My recommendation is to consider the circumstances; if this is not throwaway code, then it usually makes better sense to set classes on the elements instead of directly manipulating their style attribute. If it's something you need for a mockup then by all means slap !important on it and move on.

Replacing string within page with jQuery/javascript

I'm trying to replace a string within a tag in my html page at specific position. I have to do it often and match exactly specific string. For example, if I have:
<style id="myStyle">
h1 {
background-color: red;
}
h2 {
background-color: red;
}
</style>
I have to replace h2 background-color but not h1. Do I have to rewrite every time text within style tag? Or there is some better solution that splitting, recombining the entire string and then replacing tag's content(could be very big).
JavaScript replace function is not good, it doesn't replace at specific position.
Using jQuery you can change the style of all the h1 elements currently in the DOM like so:
$('h1').css({
'background-color': 'red'
});
You cannot actually alter what is within the style tags. But you can alter the styles of elements on the page using javascript/jQuery. The above code illustrates this
You can do so with jQuery easily
$('h1').css("cssText",
"background-color: green; other-css-properties;" );
If you really want to be specific you could give an id or a class to whatever you want to change and do something like
$("#given-id").css(...) for ids and $(".given-class").css(...) for classes
Give the h2 an id of "h2" and then have whatever event you want that triggers the change execute the following line.
document.getElementsById("h2")[0].setAttribute("style","color: red; background-color: gray;");

Can I prevent a CSS style to be overwritten?

I'd like to apply a CSS to some linkbuttons on page load but one of them <a id="lb1">logoff</a> must keep its style, no hover nor other event must change its style.
The linkbuttons have no class and the css applied to all of them is done to tags, this way:
a
{
//style
}
a:hover
{
// style
}
Is it possible?
No, you can't.
You can use more specific selectors (or even inline CSS with the style attribute) so that they are less likely to be overridden accidentally.
You can use the (eugh) sledgehammer of !important so they will only be overridden by another !important rule.
There is no way to prevent them being overridden though.
Please please please please please avoid using !important whenever possible. You will run into SO many annoying problems and issues from using this. I consider it a very lazy hack.
What you want to do is append a class to the link that you don't want overwritten. Classes are given a higher priority than general selectors (such a, p, b). So if you append this class to the link, the CSS will override the default CSS you have set for a.
CSS:
a {
color: red;
}
a:hover {
color: blue;
}
.derp:hover { /*you can add everything you want to preserve here, essentially make it the same as the link css. you can also change it to #lbl:hover, although there's no good reason to be using an ID as a CSS selector*/
color: red;
}
HTML:
this will turn blue on hover
<a class="derp" href="#">this will stay red on hover</a>
Here's a fiddle to show you. The second link has a class appended that preserves the original style: http://jsfiddle.net/p6QWq/
Why not add a class to all the link buttons you want to change, and not add it to the one you don't want to change.
Then you can call:
$(".myClass").css("backgound-color", "blue");
This would change the background color for every element with a class of myClass to a blue background.
Or you could add a whole new class to the link buttons that have a class of myClass:
$(".myClass").addClass("myExtraClass");
This would then make the class attribute of your link button class="myclass myExtraClass"
Seeing your code posted makes it a little more clear on what you want to do. Try this:
a {
text-decoration: none;
color: orange;
}
a:hover {
text-decoration: underline;
color: blue;
}
This would apply a default style to all <a> elements. Now you could overwrite this default style by providing a specific style for the anchor with the id you gave above:
#lb1 {
color: black;
text-decoration: none;
}
#lb1:hover {
color: black;
text-decoration: none;
}
I mocked this up in a quick and dirty jsFiddle. See if this gives you the desired result. IDs take precedence over classes and default element styling. So if you have one that you want to keep the same, apply and ID and style the particular element accordingly. This would also help you by preventing you from having to apply a class to several elements. It's less coding to apply one ID than to apply twelve classes. (Just an exaggerated example. I don't know how many links you have.)
Hope this helps.
css is cascading by definition, so any style you apply to a tags will apply to this specific one, except if you overwrite it.
You'll have to either assign a class to all the other buttons or overwrite all the default properties for this specific button.
Also, do not forget the pseudo-classes :visited and :active.
You should use !important in your css like :
a {
/* style */
background: #FFF !important;
}
a:hover {
/* style */
background: #FFF !important;
}
You could always overwrite your css by simply creating another stylesheet and place it at the END of your stylesheet links in the head of your html.
<head>
<link rel="stylesheet" href="location/location/first_stylesheet.css">
<link rel="stylesheet" href="location/location/revised_stylesheet.css">
</head>
This is not the most productive method of overwriting your css however; one would be well advised to eliminate the necessity for this separate stylesheet by simply appending elements with a class attribute. The class attr will allow you to modify basic html elements, tags and overlay a final layer to "rule them all". Enjoy!

Changing CSS pseudo-element styles via JavaScript [duplicate]

This question already has answers here:
Selecting and manipulating CSS pseudo-elements such as ::before and ::after using javascript (or jQuery)
(26 answers)
How to update placeholder color using Javascript?
(5 answers)
Closed 2 years ago.
Is it possible to change a CSS pseudo-element style via JavaScript?
For example, I want to dynamically set the color of the scrollbar like so:
document.querySelector("#editor::-webkit-scrollbar-thumb:vertical").style.background = localStorage.getItem("Color");
and I also want to be able to tell the scrollbar to hide like so:
document.querySelector("#editor::-webkit-scrollbar").style.visibility = "hidden";
Both of these scripts, however, return:
Uncaught TypeError: Cannot read property 'style' of null
Is there some other way of going about this?
Cross-browser interoperability is not important, I just need it to work in webkit browsers.
If you're comfortable with some graceful degradation in older browsers you can use CSS Vars. Definitely the easiest of the methods I've seen here and elsewhere.
So in your CSS you can write:
#editor {
--scrollbar-background: #ccc;
}
#editor::-webkit-scrollbar-thumb:vertical {
/* Fallback */
background-color: #ccc;
/* Dynamic value */
background-color: var(--scrollbar-background);
}
Then in your JS you can manipulate that value on the #editor element:
document.getElementById("#editor").style.setProperty('--scrollbar-background', localStorage.getItem("Color"));
Lots of other examples of manipulating CSS vars with JS here: https://eager.io/blog/communicating-between-javascript-and-css-with-css-variables/
To edit an existing one which you don't have a direct reference to requires iterating all style sheets on the page and then iterating all rules in each and then string matching the selector.
Here's a reference to a method I posted for adding new CSS for pseudo-elements, the easy version where you're setting from js
Javascript set CSS :after styles
var addRule = (function (style) {
var sheet = document.head.appendChild(style).sheet;
return function (selector, css) {
var propText = typeof css === "string" ? css : Object.keys(css).map(function (p) {
return p + ":" + (p === "content" ? "'" + css[p] + "'" : css[p]);
}).join(";");
sheet.insertRule(selector + "{" + propText + "}", sheet.cssRules.length);
};
})(document.createElement("style"));
addRule("p:before", {
display: "block",
width: "100px",
height: "100px",
background: "red",
"border-radius": "50%",
content: "''"
});
sheet.insertRule returns the index of the new rule which you can use to get a reference to it for it which can be used later to edit it.
EDIT: There is technically a way of directly changing CSS pseudo-element styles via JavaScript, as this answer describes, but the method provided here is preferable.
The closest to changing the style of a pseudo-element in JavaScript is adding and removing classes, then using the pseudo-element with those classes. An example to hide the scrollbar:
CSS
.hidden-scrollbar::-webkit-scrollbar {
visibility: hidden;
}
JavaScript
document.getElementById("editor").classList.add('hidden-scrollbar');
To later remove the same class, you could use:
document.getElementById("editor").classList.remove('hidden-scrollbar');
I changed the background of the ::selection pseudo-element by using CSS custom properties doing the following:
/*CSS Part*/
:root {
--selection-background: #000000;
}
#editor::selection {
background: var(--selection-background);
}
//JavaScript Part
document.documentElement.style.setProperty("--selection-background", "#A4CDFF");
You can't apply styles to psuedo-elements in JavaScript.
You can, however, append a <style> tag to the head of your document (or have a placeholding <style id='mystyles'> and change its content), which adjusts the styles. (This would work better than loading in another stylesheet, because embedded <style> tags have higher precedence than <link>'d ones, making sure you don't get cascading problems.
Alternatively, you could use different class names and have them defined with different psuedo-element styles in the original stylesheet.
I posted a question similar to, but not completely like, this question.
I found a way to retrieve and change styles for pseudo elements and asked what people thought of the method.
My question is at Retrieving or changing css rules for pseudo elements
Basically, you can get a style via a statement such as:
document.styleSheets[0].cssRules[0].style.backgroundColor
And change one with:
document.styleSheets[0].cssRules[0].style.backgroundColor = newColor;
You, of course, have to change the stylesheet and cssRules index. Read my question and the comments it drew.
I've found this works for pseudo elements as well as "regular" element/styles.
An old question, but one I came across when try to dynamically change the colour of the content of an element's :before selector.
The simplest solution I can think of is to use CSS variables, a solution not applicable when the question was asked:
"#editor::-webkit-scrollbar-thumb:vertical {
background: --editorScrollbarClr
}
Change the value in JavaScript:
document.body.style.setProperty(
'--editorScrollbarClr',
localStorage.getItem("Color")
);
The same can be done for other properties.
Looks like querySelector won't work with pseudo-classes/pseudo-elements, at least not those. The only thing I can think of is to dynamically add a stylesheet (or change an existing one) to do what you need.
Lots of good examples here:
How do I load css rules dynamically in Webkit (Safari/Chrome)?

Categories

Resources