Suppose I have the following.
HTML:
<div id="foo"></div>
CSS:
#foo{
width: 150px;
}
JS:
document.getElementById("foo").style.width //Equals to "" instead of 150px
$("#foo").css("width") //equals to the expected "150px"
or this JSFiddle.
Why can we access the width of the element using jQuery but not using vanilla JS? Is it because external CSS rules are not part of the DOM?
Try offsetWidth. When you try to access style.width, it will give you just the width assigned to the element's style property. But in your case it is assigned the width via css rule.
document.getElementById("foo").offsetWidth;
Fiddle
Edit: clientWidth would probably be more appropriate as it gives you the inner width of the element, where as offsetWidth considers borders, margins as well.
Use getComputedStyle. See this updated fiddle:
computedWidth = window.getComputedStyle(document.getElementById("foo"), null).
getPropertyValue("width");
elem.style will just give you back inline styles associated with the element, i.e. the contents of the style="" attribute.
Related
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?
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>
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.
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>
Hm, I tried it as well with the same result as you did. A quick google search turned up Using JavaScript to read html / body tag margin-top which uses style.getPropertyValue() to return the information you're looking for.
instead of using core javascript, let you use js library jQuery. Then use this syntaxt to get its value.:
console.log($('body').css('margin-top'));
for pure javascript use this
var element = document.body,
style = window.getComputedStyle(element),
margin_top = style.getPropertyValue('margin-top');
console.log(margin_top);
http://jsfiddle.net/hAw53/726/
I tried the following code to remove a property from my css but doesn't work.
document.getElementById("wrap").style.removeProperty('overflow-x');
The CSS:
#wrap{
overflow-x : hidden;
}
When I run the javascript, I get the error Cannot read property 'style' of null
The code posted would remove overflow-x style in the following scenareo:
<div id="wrap" style="overflow-x: hidden"></div>
CSS applied properties are not applied directly to the style attribute of an element - they are applied at a layer higher.
Effectively, there's nothing to remove on the style property, but you can set a value there instead, which would override the value applied from CSS properties (unless css has !important flag specified)
Try this instead:
document.getElementById("wrap").style.overflowX = 'visible';
As your specific scenario is about applying the style based on some browser detection, I suggest the following javascript:
var userAgent = window.navigator.userAgent.toLowerCase();
var is_ios = /iphone|ipod|ipad/.test( userAgent );
if (!is_ios) document.body.className += 'not-ios';
With CSS:
.not-ios #wrap {
overflow-x : hidden;
}
You could also use class "wrap" instead of id to make this more re-usable (if required)
Using:
$(my_div).width(window.innerWidth)
Does not provide the desired result, because it does not account for the vertical scrollbar, so the element overflows the window, creating a horizontal scrollbar, as illustred below.
Illustration http://dl.dropboxusercontent.com/u/62862049/Screenshots/om.png
You could use width:100%
<div style="width:100%;height:1500px;background:red"></div>
Demo
window.innerWidth includes the width of the vertical scrollbar in some versions of Firefox:
https://developer.mozilla.org/en-US/docs/Web/API/window.innerWidth
however, w3schools seems to disagree (it says it doesn't include the width of the scrollbar):
http://www.w3schools.com/jsref/prop_win_innerheight.asp
There's even a bug concerning this in the Mozilla bug tracker:
https://bugzilla.mozilla.org/show_bug.cgi?id=156388#c14
The confusion above has been cleared a bit with CSS3, which has a specific property to calculate widths, box-sizing. Set box-sizing like this:
box-sizing: border-box
Which does the following (quoted from w3schools):
The specified width and height (and min/max properties) on this element determine the border box of the element. That is, any padding or border specified on the element is laid out and drawn inside this specified width and height. The content width and height are calculated by subtracting the border and padding widths of the respective sides from the specified 'width' and 'height' properties
You can use width:100% as noted, but bear in mind that this will ALSO include any extra spacing and padding you got - however, in CSS3-enabled browsers, this is resolved with the correct box-sizing property, as noted above. So, if you got, say a div like:
<div style="width:100%; padding: 20px;">
<div style="width:100%; background:red">Test</div>
</div>
The inner div will go off-bounds according to the CSS21 spec. Here's a jsFiddle that illustrates this problem.
So, make sure that you don't have any padding to avoid such issues.
If you want to use jQuery to get the width of the window, you could use jQuery's width() method (or css("width")).
Could you use
$(my_div).css('width', '100%');
?
$(my_div).css("width", "100%");
or
#my_div {
width: 100%;
}
You're also probably going to want to make sure your body or parent div has no padding or margin:
body {
padding: 0;
margin: 0;
}
I have a div inside of another div. The outer div has a percentage width (80%), and I want the inner div to have 30px less width than the width of the outer div. How do I do this? I'm assuming I'll need to use javascript?
Thanks in advance.
Use margins :
<div style="width:80%;">
<div style="margin-left:15px;margin-right:15px;"> inner </div>
</div>
demonstration
#dystroy has a very good answer, though it lacks dynamic customization.
My take, use CSS variables.
You'll have to do something like this:
#parent-div
{
var-width: 100px; /* Or something else? */
//Notice that though the attribute is named var-width, the browser will
//treat it as width and will use the `var-` prefix as directive
//so that the calculations can be performed by using it as variable.
}
#child-div
{
width: calc(var(width) - 30);
}
This will make the CSS calculate the child's width.
More on this, here.
<style>
.info{
width:94%;
}
</style>
Now doing like this using JQuery
$('.info').css('width');
returns 94px rather than the equivalent value in pixles (500px in my case.)
if i set the width in css as 105% , JQuery would return it as 105px .
The height and width of the parent container is 600px and 500px respectively.
I think a possible cause is the container of the element being hidden at the moment you're trying to obtain the dimensions.
I had a similar situation with nested divs and tables.
See the following fiddle where I managed to reproduce the behavior:
http://jsfiddle.net/36yvb/
I still think it's a bug in jQuery returning a percentage as an integer number (without the % sign) when not being able to actually compute the dimensions of the element.
Change the width of #another-cell (expressed in %) and see it return the same value without the % sign when the table is hidden.
Actually, it doesn't seem so: see this fiddle.
html:
<div id="info"></div>
css:
html, body {
position: relative;
width: 500px;
}
#info {
width: 94%;
}
js:
$( function() {
document.write( $('#info').css('width') );
});
what is info width relative to? is it an element with 100px width maybe?
The width that it returns depends upon what part of the HTML is it written in. Meaning to say is that if it is written inside tag then then 94% percent would reflect 94% of that particular div.
But again if another tag in the same tag is already using some amount of defined width then the info might even get lesser space if the tag in defined before the info tag.
Please give up more amount of actual code to get a better answer
The only thing that explains this behavior is that you have more than one element with the class info
When this happens and you do a $('.info').css('width'); jQuery will return to you the width of the first element in the set.
If this is the case, you may need to be more specific with your selector.
DEMO
Each broswer will return textually different, but logically equal values e.g., #FFF, #ffffff, and rgb(255,255,255) when using .css()
Instead of using .css('width') use .width()
According to jQuery: http://api.jquery.com/width/
The difference between .css(width) and .width() is that the latter
returns a unit-less pixel value (for example, 400) while the former
returns a value with units intact (for example, 400px). The .width()
method is recommended when an element's width needs to be used in a
mathematical calculation.