Bug Tracker

Opened 14 years ago

Closed 14 years ago

Last modified 3 years ago

#27 closed bug (fixed)

.css() returns incorrect values

Reported by: dave.methvin@… Owned by:
Priority: undecided Milestone:
Component: ajax Version:
Keywords: css Cc:
Blocked by: Blocking:

Description (last modified by Ryan J Ollos)

The core .css() method does not return values that reflect the underlying css values for the element. The method attempts to convert many properties to raw numbers and loses the units in the process. Sample code:

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<!-- saved from url=(0014)about:internet -->
<html>
<head>
<script type="text/javascript" src="jquery-1.0a.js"></script>
<script type="text/javascript"> <!--
function test()
{
 alert(document.getElementById("qq").style.height); // "200px"
 alert(document.getElementById("qq").style.borderBottomWidth); // "2px"
 alert(document.getElementById("qq").style.borderBottomColor); // "red"
 alert($("#qq").css("borderBottomWidth")); // 2 (number without units)
 alert($("#qq").css("borderBottomColor")); // NaN

 // IE6 quirks (doctype above removed): 200 (number without units)
 // IE6 standards (doctype strict): 230 (number without units)
 // Firefox 1.5: 230 (number without units)
 alert($("#qq").css("height"));
}
// -->
</script>
</head>
<body onload="test()">
 <div id="qq" style="height:200px; border: 2px solid red; padding-top: 2em;">
 I can still hear you saying, you would never break the chain.
 </div>
</body>
</html>

In a plugin I'm building, I need to obtain the border width/color and padding for each side separately, and I pass them back in later for other elements. Because of that, I really need any value returned by .css() to be usable as an input value later, e.g., $('#div1').css('borderBottomColor', $('#div2').css('borderBottomColor')). With all the conversions going on here that's not possible.

I suggest that .css() only return the actual css attributes (including the height and width cases) and not attempt any heroics. Conversion or canonicalization should happen elsewhere, including conversion from non-pixel units to pixels, or conversion of color spaces (e.g., #ff0, #ffff00, rgb(255,255,0), rgb(100%,100%,0), rgba(255,255,0,0) are all the same thing color-wise but they have to be converted to a common format for operations like blending).

Some of these breaking changes were made recently so I doubt there's much external code that depends on it. The biggest impact I see from this change is with height and width, since several plugins seem to have made use of the fact that .css('height') returns a raw pixel number (one that isn't the css height btw). However, I'm convinced that down this path lies madness; perhaps another way to do this is with .height() and .width() methods that take all the quirks into account?

Change History (5)

comment:1 Changed 14 years ago by john

Resolution: fixed
Status: newclosed
Version: 1.0

Ok - I put a lot of work into this bug this evening, here is what I came up with:

  • I no longer do any unecessary parseFloats or parseInts - so you will always get the string representation of the style (with the exception of height/width)
  • There were a mess of bugs with height/width reporting. IE 6 in Quirks, IE 6 in Standards, Firefox, and Safari all report 200 as being the height - both when the element has a display of none and has a display of block. This was, by far, the hardest part to fix, but it was worth it.

For now, I'm not going to return the "true" height of the element, only this real pixel height, because it is terribly useful - and used by a lot of code (like the fx module, interface, and other fx plugins). I think this is a moderate concession to make, and I hope you'll agree (in favor of having accurate height reporting that works no matter what).

All of this is in SVN rev 124. Thanks for the great use-case, it certainly gave me something to do for the past couple hours ;-P

comment:2 Changed 14 years ago by dave.methvin

I think that's a good compromise, and the solution with $.swap was genius. I realize that a lot of stuff depends on height and width being returned as a raw pixel number, but it would be nice to fix it eventually. At least now I can safely throw "px" after that number and know it's right, so thanks!

comment:3 Changed 14 years ago by anonymous

Component: ajax
Priority: blocker
Resolution: invalid
Status: reopenedclosed
Type: bug

comment:4 Changed 14 years ago by john

Component: ajax
Priority: blocker
Resolution: fixed
Status: reopenedclosed
Type: bug

comment:5 Changed 3 years ago by Ryan J Ollos

Cc: &#34 &#34 removed
Description: modified (diff)
Note: See TracTickets for help on using tickets.