Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

document.body.style.marginTop returning blank string in JS

It was my understanding that [some elem].style.maginTop would return a string with the element's top margin.

Instead, I'm always getting a blank string. I want to use this with the body, but I also tried on a div, and that didn't work either.

console.log(document.body.style.marginTop); // logs ""
console.log(typeof(document.body.style.marginTop)); // logs "String"

var elem = document.getElementById("testDiv");
console.log(elem.style.marginTop); // logs ""
body {
    margin-top:100px;
}
#testDiv {
    margin-top:50px;
}
hi!

<div id="testDiv">test</div>

I'm not sure what I'm doing wrong... Does anybody have a non-jQuery solution to this?

like image 971
PullJosh Avatar asked Dec 26 '15 15:12

PullJosh


3 Answers

The HTMLElement.style only returns inline styles:

The HTMLElement.style property returns a CSSStyleDeclaration object that represents the element's style attribute.

To access the styles from stylesheets use Window.getComputedStyle(element):

The Window.getComputedStyle() method gives the values of all the CSS properties of an element after applying the active stylesheets and resolving any basic computation those values may contain.

var elem = document.getElementById("testDiv");
var style = window.getComputedStyle(elem);

//output
document.body.innerHTML = style.marginTop;
body {
    margin-top:100px;
}
#testDiv {
    margin-top:50px;
}
hi!

<div id="testDiv">test</div>
like image 158
Johan Karlsson Avatar answered Nov 16 '22 22:11

Johan Karlsson


You can use getComputedStyle and getPropertyValue to get top margin.

console.log(document.body.style.marginTop); // logs ""
console.log(typeof(document.body.style.marginTop)); // logs "String"

var elem = document.getElementById("testDiv");
//console.log(elem.style.marginTop); // logs ""
console.log(getComputedStyle(elem).getPropertyValue("margin-top"));
alert(getComputedStyle(elem).getPropertyValue("margin-top"));
body {
    margin-top:100px;
}
#testDiv {
    margin-top:50px;
}
hi!

<div id="testDiv">test</div>

Tested and working.

like image 44
Nicolo Avatar answered Nov 16 '22 20:11

Nicolo


I don't know why, but I got it working by implicitly assigning the margin-top by JS first. I know why my answer works (it's been over 2 years so I better know why). By setting the values of div#test and body to 50px and 100px like this:

document.getElementById("testDiv").style.marginTop = '50px';
document.body.style.marginTop = '100px';

I'm actually setting the CSS property/value of the elements inline:

<body style='margin-top: 100px'>
  <div id='testDiv' style='margin-top: 50px'>test</div>
</body>

Whenever the .style property is used, the CSS property/value that follows it is always inline. One important thing to remember about inline CSS styles is that they have a higher priority than the other 2 means of CSS Declaration: external stylesheets (ex. <link href="file.css"...) and inline stylesheet (ex. <style>...</style>). The only way to override an inline style is to use !important (unless of course the inline style has !important as well.)

So if the.style property is used to read a property/value of an element, it'll only return the inline style value if it actually exists which in OP's case it never did and in my case it did because I used .style to assign the property/values. While my solution is correct, the answers by Nicolo and Mr. Karlsson are better since you'll get the values from all CSS stylesheets.

document.getElementById("testDiv").style.marginTop = '50px';
document.body.style.marginTop = '100px';
console.log(document.getElementById("testDiv").style.marginTop);
console.log(document.body.style.marginTop);
body {
  margin-top: 100px;
}

#testDiv {
  margin-top: 50px;
}
hi!

<div id="testDiv">test</div>
like image 26
zer00ne Avatar answered Nov 16 '22 21:11

zer00ne