11

In jQuery, both $('#foo').height() and $('#foo').css('height') return a value, even if no height property was explicitly set using CSS. Is there a way to detect if an element doesn't have an explicit height, i.e. it's just being rendered according to its contents?

Here's an example I wrote to demonstrate: http://jsfiddle.net/Enn6p/2/

EDIT

To clarify my question further, $('#foo').css('min-height') and $('#foo').css('max-height') already properly return an empty string if they aren't explicitly set. I am looking for a way to find out whether an explicit height value is being set via CSS, or not.

USE CASE

I have a script that attempts to make floated elements the same height. It does this by looping over the elements to see which one is the tallest, then applying that height to all of them. In some cases, these elements already have an explicit height set, but the others are rendered implicitly.

I now want to add the ability to undo this, and make everything go back to their original heights. In order to do this, I need to know if the element originally had a height set, or if the height was "auto". Once I can do this, I can store the original value in the data collection for the element and then use that to revert to the original height later.

Chris Bloom
  • 3,526
  • 1
  • 33
  • 47
  • nice question. my initial thoughts are that this is not simple, but im interested in seeing the answer – Sam Creamer Jun 10 '14 at 17:37
  • http://stackoverflow.com/questions/10552382/find-out-if-html-height-is-set-by-style-or-by-content – theonlygusti Jun 10 '14 at 17:39
  • Possibly related: http://stackoverflow.com/questions/2281633/javascript-isset-equivalent – TylerH Jun 10 '14 at 17:40
  • Thanks for the suggested links. That lead me to wonder if comparing `$('#foo').css('height') == $('#foo')[0].style.height` would work. Is `.style` available cross browser? – Chris Bloom Jun 10 '14 at 17:46
  • 1
    @Chrisbloom7 The `style` property is available across all browsers, but it's not what you think. `.style.height` will only be set if the `style` attribute provides a `height` value. It will not be set if the element has a `class` that sets a `height` value. `style` is probably not the way to go – Ian Jun 10 '14 at 17:48
  • 1
    Thanks, Ian. I see now it only works with inline styles. – Chris Bloom Jun 10 '14 at 17:50
  • 1
    have a look at this: http://jsfiddle.net/strikernl/y3P3A/ and also my answer – Ashkan Mobayen Khiabani Jun 10 '14 at 17:54
  • styles can come from so many places, it would be hard to define what "explicitly set" means. what with the cascaded classes and tags, min-height, zoom, border, padding, etc all affecting the height and all... – dandavis Jun 10 '14 at 18:13
  • Good point @dandavis. In this case, I'd be satisfied knowing only if a height property has been defined directly on the object. – Chris Bloom Jun 10 '14 at 18:45
  • I added a use case above to further clarify my issue. – Chris Bloom Jun 10 '14 at 18:50
  • Can't you just do `elem.style.height = 0` on all your floating elements ? – theonlygusti Jun 10 '14 at 18:55
  • See my answer on similar post [here](https://stackoverflow.com/a/71140177/1245149) – Mojo Feb 16 '22 at 10:34

2 Answers2

2

In some old versions of jQuery it was possible:

http://jsfiddle.net/strikernl/y3P3A/

but now you should just use a function like:

function sizeDefined(obj){
   var tmp = obj.clone().html('').appendTo($('body'));
    var w = (tmp.width()==0  ? "no":"yes");
    var h = (tmp.height()==0  ? "no":"yes");
    tmp.remove();
   return  [w,h];
}

http://jsfiddle.net/Enn6p/12/

Ashkan Mobayen Khiabani
  • 33,575
  • 33
  • 102
  • 171
  • This returns false negative if there is a min-height but no height. http://jsfiddle.net/Enn6p/5/ – Chris Bloom Jun 10 '14 at 18:01
  • @Chrisbloom7 how about now? – Ashkan Mobayen Khiabani Jun 10 '14 at 18:18
  • Still doesn't seem to work. http://jsfiddle.net/Enn6p/9/ I think because the cloned element is never rendered by the DOM, so there is never any height. – Chris Bloom Jun 10 '14 at 18:23
  • You can just do `return [tmp.width()==0 && tmp.css('min-width')=='', tmp.height()==0 && tmp.css('min-height')=='']`, there is no need for the ternary assignment. – theonlygusti Jun 10 '14 at 18:28
  • Thanks, but it's still not working accurately. It returns `true` for Outer B even though that only has a `min-height` specified, and it returns `false` for Inner B even though that has a `height` specified – Chris Bloom Jun 10 '14 at 18:35
  • The link you showed is either wrong, or it isn't fixed. – theonlygusti Jun 10 '14 at 18:35
  • Well, http://jsfiddle.net/Enn6p/16/ is certainly closer, but it's still reporting one false positive: inner_a is reported as having a set height when it doesn't. Thoughts? – Chris Bloom Jun 10 '14 at 19:43
  • Slight fix to some logic: http://jsfiddle.net/Enn6p/17/ (still reporting false positive) – Chris Bloom Jun 10 '14 at 19:46
1

Basically, if you get rid of the content of an element and measure its height it will equate to 0, unless it has a height set previously (as a style). So by that reasoning:

 function hasSetHeight(elem){
    var html=elem.html();
    elem.html('');
    height = elem.height();
    elem.html(html);
    return (height > 0);
}

deletes all content of the element, measures its height and returns true or false if the element has a set height or not.

theonlygusti
  • 11,032
  • 11
  • 64
  • 119
  • Why did this get down voted? It seemed to work when I tested it, though was wondering if it would lead to content flashing in and out on large pages. http://jsfiddle.net/Enn6p/4/ – Chris Bloom Jun 10 '14 at 17:57
  • It probably got downvoted because you merely provided code. You provided no explanation. – Evik James Jun 10 '14 at 18:04
  • This seems to work, but only if the element you are measuring has already been rendered in the DOM. If you try doing it on an element that hasn't been added to the DOM, it will always report false even if an explicit height has been set. It works for my purposes, but figured I'd mention it in case anyone else comes along looking. – Chris Bloom Jun 10 '14 at 18:18
  • @Chrisbloom7 Is there anything else that could be improved? – theonlygusti Jun 10 '14 at 18:26
  • 1
    Actually, I'm testing this again and it doesn't work after all. See http://jsfiddle.net/Enn6p/11/ It returns `true` for Outer B even though that only has a `min-height` specified, and it returns `false` for Inner B even though that has a `height` specified. – Chris Bloom Jun 10 '14 at 18:32
  • @Chrisbloom7 So you want only height specified, not min or max? – theonlygusti Jun 10 '14 at 18:36
  • `$('#foo').css('min-height')` and `$('#foo').css('max-height')` already properly return an empty string if they aren't explicitly set. I want to find out if there is an explicit $('#foo').css('height') value. – Chris Bloom Jun 10 '14 at 18:40
  • I am going to make a new answer. – theonlygusti Jun 10 '14 at 18:51