image dimensions oddity - javascript

el = function(q) {return document.getElementById(q)};
el('strange').style.height = '100px'
el('strange').height = 2000
alert(el('strange').height) // 100?
alert(el('strange').getAttribute('height')) //2000? Wait.. What?
el is a shorthand of document.getElementById. Can someone explain me what's going on? I suspect that the height property is slightly different than the height attribute: they modified it so it returns the computed style. I'm not sure, because DOM 0 says that the property should be the same as the getAttribute, but the href property of an anchor doesn't match with the getAttribute in most browsers. And:
https://developer.mozilla.org/en/DOM/HTMLImageElement
The HTML:
<img id="strange" src="http://images.devshed.com/fcw/belts/fcw_forums.gif" />

The oddity isn't exaclty were you're spotting it. It comes from the fact that the call to the height attribute as a setter is creating a html height attribute in the img tag, and as far as I know, it's an attribute used only for canvas. There is no connection between this html tag and the dom value.
If i do the following:
strange.style.height = '100px';
strange.height = 2000;
console.log(strange.height); // 100
console.log(strange.style.height); // 100px
the output will be 100 and 100px the height on the DOM is correct. However, using the getAttribute search for the attributes in the html tag, therefor returning "2000".
EDIT
Ok i think i got it
There are 3 different stuff:
The css height, the height attribute, the height DOM value.
The easiest is the DOM value. It always return the img real height in css pixel. If set trhough css, it will be based on the css value, if set through attribute, it will be calculated from that.
Now the two other.
They both specify the img dimension. But the css value as precedence over the HTML attribute.
This is stated in the w3 recommandation. I quote
For
Inline replaced elements, block-level replaced elements in normal flow, 'inline-block' replaced elements in normal flow and floating replaced elements
It's stated that
If 'height' and 'width' both have computed values of 'auto' and the element also has an intrinsic height, then that intrinsic height is the used value of 'height'.
Therefore, img (who are inline-block element I think) use the height css value, but if this one is set to auto (and it's the default) it uses the intrinsic height. And that is the html attribute.
So calling strange.height as a getter gets the DOM value, and as a setter, it sets the HTML attribute.
EDIT2 And to answer more exactly, you have 3 basic rules:
CSS prevails over attribute
DOM should be the same as attribute
DOM reflects the reality (here the real height)
You just can't follow the 3 rules if both CSS and attribute value are specified and differ.
The point is DOM should be the same. Here it can't be if there is CSS, so it has a different value.
As a side note, a nice explanation of the use of the height attribute here: http://reference.sitepoint.com/html/img .

Related

Distinguish between used and computed values returned from getComputedStyle

The MDN documentation for getComputedStyle states
The values returned by getComputedStyle are known as resolved values.
These are usually the same as the CSS 2.1 computed values, but for
some older properties like width, height or padding, they are instead
the used values.
Is there a way to only get the computed values without the used ones?
My use case is this:
Take for instance a body element. The browsers width is currently 600px. If you call getComputedStyle on the body element, the style returned would contain width: 600px.
Resize the browser and the width will be different again, although the "correct" value should probably be auto.
I'd need the returned style to be idempotent, meaning that I can set the style back on the element without changing some values (like width) to fixed values.
For a given element and style property you would need the first of:
A value that has been explicitly applied to an element (through the style attribute or CSS)
The browser's default value for that property
You cannot do that reliably because the CSS spec does not provide a way to access the browser's default CSS rules.

Get element's CSS value with Javascript

I'm trying to find a way to get an element's CSS height property, or actually, just tell if a height property is set.
The problem is, when I use
$(elem).css('height');
I get the display height of the element, but I'm trying to see if the element has a height property that was set in either a class, id, or directly on the div.
Any suggestions?
You can use height also.
$(elem).height(); // to get the height.
Also see this Q/A
if you want to get correct CSS value, i can advise don't use jQuery
if we have HTML:
<div id="elem" style="height: auto"></div>
we can write JS:
$('#elem').get(0).style.height // "auto"
if we have HTML:
<div id="elem"></div>
JS:
$('#elem').get(0).style.height // ""
universal function:
var height = function(elem){
return $(elem).get(0).style.height === "" ? $(elem).height() : $(elem).get(0).style.height;
}
Likely not the best way but I would just look at the outerHTML, see if a height value is set. If it isn't then it's in the CSS (or nothing is set).
s = $(elem)[0].outerHTML;
if (s.indexOf("height:") > 0) {
// inline style
} else {
// somewhere else
}
$( "div" ).click(function() {
you can check if height is defined for this div parent element or children using *this* reference. For now i am just fetching the height of the div which has been clicked.
var height= $( this ).css( "height" );
//If height is truthy
if(height){
//your code here
}
});
Hope this answers your query.
For more details..
The problem is what do you mean by 'is set'?
In vanilla javascript you can do:
element.style.height
This will return an empty string if no height has been set INLINE.
However, if a height has been applied via a stylesheet, it will still return an empty string.
The problem is, if you return a computed height by either .height() in jQuery or window.getComputedStyle(element).height in Javascript, then there is no way of telling if it was calculated by applying a style sheet (what you would call 'having a height property set'), or was generated by extending the height of the element to fit its contents (which you'd call 'not having a height property set').
---------------------Update----------------------
To make it clearer, I'm trying to see if the height of a div is a computed height, or if it a height that was defined in css.
A div can contain the height of it's children, or it can have a height set specifically on the div. The heights for either the children or the div in question can be set in a CSS file, style tag on the page, or on the div itself.
I'm trying to see if the div has a css set height property.
by pedalpete
---------------------Update----------------------
I understood your question, but perhaps my answer was a bit opaque.
There is nothing you can call that will tell you if an element has a style property applied to it by a style sheet. In other words, you can't do what you want to do.
The only thing you can find out (via element.style) is if there is an inline style declared.
getComputedStyle will tell you how high an element currently is, but it won't tell you how it got that way.
by Graham Nicol
Looks like there isn't an easy way of doing this, my method to resolve this is to hide the children of the div, and and check if the height of the div has changed. If it has, the height was not set, if it hasn't the height was set.
This fails when the div has nothing but text, but as this is a layout tag, it will likely always have sub tags.
var elHeight = $(elem).height();
$(elem).children().hide();
var checkHeight = elHeight===$(elem).height();
$(elem).children().show();
console.log(checkHeight);
if(checkHeight===false) return setSize($(elem).parent().height()/2);

How to get min-height CSS property? [duplicate]

This question already has answers here:
How to get computed style of a HTMLElement
(2 answers)
Closed 9 years ago.
As far as I was aware CSS properties of the DOM element style are camel-cased, such that min-height would be element.style.minHeight, but in my example below the style property is empty, but jQuery's abstraction gets it correctly.
// element with css: #test{ min-height: 100px; }
var el = document.getElementById('test');
console.log( el.style.minHeight );
// ""
console.log( $(el).css('min-height') );
// "100px"
See fiddle for this in action.
What is jQuery doing to pull the correct style property that I'm not doing?
interestingly enough, adding a style attribute directly on the html element does work.
You can use window.getComputedStyle(el,null).getPropertyValue("min-height") and see if it returns the right value.
WARNING: It might not work on IE < 8.
From Mozilla's website...
CSS 2.0 defined only computed value as the last step in a property's calculation. Then, CSS 2.1 introduced the distinct definition of used value so that an element could explicitly inherit a width/height of a parent whose computed value is a percentage. For CSS properties that don't depend on layout (e.g. display, font-size, line-height), the computed values and used values are the same. These are the properties that do depend on layout so have a different computed value and used value: (taken from CSS 2.1 Changes: Specified, computed, and actual values):
background-position
bottom, left, right, top
height, width
margin-bottom, margin-left, margin-right, margin-top,
min-height, min-width
padding-bottom, padding-left, padding-right, padding-top
text-indent
Try this:
style = window.getComputedStyle(el),
console.log( style.getPropertyValue('min-height'));
Check an update of your fiddle:
http://jsfiddle.net/VEuJe/4/
JQuery method css is not so simple. You can check on this link jquery css
The .css() method is a convenient way to get a style property from the
first matched element, especially in light of the different ways
browsers access most of those properties (the getComputedStyle()
method in standards-based browsers versus the currentStyle and
runtimeStyle properties in Internet Explorer) and the different terms
browsers use for certain properties. For example, Internet Explorer's
DOM implementation refers to the float property as styleFloat, while
W3C standards-compliant browsers refer to it as cssFloat. For
consistency, you can simply use "float", and jQuery will translate it
to the correct value for each browser.

Width of an inline element

How do know width of an inline element, without adding to document?
With adding
var span = document.createElement('span');
span.innerHTML = 'Hello, world!';
span.offsetWidth; //0
document.body.appendChild(span);
span.offsetWidth; //70
How without adding to document?
Sorry for my english)
The width of an element does obviously depend on the styles used (e.g. on the font size), so it is impossible to compute the width of the element without knowing where it is in the DOM.
You may add it to some invisible element if you don't want it to show on the screen.
You cannot get a width of an element if the element itself is not part of the DOM.
You need to append it, but you may also position it outside the visible area (with position: absolute and a negative left/top property) and remove it once you got the width
Until the element is added, there's no way to know for sure how wide it is, because it depends on the styling context.
jQuery's width() method has a trick that it uses for display: none elements, I don't know if it will work for an element that hasn't even been added to the DOM (it works by temporarily showing the element, getting the width, then hiding it again).

How do I get the CSS width value with Javascript?

I'm trying to calculate the width of an element so that when I use JavaScript to wrap a parent element around it, I can set the width of the parent to match the width of the child. The obvious $('#element').css('width'); isn't quite what I want because it only seems to return the calculated value in pixels. Is there some way that I can return the actual CSS value, whether it be 300px or 20% or auto, instead of the calculated value?
Here's generally how it's set up, but I'd like to know the CSS value of #child instead of the calculated value.
$(document).ready(function(){
$('#child').wrap('<div id="parent"></div>');
$('#parent').each(function(){
var childWidth = $(this).children('#child').css('width');
$(this).css('width', childWidth)
});
});
I don't believe you can do that. The best you will get is offsetWidth or clientWidth which return the calculated value, with and without counting margins, padding and borders.
You need to read the stylesheet itself.
See: How can I read out the CSS text via Javascript as defined in the stylesheet?
Everyone but IE supports window.getComputedStyle(element), which you can use like so:
getComputedStyle($('#child')).width; // returns actual width of #child
Doesn't help you with IE, though.

Categories