It can be really frustrating; you want to know the height of an element, but it is not in the DOM yet. Since the element’s width and height depends on the styling, the measures can only be calculated on screen, in the DOM.
Size & Styling
Your best shot is adding the element to the body in a hidden state (visibility: hidden
) or off-screen (position: absolute; left: -9999px;
), get the width and height and remove it from the DOM. But sometimes the size of the element depends on the css of an ancestor element, like width: 100%;
, which is not present in the body. Or better, you can also append the element to the eventual element, but only if that one exists and sometimes it doesn’t.
Family-tree-substitute
If it doesn’t, we could replicate it. We can make a structure that will ‘mimic’ the eventual structure that the elements dimension depends on. An example:
1 2 3 |
section.column p { font-size: 20px; } |
1 2 3 |
var $p = $('').text('Lorem ipsum dolor sit amet, consectetuer adipiscing elit...'); |
The size of the paragraph depends on the ancestor elements; when it is a child of a section
with the class .column
it will have a maximum width of 300px
and, since it has a larger font-size than the default 12px
, will be higher than outside of the column.
Now, lets replicate the ancestors. I use the jQuery css-parser I wrote to create the elements.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 |
function getDimension($el, tree) { var ancestors = tree.split(' '); // As 'base' I use a class for hiding the tree // by using visibility: hidden; and a position somewhere off screen var $chain = $().parse('div.secret'); // Create an element for each ancestor // and append them to each other. for (i in ancestors) { var $ancestor = $().parse(ancestors[i]); $chain = $ancestor.appendTo($chain); } // Append the given element to the chain // and add the complete tree to the body... $chain.append($el) .closest('.secret') .appendTo('body'); // ...so we can get the dimensions of the element var dimension = { width: $el.outerWidth(), height: $el.outerHeight() } // Now we can remove the element $('.secret').remove(); // And were done! return dimension; } |
This function will replicate the family tree needed to get the proper dimensions and can be used as simple as this:
1 2 3 4 5 |
var size = getDimensions($p, 'section.column'); console.log(size.width, size.height); |
Ok, this only works if you now the chain of ancestors, but hey, even the web can’t be perfect…