13

Alright, I've search the jQuery docs (needs somebody devoted to maintaining), I've searched SO, and I've searched Google. I can't find the answer to this question.


In Words

In the past, I remember jQuery working like this:

$('#myObj').width() returns the computed width of #myObj.
$('#myObj').css('width') returns the width as it is entered into the CSS stylesheet.

Now, any jQuery package I use returns the exact same number no matter which method I use.

$('#myObj').width() returns the computed width of #myObj as an integer (float?).
$('#myObj').css('width') returns the computed width of #myObj as a string with px on the end.


In Pseudocode

#myobject{
    width: 14em;
    height: 14em;
}

<div id="myobject">Has Text</div>

<script type="text/javascript">
    $( '#myobject' ).click(function(){
        alert($(this).css('width') + "\n" + $(this).width());
    });
</script>

//Always alerts "224px [newline] 224"
//Expected to alert "14em [newline] 224"

These pixel-based return values are almost completely useless, as I need to do calculations based on what's actually in the CSS. For example, I want to do math on the left position of an element, but I can't because it keeps returning pixel values, which are worthless in an em-based design.

Is there any way to get the actual values out of the CSS in jQuery?
Is this a jQuery bug, or am I missing something?

Here's a jsfiddle: http://jsfiddle.net/yAnFL/1/.


Resolution

Apparently, this is the intended result.
I have decided to use this plugin to do conversions for me.
Taking away control of CSS seems like a poor choice in the jQuery design.

rockerest
  • 10,412
  • 3
  • 37
  • 67

7 Answers7

3

This is not a complete answer to your question but it may be a working solution to caclulate the em values. I adapted this function from here. And here is the updated fiddle.

$.fn.emWidth = function(){
    var wpx = this.width();
    var temp = $('<div />').css({
        width:'1em', 
        position: 'absolute'
    });
    this.append(temp);
    var oneEm = temp.width();
    temp.remove();
    var value = wpx/oneEm;
    return Math.round(value*100)/100;
};
Josiah Ruddell
  • 29,697
  • 8
  • 65
  • 67
  • I'm giving you the answer because the plugin I used is essentially the same thing, just more generic. Thanks! – rockerest Mar 29 '11 at 17:20
2

In the jQuery manual it is stated:

The difference between .css(width) and .width() is that the latter returns a unit-less pixel value (for example, 400) while the former returns a value with units intact (for example, 400px).

Seems like the behaviour of .css() was changed in version 1.3, or at least it seems like that from the bug tracker.

I was trying to find a good (not hacky) solution also, but I haven't been able yet.

Also on SO.

Community
  • 1
  • 1
kapa
  • 77,694
  • 21
  • 158
  • 175
  • Thx, but it still does not fulfill my `not hacky` requirement :). Will update here if I run into something. – kapa Mar 30 '11 at 10:22
2

As some others have stated, jQuery now uses hooks to intercept evaluation of some css properties. Here is a general solution that lets you get css and bypass those hooks.

$.fn.hooklessCSS = function(name) {
    var hooks = $.cssHooks;
    $.cssHooks = {};
    var ret = $(this).css(name);
    $.cssHooks = hooks;
    return ret;
}
Conley Owens
  • 8,691
  • 5
  • 30
  • 43
  • Beautiful… Thanks, this worked exactly as I needed it to. I needed to get the CSS properties as percentages, and this worked a charm. – thirdender Sep 22 '12 at 05:05
0

This is indeed an issue in newer versions of jQuery. If this is an important feature for you, you can try downgrading to 1.4.2 where it is still working properly.

Source: Comments at http://api.jquery.com/css/

tvkanters
  • 3,519
  • 4
  • 29
  • 45
  • When I select jQuery 1.4.2 on my jsfiddle, it still reports the same values. Perhaps jsfiddle isn't loading libraries correctly? – rockerest Mar 29 '11 at 16:48
  • Hmm, I just tried it and even with older versions than 1.4.2 it's still wrong. Either the comments are wrong or it's a problem with jsFiddle. You could try to make a real project with jQuery 1.4.2 or even 1.3.2 and see if that works any better. You can find older version easily on http://code.google.com/apis/libraries/devguide.html#jquery – tvkanters Mar 29 '11 at 16:53
  • 1
    It seems to work in the old version only if you get the `.css('width')` value and define the width inline like `
    `
    – JustinStolle Mar 29 '11 at 17:10
0

jQuery always* returns dimensions such as width in units of pixels. Perhaps you can borrow the code from this px to em conversion tool to help you get the value you want.

It looks like 1.4.2 is the most recent version that will still return $(this).css('width') in its assigned unit of measure, but seemingly only if the width is assigned in the style attribute of the element's tag. If it's in a separate CSS declaration like your example, it comes back as pixels still.

$(this).width() remains to be in pixels.

(*in versions 1.4.3 and later)

JustinStolle
  • 4,182
  • 3
  • 37
  • 48
0

jQuery now uses a cssHooks feature for certain .css() requests, width and height in particular.

So the width() function and the .css('width') both run through the same code on occasion.

Orbling
  • 20,413
  • 3
  • 53
  • 64
0

if you define the style inline then you can use document.getElementById("myObj").style.width to retrieve the value as it is defined in the inline style

http://jsfiddle.net/yAnFL/14/

I'm not sure how to grab the value from an external sheet though.

Andbdrew
  • 11,788
  • 4
  • 33
  • 37