59

I'm using jQuery (v1.7.1) and I need to get the absolute, floating-point width of an element, but all of jQuery's width methods seem to be rounding-off the value of the width.

For example if the actual width of an element was 20.333333px, jQuery's width method returns 20, i.e ignoring the decimal value.

You can see what I mean on this jsFiddle

So, my question is: How do I get the floating-point value of the width of an element?

S P
  • 1,801
  • 6
  • 32
  • 55
  • 2
    possible duplicate of [Do not round .width() in jQuery](http://stackoverflow.com/questions/3603065/do-not-round-width-in-jquery) – John Koerner Aug 10 '12 at 18:48
  • 1
    Might want to check here: http://stackoverflow.com/questions/4308989/are-the-decimal-places-in-a-css-width-respected Seems the browser truncates the pixels, so it's probably not an issue with your jquery. – Michael Peterson Aug 10 '12 at 18:52
  • jquery width function always return int value hence you will never get a float value. see - http://api.jquery.com/width/ – Bhushan Kawadkar Aug 10 '12 at 19:01
  • Thank you @JohnKoerner, I couldn't find that question before, but I am still wondering if there could be any possible solution to this? Some way to retrieve the floating-point width of an element, since the CSS property does seem to be holding it (At-least when I inspect with Chrome's console) – S P Aug 10 '12 at 19:05
  • @MichaelPeterson, thank you, http://jsfiddle.net/q5BQs/3/ pretty much shows that the decimal values are completely ignored when rendering the elements, although those values are retained on Chrome's console. – S P Aug 10 '12 at 19:12
  • 2
    When something is displayed, it can ONLY be displayed on a whole pixel boundary. There is no such thing as a half pixel width. – jfriend00 Aug 10 '12 at 19:13

2 Answers2

95

If you already have a reference to the DOM element, element.getBoundingClientRect will get you the values you want.

The method has existed since Internet Explorer 4, and so it's safe to use everywhere. However, the width and height attributes exist only in IE9+. You have to calculate them if you support IE8 and below:

var rect = $("#a")[0].getBoundingClientRect();

var width;
if (rect.width) {
  // `width` is available for IE9+
  width = rect.width;
} else {
  // Calculate width for IE8 and below
  width = rect.right - rect.left;
}

getBoundingClientRect is 70% faster than window.getComputedStyle in Chrome 28, and the differences are greater in Firefox: http://jsperf.com/getcomputedstyle-vs-getboundingclientrect

Ross Allen
  • 43,772
  • 14
  • 97
  • 95
  • 3
    According to Mozilla Network Developer : getBoundingClientRect() was introduced since ie4 but `width` and `height` properties were only introduced on ie9. So for ie8 you have to compute it `top - bottom` and `right - left`. Nothing important just to be completely accurate. – Ghetolay Mar 04 '15 at 11:14
  • 1
    @Ghetolay, I hadn't realized that; thanks for pointing it out. I'll add clarification to my answer. – Ross Allen Mar 04 '15 at 12:50
  • 2
    This doesn't actually work for ie9. In ie9 getBoundingClientRect returns rounded values, rather than the floating point width the asker wanted. The only way to get an accurate value in ie9 is using getComputedStyle. https://jsfiddle.net/JoolsCaesar/z6bx2moh/ – Jools Jan 13 '16 at 16:52
  • @Ghetolay - minor correction, it should be `bottom - top` for height else you'll end up with a negative number. – But those new buttons though.. Jul 13 '16 at 16:46
  • @jools Can you have a look to this updated Fiddle and help me if you know how to do this ? thx. https://jsfiddle.net/z6bx2moh/18/ I am trying to get the floating-point width of an element with dynamic width and that is overflowed... – M'sieur Toph' Oct 21 '16 at 01:20
  • @M'sieurToph' `#inner` needs to be `display:inline` or `display:inline-block`. If you can't change that, you'll need to add another wrapper div, inside `#inner` and around your items, which has one of those `display` values. https://jsfiddle.net/JoolsCaesar/z6bx2moh/21/ – Jools Oct 22 '16 at 09:36
16

Try this:

var element = document.getElementById("a");
alert(window.getComputedStyle(element).width);

Updated fiddle: http://jsfiddle.net/johnkoer/Z2MBj/18/

John Koerner
  • 37,428
  • 8
  • 84
  • 134
  • Yes, I see, the computed width is rounded (http://jsfiddle.net/Z2MBj/19/ at-least on Chrome). http://jsfiddle.net/q5BQs/3/ shows that more visually. – S P Aug 10 '12 at 19:19
  • 6
    `getBoundingClientRect` is up to 70% faster than `getComputedStyle` and provides the same dimensions: http://jsperf.com/getcomputedstyle-vs-getboundingclientrect – Ross Allen Aug 22 '13 at 16:45
  • 5
    To add to @ssorallen's comment, `getComputedStyle` returns a string where as `getBoundingClientRect` returns a float. – iheartcsharp Aug 18 '14 at 17:45
  • 7
    `getBoundingClientRect` does not return the same value as `getComputedStyle`, if the element is affected by any CSS transformations then `getBoundingClientRect` will return the transformed value. – leafo Apr 30 '15 at 10:51
  • 2
    In IE9 `getBoundingClientRect` returns rounded values and `getComputedStyle` returns the floating point values (once passed through `parseFloat`) to get rid of the "px". jsfiddle.net/JoolsCaesar/z6bx2moh – Jools Jan 13 '16 at 16:59
  • 2
    for what it's worth, I just ran a few benchmarks in chrome and `getComputedStyle()` was faster than `getBoundingClientRect()` – But those new buttons though.. Jul 13 '16 at 17:09