JS/CSS: backgroundColor for second class - javascript

I am grabbing the element below like:
let box = document.querySelector('.zero');
When I go to check the backgroundColor in javascript, it shows as "" :
box.style.backgroundColor // ""
If I'm grabbing the element node, why doesn't it list the backgroundColor as #DCDCDC, like what I set it in my CSS as? I assume it's due to the multiple classes on the element but not sure why.
code:
<div class="tic-tac-box zero">
</div>
.tic-tac-box {
background-color: #DCDCDC;
border-radius: 5px;
border: 2px solid white;
}

The reason it's not logging the color is not because there are multiple classes, but because how the DOM API works, and that Javascript doesn't know what's going on with your linked CSS. If you want to log the current style of your element you'll have to use the getComputedStyle() method:
getComputedStyle(box).backgroundColor); // rgb(220, 220, 220)
tldr: "The style property only retrieves inlined CSS values while getComputedStyle style retrieves computed CSS values." Check out this article for more info. You'll notice when you set colors with that syntax, it appends inline styles too.

Related

why are initial CSS styles not visible on DOM element.style field?

OK I have full expectation of going down in flames for asking something stupid (or at least duplicate), but in the attached snippet, why do I have to use window.getComputedStyle to access styles applied by CSS? I was under the impression that the .style field would at least reflect those styles initially applied by CSS, and/or manually changed since then.
If not, what are the exact rules governing which properties are reflected (and when) in an element's .style field?
setTimeout(() => {
console.log("the bckg color:", reddish.style.backgroundColor);
console.log("the width:", reddish.style.width);
console.log("from a computed style:", window.getComputedStyle(reddish).backgroundColor);
console.log("from a computed style:", window.getComputedStyle(reddish).width);
}, 100);
#reddish {
background-color: #fa5;
width: 100px;
height: 100px;
}
<html>
<body>
<div id="reddish"></div>
</body>
</html>
The HTMLElement.style property is not useful for completely
learning about the styles applied on the element, since it represents
only the CSS declarations set in the element's inline style
attribute, not those that come from style rules elsewhere, such as
style rules in the section, or external style sheets. To get
the values of all CSS properties for an element you should use
Window.getComputedStyle() instead.
Via- MDN Web Docs | Getting Style
Information
HTMLElement.style:
The HTMLElement.style property is used to get as well as set the inline style of an element.
console.log(document.getElementById("para").style.fontSize); // will work since the "font-size" property is set inline
console.log(document.getElementById("para").style.color); // will not work since the "color" property is not set inline
#para {color: rgb(34, 34, 34);}
<p id="para" style="font-size: 20px;">Hello</p>
Window.getComputedStyle():
The getComputedStyle() method however, returns an object containing the values of all CSS properties of an element, after applying active stylesheets and resolving any basic computation those values may contain thus returning the css properties from both inline style declarations as well as from external style-sheets.
console.log(window.getComputedStyle(document.getElementById("para")).fontSize); // will work
console.log(window.getComputedStyle(document.getElementById("para")).color); // will work
#para {
color: rgb(34, 34, 34);
}
<p id="para" style="font-size: 20px;">Hello</p>
HTMLElement.style is for the inline style of an element. It does not take into account CSS whatsoever. This is basically just directly setting or getting a property on the element object.
<div style="color: red;">Hello</div>
Window.getComputedStyle() takes into account inline styles and CSS, after resolving cascading, inheritance, etc. It's basically the "final" actual style value used to render the element on the page.
// CSS
#blue-text {
color: blue !important;
}
// HTML
<div style="color: red;" id="blue-text">Hello</div>
// JS
const myElement = document.querySelector("#blue-text");
myElement.style.color; // "red" because that's the inline style
window.getComputedStyle(myElement).color; // "rgb(0, 0, 255)" because CSS !important overrides inline style

Can I print a CSS style property to the console using Javascript?

Got another basic question that I couldn't seem to find the answer for online. I can change the CSS property of an element easily using javascript,
document.getElementById("ExampleID").style.height="30px";
however whenever I try printing a property to the console, with
console.log(document.getElementById("ExampleID").style.height);
it prints a blank line instead of the property. How can I print a style property value of the desired element? Thank you very much
You can use getComputedStyle
let elem = document.getElementById('test');
let ht = window.getComputedStyle(elem, null).getPropertyValue("height");
console.log(ht)
.test {
height: 300px;
width: 300px;
border: 1px solid red;
}
<div class="test" id="test">Test</div>
Make sure you are testing with an actual element that will be returned from your selection (see example below). Otherwise your code is fine.
const elem = document.getElementById('elemId');
elem.style.height = '30px';
console.log(elem.style.height);
<div id="elemId"></div>
document.getElementById("ExampleID").style.height="30px";
console.log(document.getElementById('ExampleID').clientHeight);
console.log(document.getElementById('ExampleID').offsetHeight);
<div id="ExampleID">
clientHeight includes padding.<br>
offsetHeight includes padding, scrollBar and borders.
</div>
clientHeight includes padding.
offsetHeight includes padding, scrollBar and borders.
You need to check HTML part in this case.
If you are setting from javascript then Your code is working fine.
In case Styles defined in CSS use window.getComputedStyle()
The window.getComputedStyle() method returns an object that reports the values of all CSS properties of an element after applying active stylesheets and resolving any basic computation those values may contain. Individual CSS property values are accessed through APIs provided by the object or by simply indexing with CSS property names.
Here is working snippet:
var divEle=document.getElementById("ExampleID");
console.log("Before:height::"+divEle.style.height);
console.log("Before:color::"+divEle.style.color);
var heightCss = window.getComputedStyle(divEle, null).getPropertyValue("height");
var colorCss = window.getComputedStyle(divEle, null).getPropertyValue("color");
console.log("Before:height from css::"+heightCss)
console.log("Before:color from css::"+colorCss)
function changeCss(){
divEle.style.height="30px";
divEle.style.color="blue";
console.log("After:height::"+divEle.style.height);
console.log("After:color::"+divEle.style.color);
}
.divClass {
height: 40px;
color: red;
width: 40px;
border: 2px solid black;
}
<div class="divClass" id="ExampleID">test</div><div><input type="button" onClick="changeCss();" value="Change Css"/></div>

