What is currently the best and easiest way to change CSS style using javascript?
I have several elements on the page with class="colorManipul" and in css .colorManipul{filter: grayscale(33%);}
I want to change the value directly in CSS so that it is reflected on all required elements with this class
Thanks for the advice, link, example, ... just anything
You can change the value of a CSS property with JS. To easily target a property you should target a CSS-Variable:
window.addEventListener('DOMContentLoaded', function() {
document.documentElement.style.setProperty('--body-bg', 'blue');
})
:root {
--body-bg: red;
}
body {
background: var(--body-bg);
}
However, this is harder to debug and a cleaner solution is to simply add a class to all elements with a certain class.
document.querySelectorAll('.colorManipul').forEach(el =>
el.classList.add('class-name')
);
If you want to change percentage of grayscale value, you can use css variable and change its value from JS For example:
CSS:
:root {
--grayscale: 33%;
}
.colorManipul {
filter: grayscale(var(--grayscale));
}
JS:
const grayscaleValue = 50;
root.style.setProperty('--grayscale', `${grayscaleValue}%`);
Related
I am implementing a dark mode on my site, and trying to do it in the cleanest way possible (no boiler plate code).
So I want to make .darkmode class in CSS, define styles with it, and when the user enables darkmode, javascript simply adds the darkmode class to the <body>.
How could I do something like this with CSS?
.darkmode {
.content{
background-color: black;
}
input{
background-color: black;
}
}
So my questions is, how can I make CSS change different elements on the page when adding this class to the <body>?
The code that you posted would be valid SCSS/LESS. But in plain css you can simply do that by using
.darkmode .content { /* CSS */ }
.darkmode input { /* CSS */ }
So yes, you always have to specify the .darkmode in front of every selector.
Let's suppose you have a selector, like
.mydiv .myanchor
You can override/add attributes using
body.darkmode .mydiv .myanchor
is much more specific and therefore the rules will override the default rules.
To achieve that in normal CSS you would have to use the CSS child selector;
body.darkmode .content {
/* Put styles here */
}
body.darkmode input {
/* Put styles here */
}
Basically the logic there says: "get the body element with the class darkmode and find it's child .content/input"
With CSS selectors, having two element selectors seporated by a space finds all of the second elements inside the first elements; div p would find all of the <p> tags inside all <div> tags.
Here is an example:
https://jsfiddle.net/6kg43qfr/
Code:
Jquery:
$('#foo').css('background-color', '#f8f7f7');
Html:
<div id="foo">
test
</div>
CSS:
#foo:hover{
background-color: red;
}
Question: Why doesn't the hover work?
That is because how you set the color in your javascript code.
Inline styles has more priority then styles applied to classes or id's
There are actually many rules, of how to properly override styles. Please take a quick look at this http://www.hongkiat.com/blog/css-priority-level/
I strongly suggest you to read more about css before proceeding with the project, in order to keep code clean and maintainable.
in order to fullfill your needs, take a look at this fiddle:
https://jsfiddle.net/6kg43qfr/2/
$('#foo').addClass("green-background")
Because the $('#foo').css() function puts the style in a style attribute on the element, which therefore overrides the stylesheet.
The best solution is:
#foo:hover{
background-color: red;
}
#foo {
background-color: #f8f7f7;
}
Or
You also can use this:
$('#foo').css('background-color', '#f8f7f7').hover(
function(){
$(this).css('background-color','red');
},
function(){
$(this).css('background-color','#f8f7f7');
});
I have one question...
If you want conditional styling: you must use ng-class or ng-style construction.
But...
For example: I'm an admin, and I want to change color of my application with custom color from colorpicker. How can I change some code in css?
For example I have this line in style.css:
body{
background: #ffffff;
}
(also all tags like a, h1 etc implement some color)
and in controller I change this #ffffff to #000000.
What is the best way to change this color in css, without using ng-class or ng-style on each tag in each controller?
The best way is generate a file like color.css with all css rules with color, background-color, border-color etc. overridden. But angularjs will not be enough.
color-default.css
body {
background: #fff;
}
color.css
body {
background: #f00;
}
Full JS way
Add class on every element you want to override.
Create class for every properties like so:
.skin-color { color: {{color}}; }
.skin-background-color { background-color: {{color}}; }
.skin-border-color { border-color: {{color}}; }
etc..
Apply class on your html where you want:
<h1 class="skin-color">My title</h1>
<p>Hello I'm online!</p>
<p class="skin-background-color">No difference!</p>
<p>I'm link</p>
You can save the color variable in localStorage for example.
Démo: http://codepen.io/anon/pen/jPrabY
You could write the CSS rule in JavaScript and add it to a stylesheet dynamically. A couple of good articles on how to do that are here and here.
var myColor = '#FF00FF';
var stylesheet = /* get stylesheet element */;
stylesheet.insertRule('.dynamic-color { background-color:"' + myColor +'";}',0);
Of course, in a pure Angular way, you would create a directive that wraps the DOM/stylesheet interaction.
The easiest way I can think about is, for example, clicking on myBox changes its background-color.
html:
<div class="myBox" ng-click="changeBackgroundColor()"></div>
js:
$scope.changeBackgroundColor = function(){
angular.element('.myBox').css('background-color', '#000');
}
css:
.myBox{background-color: #fff;}
Hope I've been helpfull.
Another alternative is SASS or LESS and deal with colors using variable...
My html,
<div id="parent">
<div id="child">
</div>
</div>
css looks like,
#parent{
height:100px;
width:200px;
any-aother-property1:something;
any-aother-property2:something;
any-aother-property3:something;
}
Is there is any way to inherit all the properties to child at once , means can I do like,
$('#child').properties= $('#parent').properties
If you really want to dynamically inherit all CSS properties given to the parent at runtime, you can do the following.
Caution: This overrides the default value for all properties. Generally speaking, it is wise to assume that defaults are correct until proven otherwise. Some properties are inherit by default and some are not for various reasons. So you probably should only override specific properties that need to be changed.
#child {
all: inherit;
}
is this enough?
#parent, #parent > div {
/* your properties */
}
Copy inline:
$('#child').get(0).style = $('#parent').get(0).style;
But better if you find a CSS way as stated in the other answers.
UPDATE:
Get all styles:
$('#child').get(0).style = window.getComputedStyle($('#parent').get(0), null);
As far as I know there is no such a thing but you can always do something like this:
#parent, #child{
height:100px;
width:200px;
any-aother-property1:something;
any-aother-property2:something;
any-aother-property3:something;
}
Add both id's to have the same properties.
I have added a function in my library, custags.js which will help you doing that.
This is the extendcss() which requires the query selectors of the elements or the other methods to function.
You can do this with any type of elements, let it be equals or parent-child.
Here is the working demo:-
const parent = document.querySelector('.parent')
const child = document.querySelector('.child');
Ω('#button').on('click', ()=>{
Ω('document').extendcss(parent, child);
});
.parent{
background-color: teal;
color: yellow;
}
<script src="https://obnoxiousnerd.github.io/custags.js/custags.min.js"></script>
<h1 class = "parent">Parent</h1>
<h1 class = "child">Child</h1>
<button id="button">Give child some css</button>
Since children inherit most of their parent's styles by default, you can focus on clearing the child's styles rather than setting them equal to the parent's.
In Chrome and Opera, you can do so with one line of code:
$('#child')[0].style.all= 'unset';
This works whether child's CSS properties are in a style sheet or are created dynamically.
To clear dynamically-created CSS only, you can do this in all modern browsers:
$('#child')[0].style.cssText= '';
That will restore the style sheet properties.
The cross-browser solution to your problem may be the following:
var cs= getComputedStyle($('#child')[0]);
for (var i=0 ; i<cs.length; i++) {
$('#child').css(cs[i], 'inherit');
}
This iterates through all of child's styles, setting them to be inherited from the parent.
You can test each of these methods in different browsers at this Fiddle:
http://jsfiddle.net/9c3sy2eb/7/
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)?