Skip to main content

Bug Tracker

Side navigation

#14038 closed bug (migrated)

Opened June 19, 2013 12:05AM UTC

Closed October 16, 2014 06:15PM UTC

.width(value) sets incorrect width value if block has border and value specified in ems and box-sizing:border-box

Reported by: tde@welldocs.com Owned by: timmywil
Priority: high Milestone: 1.12/2.2
Component: css Version: 2.0.1
Keywords: Cc:
Blocked by: Blocking:
Description

API documentation specifies:

"Note that .width("value") sets the content width of the box regardless of the value of the CSS box-sizing property."

There are two key factors leading to this bug

1. "box-sizing:border-box"

2. "border:1px solid black"

3. width specified in ems

Code that reproduces this bug

<html>
	<head>
		<style>
			#container {width:100%;}
			#box {border:1px solid black; margin:0 auto; box-sizing:border-box;}
		</style>
		<script type="text/javascript" src="http://code.jquery.com/jquery-2.0.1.js"></script>
		<script>
			var $ = jQuery.noConflict();
			$(document).ready(function() {
				$('#box').width('10em'); // width should be 10em, but jquery set it to 12em
			});
		</script>
	</head>
	<body>
		<div id="container">
			<div id="box">
				<p>some text</p>
			</div>
		</div>
	</body>
</html>
Attachments (0)
Change History (15)

Changed June 19, 2013 12:17AM UTC by tde@welldocs.com comment:1

Same behavior with JQuery 2.0.2

Changed June 23, 2013 04:05PM UTC by dmethvin comment:2

Hi, can you convert your example inline here to an example on jsfiddle.net?

Changed June 24, 2013 04:18PM UTC by m_gol comment:3

owner: → tde@welldocs.com
status: newpending

Changed June 24, 2013 04:45PM UTC by tde@welldocs.com comment:4

status: pendingnew

Changed June 27, 2013 02:30AM UTC by timmywil comment:5

resolution: → notabug
status: newclosed

Respecting border-box is outside the scope of width, due to the fact that we have specific methods that account for padding, margin, and border (innerWidth/outerWidth(true|false)/width). However, you can use .css('width') instead: http://jsfiddle.net/timmywil/JqmQ6/3/

Changed June 27, 2013 03:26AM UTC by anonymous comment:6

Replying to [comment:5 timmywil]:

Respecting border-box is outside the scope of width, due to the fact that we have specific methods that account for padding, margin, and border (innerWidth/outerWidth(true|false)/width). However, you can use .css('width') instead: http://jsfiddle.net/timmywil/JqmQ6/3/

Clearly a bug.

You just provided workaround.

But If I want block .with('10em) - it should be 10em, not 12em (if border is 1px) and not 14em (if border is 2px) and not 16em (if border is 3px) etc. Open your mind and reconsider this shit.

Documentation clearly states - "Note that .width("value") sets the content width of the box regardless of the value of the CSS box-sizing property."

Changed June 27, 2013 04:27AM UTC by timmywil comment:7

resolution: notabug
status: closedreopened

Valid. The documentation you quote is the point I was making. Nevertheless, this seems to be an edge case caused by combining a non-px like em with border-box.

Changed June 27, 2013 04:29AM UTC by timmywil comment:8

component: unfiledcss
milestone: None1.11/2.1
owner: tde@welldocs.comtimmywil
priority: undecidedhigh
status: reopenedassigned

Changed June 27, 2013 03:45PM UTC by timmywil comment:9

So, afaict, there are two routes we can take.

1. If the unit is not pixels, skip width/height augmentation completely. This is historically how we've dealt with most problems involving non-px units (with some exceptions). This also has the advantage of being a small fix.

2. We could do something similar to the main tween and convert all necessary values to the set unit. This is more accurate, but could get very expensive as it could potentially require a loop for width, border, margin, and padding in order to unify the units for value adjustment each time width is set (imagine animating width).

Thoughts?

Changed June 27, 2013 04:39PM UTC by gibson042 comment:10

I'm in favor of exploring the size and performance impact of option 2, but it may take a while to do so. A stopgap in the meantime might be reasonable, but option 1 seems like overkill.

Changed June 27, 2013 05:41PM UTC by timmywil comment:11

Perhaps we could ensure the units are the same before the setPositiveNumber call. If they're not, set the value as-is.

Changed January 28, 2014 09:41PM UTC by Joshua Tausz comment:12

I discovered a similar case which expands the scope of this bug, using jquery 1.10.2, and Chrome 29, on Windows 7 Enterprise.

This bug occurs with other types of unit miss-match.

In the example provided with the initial report, set a width of 50%, and padding px of 10, and no border. This will result in a width of 70%, very different behavior from expected.

Setting a padding of 2em returns a width of 74%. This which would seem to indicate that 1em is translated to 12px before adding those 12px to the width as 12% each.

I was able to use Chrome's built-in debugger to trace through some of the code.

In file jqery-1.10.js, the function agumentWidthOrHeight, returns -20, to reflect that padding is set to 10px on either side, but there is no unit attached.

Specifically, this occurs on line 7201.

val -= jQuery.css(elem, "padding" + cssExpand [ i ], true, styles);

This is already part of a loop used to add the various values together, so type checking/conversion could be handled inside this existing loop, if the coder were to go with comment:9's option 2.

This value of -20 is used in function setPositiveNumber, under the value "subtract", on line 7179:

Math.max( 0, matches[ 1 ] - ( subtract || 0 )  ) + matches [ 2 ] || "px" )

I suggest using type conversion, and transmitting the type with the value reported from function agumentWidthOrHeight, so that type conversion can be done on or before line 7179.

With the additional style miss-matches, which can cause further issues, I suggest that this is no longer as much of an edge-case.

Changed March 03, 2014 05:46PM UTC by dmethvin comment:13

milestone: 1.11/2.11.11.1/2.1.1

Changed March 17, 2014 04:17PM UTC by timmywil comment:14

milestone: 1.11.1/2.1.11.12/2.2

Changed October 16, 2014 06:15PM UTC by m_gol comment:15

resolution: → migrated
status: assignedclosed