Adding another class to an element, but as the first class

I want to add another class to a element, but some of those elements already have an existing class, however the class I am adding I want it to be the first class added in the class field and don't want to append it; because from what I know, in general, rules in the last listed class will overwrite rules in the former classes, correct!?
I know of a jquery method as below..
$("p").addClass("myClass");
However from what I understand this just appends the class and you can't choose where to put it.
Is there any way to do this easily or will I have to start removing classes and re-adding them?
Not sure if there is any need to do something like this, I personally like advice of #bwoebi just change specifity.
But still if you need it, this might help
HTML
<div class="second">Lorem text</div>
jQuery
var $div = $('div'),
classes = $div.attr('class');
$div.attr('class', 'first' + ' ' + classes);
You can put your variable which contains class's name in place of 'first'
Demo
You add multiple classes to an element by simply separating the classes using a space. For example:
<p class="key_paragraph dark no_border">Your text here</p>
<p class="key_paragraph dark">Your text here</p>
The order in which the classes are listed in the html attribute does not matter. What matters is the stylesheet.
In your stylesheet (css file), if you want any of the classes to override another you could change the order of the rules in the stylesheet. For example, if the class 'dark' has a border and the class 'no_border' does not, you must place 'no_border' after 'dark' in your stylesheet to ensure 'no_border' overrides 'dark' for the first paragraph. Like so:
.dark {
border: 2px solid red;
}
.no_border {
border: none;
}
Secondly, you could add specificity regardless of the order of the css rules. For example, combining classes to say 'if an element has the classes dark and red' is more specific than either of the two above rules. See here for more info on specificity. Thus, the following rule would ensure there is no border on elements with the classes 'dark' and 'no_border' regardless of the order in which they appear on the stlesheet:
.dark.no_border {
border: none;
}
.dark {
border: 2px solid red;
}
A third option is to use the css :not selector to target all elements with the class 'dark' that do not also have the class 'no_border'. Again, the order of rules in the stylesheet will not matter here. This is done as follows:
.no_border {
border: none;
}
.dark:not(.no_border) {
border: 2px solid red;
}
There are other ways to do this, but hopefully I have explained three easy ways in a manner you can understand. There is a more jquery-specific demo here (see the third example). Let me know if you have any questions.
Just for fun in case you wanted to add the new class at a specific index inside the current classes:
http://jsfiddle.net/ckzVk/
function addClassAtIndex(elementId,classNameToAdd,index){
var element = document.getElementById(elementId);
var elementClasses = element.className.split(" ");
elementClasses.splice(index,0,classNameToAdd);
var newClasses = elementClasses.join(" ");
element.className = newClasses;
}
To add class "man" to div:
<div id="stuff" class="cool bro sweet">The div.</div>
JS:
addClassAtIndex("stuff","man",1");
Result:
<div id="stuff" class="cool man bro sweet">The div.</div>

Change background color via a checkbox when checked with Jquery

I'm trying to change the background color of a div with a checkbox in it. I've made this for reference. I'm trying to replace the parent <div> with the 'highlight' <div>, so I thought the toggle <div> would work. When the checkbox is deselected, I would like the background color to go back to normal (or remove the 'highlight' <div>). Any help is appreciated.
You are setting an inline background-color style for the divs. This takes precedence over any properties you set via a CSS rule.
Add !important to the background-color value of the checked class in your css file, like so: http://jsfiddle.net/KtsGs/1/
There are a few issues present in the jsFiddle.
The first one is that, despite having written jQuery code, you haven't selected jQuery as the framework on the left hand side. That's a small issue specific to the code on jsFiddle, and easily fixed, though.
The second issue is that you have inline styles on the <div> elements, including a background-color. That inline style will be used in preference to any background-color specified using a CSS class (unless it's specified as being !important), so even when your code correctly adds the checked class to the element, the background colour isn't going to change.
The simplest solution is to simply change your CSS declaration:
.checked {
background-color: #ff0000 !important;
}
Here is an updated version of your jsFiddle with the working functionality (using the suggestion above).
However, I'd suggest you instead move the inline styles and JavaScript event handlers to their own CSS declarations, so you don't have to specify !important. That would require the following changes:
#holder > div {
clear: both;
padding: 0.5%;
margin-bottom: 1px;
border-bottom: 1px solid #eee;
float: left;
width: 96%;
style: height: 16px;
cursor: pointer;
background-color: white; // added this to the existing CSS
}
#holder > div:hover { // this is new
background-color: #fafafa;
}
Then move the CSS declaration for .checked below those, so that it takes precedence for the background-color property.
Here is another updated version of your jsFiddle, using the CSS declarations instead.

Dynamically change CSS rules in JavaScript or jQuery

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.

Categories

Resources