How to detect if element has 'auto' height
Please try:
document.getElementById("ele_id").style.height
Also check the following plugin:
http://gregpettit.ca/2012/jquery-check-if-element-has-auto-widthheight/
Update:
Based on other answers and lot of online research I came up with a mix of everything in a single function. Check out the jsfiddle here: https://jsfiddle.net/oriadam/d01ap7r6/3/
// input a jQuery element
// return true for elements with auto height (90-100% is considered auto as well)
// return false for elements with fixed height
function is_height_auto($e) {
var e = $e[0],
// check fixed style:
chk = function(value) {
return /\d/.test(value) && !/^(100|9\d)\%/.test(value);
};
// start from the first, easiest, inline styles
if (chk(e.style.height)) {
// console.log('fixed for having style', e.style.height)
return false;
}
// start from the first, easiest, inline styles
var overflow = getComputedStyle(e)['overflow'];
if (overflow == 'scroll' || overflow == 'auto' || (e.tagName == 'BODY' && overflow == 'visible')) {
// console.log('auto for having overflow or is body', getComputedStyle(e)['overflow'], e.tagName);
return true;
}
// deprecated chrome way - check each rule that applies to the element
if (typeof getMatchedCSSRules == 'function') {
var i, MatchedCSSRules = getMatchedCSSRules(e) || [];
for (i = MatchedCSSRules.length; i; i--) {
if (MatchedCSSRules[i - 1].style.height) {
// console.log('found height at MatchedCSSRules[' + (i - 1) + ']: ', MatchedCSSRules[i - 1], ' All matches: ', MatchedCSSRules)
return !chk(MatchedCSSRules[i - 1].style.height);
}
}
}
// append something, see if height was changed, remove the something
var originalHeight = $e.height(),
$ghost = jQuery('<b style="display:block;height:1px;width:1px;padding:0;margin:0;">').appendTo($e),
newHeight = $e.height();
$ghost.remove(); // cleanup
// console.log('Using a ghost got ',newHeight > originalHeight,' originalHeight=' + originalHeight + ' newHeight=' + newHeight)
return newHeight > originalHeight;
} //is_height_auto()
** Ghost element method explained (Previous answer):**
Greg Pettit had a pretty good answer in his blog, here is the main idea:
What’s unique about having auto height? Well, the fact that it allows height to change dynamically, of course!
- Clone the element
- Put it in visibility:hidden and position:absolute
- Remove it's content
- See if height changed (it should be around 0 now).
Cleanup
var isAutoHeight = function(element) { // make a staging area for all our work. $('body').append('');
// assume false by default var autoHeight = false; // clone the div and move it; get its height var clone = element.clone(); clone.appendTo('#stage'); var initialHeight = clone.height(); // destroy all the content and compare height clone.html(''); var currentHeight = clone.height(); if (currentHeight < initialHeight) { autoHeight = true; } // get that clone and its smelly duplicate ID out of the DOM! clone.remove(); // do the same for the stage $('#stage').remove(); return autoHeight;
};
Starting by Oriadam answer I created following jQuery function:
/**
* Checks if the element has explicitly set height by CSS styles.
* E.g.:
*
* var $myElement = jQuery('.my-element');
* if ($myElement.hasExplicitHeight()) {
* //...
* }
*
* This function is needed as .height() or .css('height') return a value, even
* if no height property was explicitly set using CSS.
*
* @returns {Boolean}
*/
jQuery.fn.hasExplicitHeight = function() {
var $element = jQuery(this);
var $clone = $element.clone();
$clone.html('');
$clone.css('visibility', 'hidden');
$clone.css('position', 'absolute');
$clone.insertAfter($element);
var hasExplicitHeight = $element.css('height') === $clone.css('height');
$clone.remove();
return hasExplicitHeight;
};
It works fine under condition that it is called only after the document is ready:
jQuery(function() {
// this code is launched only after the document is ready
jQuery('.my-element').hasExplicitHeight();
});
Ran into a bug using the method of clone->heightCheck->remove innerHTML->heightCompare. Where it does not register a change in height, even if the element has 100%/auto height.
Instead, this method appears to work:
let autoHeight = false;
// Set up stage area with 100% height/width
const stage = document.createElement('div');
stage.setAttribute('style', "position: relative; height: 100%; width: 100%;");
// Add stage to body
document.body.appendChild(stage);
// Clone the element and append to stage
const clone = element.cloneNode(false);
stage.appendChild(clone);
// Get Initial Height
const initialHeight = clone.offsetHeight;
// Squish content
stage.setAttribute('style', "position: relative; height: 1px; width: 1px;");
// Get new height
const currentHeight = clone.offsetHeight;
// Get max height (if it exists)
const hasMaxHeight = getComputedStyle(clone)["maxHeight"];
// Compare
if (currentHeight < initialHeight && hasMaxHeight == 'none') {
// Has 100% or auto height, and no maxHeight
} else if (hasMaxHeight !== 'none') {
// Flexible, but has a maxHeight
} else {
// Constrained by height size
}
// Remove elements
stage.remove();