24

How to detect whether a DOM element is block or inline with javascript?

For example, is there a function/property which returns 'inline' for a '<a>' tag (or 'block' for a '<p>' tag)?

Thank you.

Mohsen Nosratinia
  • 9,844
  • 1
  • 27
  • 52
abernier
  • 27,030
  • 20
  • 83
  • 114
  • I'm not talking about computed style value, just the inline/block "nature" of the DOM element. – abernier May 21 '10 at 09:47
  • 1
    Do you mean how it is displayed or how it is defined in HTML? Keep in mind that there are other categories (beyond inline and block) for both and some elements (such as ``) can be different depending on the context. – Quentin May 21 '10 at 09:47

3 Answers3

34

You can go with getComputedStyle() and currentStyle to get the calculated styles for an element. This should do it:

function getDisplayType (element) {
    var cStyle = element.currentStyle || window.getComputedStyle(element, ""); 
    return cStyle.display;
}

To be a little clearer, computed styles contain values for every style property, even for those that don't have a style property set. Those values will be the default value so in the case of an unstyled <a> element, display will return inline:

function getElementDefaultDisplay(tag) {
    var cStyle,
        t = document.createElement(tag),
        gcs = "getComputedStyle" in window;

    document.body.appendChild(t);
    cStyle = (gcs ? window.getComputedStyle(t, "") : t.currentStyle).display; 
    document.body.removeChild(t);

    return cStyle;
}

Tested in latest Firefox, Chrome and IE7/IE8.

Results:

> getElementDefaultDisplay("a")
inline
> getElementDefaultDisplay("div")
block

Update: edited to give preference to standards compliance/getComputedStyle() in IE9, which supports both methods.

Andy E
  • 338,112
  • 86
  • 474
  • 445
  • 1
    Some errors that prevent this working in Firefox (untested in other browsers): `window.getComputedStyle` takes a second parameter, which can be "", and you need to get the `display` property using `cStyle.getPropertyValue("display")`. Needs some refactoring to work with the IE branch. – Tim Down May 21 '10 at 10:01
  • @Tim Down: all Firefox needed was the empty string as a second parameter: http://jsfiddle.net/fadrS/1/ – Andy E May 21 '10 at 10:10
  • 1
    Yes, my point was only about the `window.getComputedStyle` branch (therefore all other browsers). – Tim Down May 21 '10 at 10:11
  • So it does. I'm not sure whether any browser needs the `getPropertyValue()` call: no recent browser seems to, but all the references I've seen on the web use it. Btw, Safari 2 doesn't support `window.getComputedStyle`. – Tim Down May 21 '10 at 10:19
  • Apparently `null` is more standards-compliant as the second parameter to `window.getComputedStyle` rather than an empty string. – Tim Down May 21 '10 at 11:16
  • What do you do when a div has display:none ? – James Westgate May 28 '11 at 09:55
  • @James: I'm not following you, what do you mean exactly? DOM elements aren't passed to this function, it just gets the default `display` value. – Andy E May 28 '11 at 11:33
  • @Andy - In its simplest form lets say the div markup is placed on a page like this `
    ` - now you have no way of knowing whether it is block or inline ...
    – James Westgate May 29 '11 at 11:07
  • @James this function accepts a tagname and creates an element from that tagname. It can only have the default display value. – Andy E May 29 '11 at 16:54
  • 3
    @Tim: not sure if you know, but after I posted this answer I filed a bug with Mozilla regarding the second parameter. It was fixed and the parameter has been optional since Firefox 4.0. Still worth putting it in code as there could still be a few <4.0 users on the web, however. – Andy E Oct 02 '11 at 18:50
  • 4
    Nice one. According to the spec, it's always supposed to have been optional, so that's some good web citizen brownie points for you. – Tim Down Oct 02 '11 at 21:28
10

The traditional and rather ugly way of doing this is to consult a list of element names for block-level elements:

var blockRegex = /^(address|blockquote|body|center|dir|div|dl|fieldset|form|h[1-6]|hr|isindex|menu|noframes|noscript|ol|p|pre|table|ul|dd|dt|frameset|li|tbody|td|tfoot|th|thead|tr|html)$/i;

function isBlockLevel(el) {
    return blockRegex.test(el.nodeName);
}
Tim Down
  • 318,141
  • 75
  • 454
  • 536
  • would this not just retrieve the default value rather than the actual one? – War May 23 '10 at 15:28
  • 3
    Yes, it would. This isn't as good a solution as Andy E's `currentStyle` / `window.getComputedStyle` approach, but it used to have the advantage that it would work in pretty much any browser. These days with better browsers it's probably safe to use Andy E's approach. I gave this answer only as a fallback option, and I've thought about deleting it. – Tim Down May 23 '10 at 15:54
  • Downvoted for using a list instead of an object and the `in` operator. – jcayzac Oct 01 '11 at 15:06
  • 4
    @jcayzac: I agree that using an object and the `in` operator (with a `hasOwnProperty()` check) would be be slightly less code, but it would be no more correct. I tend to reserve downvotes for answers that don't work or don't answer the question, so I think yours is a little harsh, but it's your choice, and thanks for taking the time to explain. – Tim Down Oct 01 '11 at 17:21
  • @jcayzac: I changed it to a regex-based test instead. – Tim Down Oct 01 '11 at 17:33
  • @jcayzac: I agree, downvote was a little harsh. I already +1'd this a while ago, so I can't counter it now. Whilst we're on the subject though, I wrote [a blog post on list methods](http://whattheheadsaid.com/2011/09/building-and-checking-lists-in-javascript) very recently with a jsperf comparison of array, object and regex methods. – Andy E Oct 02 '11 at 18:47
  • 2
    @Andy E: Good post. I've used all three methods and am in a regex phase at the moment, but have no set favourite. It's always been an irritation that it's not simpler. – Tim Down Oct 02 '11 at 21:07
  • 1
    Removed the downvote due to Tim's change. Sorry if it seemed harsh. – jcayzac Oct 03 '11 at 15:46
2

Consider that a block element may have been added to the dom containing a class with display:none. In that case you would need to know the default for that element. The following code gets a default style setting for an element (http://jsfiddle.net/jameswestgate/qBV5c/embedded/):

function getDefaultStyle(nodeName, property) {
    var div = document.createElement('div');
    div.setAttribute('style','position:absolute; left:-9999px;');

    var el = document.createElement(nodeName);
    div.appendChild(el);
    document.body.appendChild(div);

    var result = getComputedStyle(el, null).getPropertyValue(property);
    document.body.removeChild(div); 

    return result;
}

In this case call it using the nodeName of eg p and the display property which should return block or inline

getDefaultStyle('p', 'display'); //returns block

(For IE browsers, you need to use currentStyle instead of getComputedStyle)

James Westgate
  • 11,306
  • 8
  • 61
  • 68