views:

307

answers:

4

I am making a simple accordion menu in javascript. I'd like to be able to set the compact and expanded heights for the elements via the css max-height and min-height values. For some reason, when I try to retrieve the min-height and max-height of the elements in javascript for animation purposes, I get an empty string rather than, for instance, "500px" like it should. The max-height value is set in css, e.g. #id { min-height: 40px; max-height: 500px; } is all set up, but when I put a debugging mechanism in my javascript such as alert( item.style.minHeight ); it pops up an empty alert box. This happens in Firefox 3.6.2 and IE 8. Does anybody know why javascript refuses to be able to get an element's minHeight and maxHeight?

A: 

You need to use currentStyle instead...

alert(item.currentStyle.minHeight);

The style property refers to what has been set by Javascript, as opposed to the inherited CSS. Libraries like jQuery address this internally (among other countless annoyances).

Josh Stodola
+2  A: 
currentStyle for IE, getComputedStyle elsewhere.
document.defaultView.getComputedStyle(who,'').getPropertyValue('min-height');

Might as well learn it, IE 9 will support getComputedStyle.

kennebec
+3  A: 

The element.style property lets you know only the CSS properties that were defined as inline in that element, you should get the computed style, is not so easy to do it in a cross-browser way, as others said, IE has its own way, through the element.currentStyle property, the DOM Level 2 standard way, implemented by other browsers is the document.defaultView.getComputedStyle method.

However there are differences between the IE way and the standard way, for example, the IE element.currentStyle property expect that you access the CCS property names composed of two or more words in camelCase (e.g. maxHeight, fontSize, backgroundColor, etc), the standard way expects the properties with the words separated with dashes (e.g. max-height, font-size, background-color, etc).

Also, the IE element.currentStyle will return all the sizes in the unit that they were specified, (e.g. 12pt, 50%, 5em), the standard way will compute the actual size in pixels.

I made some time ago a cross-browser function that allows you to get the computed styles in a cross-browser way:

function getStyle(el, styleProp) {
  var value, defaultView = (el.ownerDocument || document).defaultView;
  // W3C standard way:
  if (defaultView && defaultView.getComputedStyle) {
    // sanitize property name to css notation
    // (hypen separated words eg. font-Size)
    styleProp = styleProp.replace(/([A-Z])/g, "-$1").toLowerCase();
    return defaultView.getComputedStyle(el, null).getPropertyValue(styleProp);
  } else if (el.currentStyle) { // IE
    // sanitize property name to camelCase
    styleProp = styleProp.replace(/\-(\w)/g, function(str, letter) {
      return letter.toUpperCase();
    });
    value = el.currentStyle[styleProp];
    // convert other units to pixels on IE
    if (/^\d+(em|pt|%|ex)?$/i.test(value)) { 
      return (function(value) {
        var oldLeft = el.style.left, oldRsLeft = el.runtimeStyle.left;
        el.runtimeStyle.left = el.currentStyle.left;
        el.style.left = value || 0;
        value = el.style.pixelLeft + "px";
        el.style.left = oldLeft;
        el.runtimeStyle.left = oldRsLeft;
        return value;
      })(value);
    }
    return value;
  }
}

The above function is not perfect for some cases, for example for colors, the standard method will return colors in the rgb(...) notation, on IE they will return them as they were defined.

Check this example.

CMS
A: 

I highly recommend jQuery.

Just add jQuery to your page, then you can get and set CSS attributes dynamically and in a cross browser way (it eliminates a LOT of headaches). Here's the syntax:

/*  this outer '$(function() { innerContent });'
    is jQuery's helpful function that executes when all
    the elements in your HTML document are ready to
    be accessed (if you executed code without this,
    when you try to find the element you want to find,
    it might not have been created yet, and so your code
    will have no effect on that element)  */
$(function() {

    //  get CSS data
    var currentMinHeight = $('#idOfElement').css('min-height');
    var currentMaxHeight = $('#idOfElement').css('max-height';

    //  set CSS data
    $('#idOfElement').css('min-height', '999px');
    $('#idOfElement').css('max-height', '999px');

});

Be sure not to forget the # in front of the element's id (this is how jQuery knows you want the element that has that id)

There are ways you avoid the redundant function calls I made above and accomplish the same thing. jQuery.com will get you rolling like a cross browser pro in no time!