Open
Bug 458617
Opened 16 years ago
Updated 2 years ago
div.offsetWidth value WRONG (too small) -- causes text wrapping
Categories
(Core :: DOM: CSS Object Model, defect, P5)
Core
DOM: CSS Object Model
Tracking
()
UNCONFIRMED
People
(Reporter: bugzilla, Unassigned)
References
()
Details
(Keywords: dev-doc-needed, testcase, Whiteboard: WONTFIX?)
Attachments
(4 files)
User-Agent: Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US) AppleWebKit/525.19 (KHTML, like Gecko) Chrome/0.2.153.0 Safari/525.19
Build Identifier: Mozilla/5.0 (Macintosh; U; PPC Mac OS X 10.4; en-US; rv:1.9.0.3) Gecko/2008092414 Firefox/3.0.3
1. Use font Helvetica with size 8pt
2. fill a div with text. The div has style position = absolute
3. let w = the div's offsetWidth attribute value
4. In a second div, set its width to w
5. Fill the second div with the exact same text
6. Problem: On Firefox / Mac, the second div is not wide enough and it wraps the text
The test url shows the problem. The bug ONLY occurs on FF/Mac. No problem with FF/Win, IE6, IE7, Safari/Mac, Safari/Win, Chrome/Win
In other words: div2.style.width = div1.offsetWidth causes div2's text contents to wrap even when div1's text does not wrap. (And they both have the exact same text.)
Reproducible: Always
Steps to Reproduce:
1. See the test file http://simile-widgets.googlecode.com/svn/timeline/trunk/src/webapp/examples/test_example/firefox_mac_test_case.html
2. Appears to require combination of div having position=absolute, font=Helvetica and point size=8. The font/point size combination could simply cause the bug to be triggered with a smaller number of characters.
Actual Results:
A div with an explicit width set wraps the text. But the text should not wrap, since the same text does not wrap in the first div.
Comment 1•16 years ago
|
||
I think it makes sense that offsetWidth/offsetHeight should return
a value that is large enough to fit the content in this case.
Not sure if this is a regression or not, but it works for me
in Firefox 2.x
Component: General → DOM: Core & HTML
Keywords: testcase
OS: Mac OS X → All
Product: Firefox → Core
QA Contact: general → general
Hardware: Macintosh → All
Summary: Mac only: div.offsetWidth value WRONG (too small) -- causes text wrapping → div.offsetWidth value WRONG (too small) -- causes text wrapping
Comment 2•16 years ago
|
||
Comment 3•16 years ago
|
||
I tried the obvious, use "ceil" instead of "round" in
nsGenericHTMLElement::GetOffsetRect() and this fixed it, but it broke
a couple of the JQuery width/height tests in
dom/tests/mochitest/ajax/jquery/test/unit/core.js
This is a tough problem. Ideally Web developers would use Math.ceil(elem.getBoundingClientRect().width)...
Comment 5•16 years ago
|
||
Here's a minimized version of the JQuery test that broke.
The test makes the assumption that if you set the CSS 'width' property
to an integer value you should then have:
CSS width = offsetWidth - Math.round(border + padding)
where border and padding is calculated using
"parseFloat(computedStyle.getPropertyValue( ... ))"
The test appears to work in Opera/Safari since they round the computed
style values for border/padding.
The JQuery test suite seems to use entirely different code path for IE
(IE doesn't seem to support getComputedStyle()).
Comment 6•16 years ago
|
||
BTW, here the JQuery code in question:
http://code.google.com/p/jqueryjs/source/browse/trunk/jquery/src/core.js#802
If I follow their code correctly the elem.width() method is implemented
through css(elem, "width", true).
Reporter | ||
Comment 7•16 years ago
|
||
@Mats,
Re: regression
Yes, sorry I forgot to mention: this behavior is a change between FF2/Mac ==> FF3/Mac. In FF2 / Mac the text did not wrap.
Regards,
Larry
Comment 8•16 years ago
|
||
(In reply to comment #4)
> This is a tough problem. Ideally Web developers would use
> Math.ceil(elem.getBoundingClientRect().width)...
Yeah, I don't really see any solution to this bug without breaking
something else. Whatever we do we lose. So I think we should leave
it as is and suggest better alternatives (as you did).
Would be good to document the fact that offset* are rounded values,
and perhaps even pointing out the specific problem in this bug at MDC:
http://developer.mozilla.org/en/DOM/element.offsetWidth
Keywords: dev-doc-needed
Whiteboard: WONTFIX?
Comment 9•16 years ago
|
||
Looking at the code it seems we're rounding scroll* and client* as well,
for documentation...
http://mxr.mozilla.org/seamonkey/source/content/html/content/src/nsGenericHTMLElement.cpp#936
Reporter | ||
Comment 10•16 years ago
|
||
Hmmm, you do realize that this bug only exists in FF version, yes? And that it was introduced sometime between FF 2.0 and 3.0?
If the problem is the jquery test, why does FF / Win pass it? Or if you feel that the jquery test is faulty, can you propose how the jquery test should be improved (and then I'll be happy to submit a bug against the jquery test to them).
Thanks very much for your time and energy on this request and on FF in general. Much appreciated! Regards, Larry
Reporter | ||
Comment 11•16 years ago
|
||
Sorry, what I was trying to say was that this bug is only in FF/Mac, not in FF/Win. So any notes about it would need to be platform-specific.
I'm pretty sure that this issue is a consequence of us supporting subpixel text layout (which we introduced in Firefox 3 on Mac and Linux).
That means you might have a string whose advance width is 10.3px. So its enclosing DIV gets that width. Then its offsetWidth rounds to 10px, but if you set its width to 10px, the string doesn't completely fit anymore so we wrap.
Note that if the user has a high DPI screen or is zoomed in by say 2x, sub-CSS-pixel layout is a very good thing.
Comment 13•16 years ago
|
||
FWIW, here's a case that also breaks in Firefox 2.
Comment 14•16 years ago
|
||
The rounding of offsetWidth is exactly the same in Firefox 2:
http://bonsai.mozilla.org/cvsblame.cgi?file=/mozilla/content/html/content/src/nsGenericHTMLElement.cpp&rev=MOZILLA_1_8_BRANCH&root=/cvsroot&mark=801-804#796
http://bonsai.mozilla.org/cvsblame.cgi?file=/mozilla/xpcom/ds/nsUnitConversion.h&rev=MOZILLA_1_8_BRANCH&root=/cvsroot&mark=167#164
and it's the same for all platforms.
Comment 15•16 years ago
|
||
(In reply to comment #11)
> Sorry, what I was trying to say was that this bug is only in FF/Mac, not in
> FF/Win. So any notes about it would need to be platform-specific.
No, I don't think it's Mac-specific. Just because it happens on Mac
but not on Windows for you doesn't mean this is the case for everyone.
I'm pretty sure we can find cases that breaks on Linux and Windows too,
given the right font and screen DPI.
Windows is different from Mac and Linux because on Windows font metrics are device-pixel aligned, and on Mac and Linux, in Gecko 1.9 and later, they aren't.
But yes, if you zoom in on Windows, or use a high-DPI screen that triggers pixel scaling, you certainly could see this "bug".
Reporter | ||
Comment 17•16 years ago
|
||
I've been looking into the solution suggested above--using Math.ceil(elem.getBoundingClientRect().width) -- and it appears that:
a) Availability: For FF, the method was just introduced in ver 3. FF documentation:
http://developer.mozilla.org/En/DOM/Element.getBoundingClientRect
FF doc says that the method is "Not part of any W3C specification." But it is also in IE 5 and later. IE docs:
http://msdn.microsoft.com/en-us/library/ms536433.aspx
b) The solution from above uses the 'width' property of the returned TextRectangle Object. MS documentation does not show a width property:
http://msdn.microsoft.com/en-us/library/ms535906(VS.85).aspx
So my plan is to use
// find width
if (elem.getBoundingClientRect != null) {
var rect = elem.getBoundingClientRect();
width = Math.ceil(rect.right - rect.left);
} else {
width = elem.offsetWidth;
}
c) Additional useful comments about getBoundingClientRect
http://www.nczonline.net/blog/2008/02/04/getting-element-dimensions-a-follow-up/
The differences in the root elements' origin don't matter when calculating width and height.
Comments are appreciated.
Larry
getBoundingClientRect is actually part of the CSSOM Views spec:
http://www.w3.org/TR/cssom-view/
I've just updated our docs to mention that. (It's also supported by the latest version of Opera.)
Yeah, using right - left is the way to go. Your code looks good, hope it works for you :-)
Comment 19•6 years ago
|
||
https://bugzilla.mozilla.org/show_bug.cgi?id=1472046
Move all DOM bugs that haven’t been updated in more than 3 years and has no one currently assigned to P5.
If you have questions, please contact :mdaly.
Priority: -- → P5
Updated•4 years ago
|
Component: DOM: Core & HTML → DOM: CSS Object Model
Updated•2 years ago
|
Severity: normal → S3
You need to log in
before you can comment on or make changes to this bug.
Description
•