17

I seem to have stumbled onto a bug in IE where the scrollWidth is off by 1px compared to the offsetWidth. The trigger to this seems to be dependent on the length of the text/characters in the element and only happens when overflow is set to something other than visible.

For context on why I am checking them against each other see this question: HTML - how can I show tooltip ONLY when ellipsis is activated

For an example of the issue see: http://jsfiddle.net/w5cwhjbf/2/

.base{ font-size: 16px; overflow: hidden; } .wrapper{ float: left; }
<div class="wrapper"> <div id="div1" class="base"> Why is my scrollWidth wrong in IE? </div> </div> <br style="clear: both;"> <br> <button id="btn1" onclick="fnCheckScroll(div1,btn1)">Calculates Wrong</button> <br> <br> <br> <div class="wrapper"> <div id="div2" class="base"> Why is my scrollWidth right in IE? </div> </div> <br style="clear: both;"> <br> <button id="btn2" onclick="fnCheckScroll(div2,btn2)">Calculates Correctly</button> <br> <br> <br> Issue seems to be based on the character widths/font size resulting in I would assume a fractional value that in one case gets rounded up and the other rounded down. The issue however does not ever cause scroll bars to appear (if overflow is auto). Issue doesnt happen with overflow: visible. <script type="text/javascript"> function fnCheckScroll(div, btn) { var iScrollWidth = div.scrollWidth; var iOffsetWidth = div.offsetWidth; var iDifference = iScrollWidth - iOffsetWidth; btn.innerHTML = ("Width: " + iOffsetWidth + "px | scrollWidth: " + iScrollWidth + "px | Difference: " + iDifference + "px"); } </script>

You will notice in the example, though the first item has room to grow to whatever size it wants, its width is set 1px too short, or the scrollWidth reported is 1px too big, as well as the fact that no scrollbar is thrown (when CSS explicitly set to overflow: auto), IE knows somewhere in its code it is not actually overflowing.

Question is, what would be your suggested fix or workaround for this issue, as it seems like it randomly happens based on the characters/font/font-size in the div?

7
  • Hey, have you come across a good workaround for this? Commented Feb 14, 2017 at 10:41
  • 1
    Sadly no, we had to put in the 1px grace in the javascript check for the IE versions effected and deal with the occasional issue where the tooltip didnt show up due to the miscalculation. Commented Feb 27, 2017 at 18:49
  • yeah, did the same.. sucks Commented Feb 27, 2017 at 19:11
  • Update: Logged a bug on Edge, and Microsoft has already fixed it, so this should be a non issue soon for that browser however you will still see the issue in IE: developer.microsoft.com/en-us/microsoft-edge/platform/issues/… Commented Apr 19, 2017 at 20:30
  • Anyone has good workaround other than the above? Commented Oct 30, 2017 at 17:25

3 Answers 3

2

It's hard to give the best solution without knowing how this applies to your specific problem with this bug. That being said, you could:

  • Use a javascript bug-fix to adjust the attributes/styles/etc. if the two elements are different sizes.

    if(iDifference != 0) { /* make adjustments. */ }

  • Use a tolerance check between the two elements; if the difference is less than or equal to 2px, then don't worry about it and process everything as normal.

    if(Math.abs(iDifference) <= 2) { /* no problem here! */ }

  • Use the outer element for all computations, since that has the true width of the container.

  • Use the inner element for all computations, since that will never cause an overlap with the outer element.

  • Do nothing! Why fix it if it isn't broken?

It all depends on what you're trying to do and how the 1px gap is causing a problem.

Sign up to request clarification or add additional context in comments.

6 Comments

Siphon, I see I forgot to include the link to the specific use case of why I am using the check. It is now included above.
Then I would suggest you use the inner container width. You might even want to trim a few pixels off the width for some padding, if needed. Worrying about 1 px seems like a trivial thing to worry about if you use 5px to 20px for padding.
Siphon, per the use case, we are using the calculation to determine if the text-overflow: ellipsis is happening. (it only triggers in the same cases a scrollbar shows up). In this case, in IE due to this issue you cannot tell the difference between it is 1px overflowing and has the ellipsis, vs it is reporting 1px off but isnt overflowing and doesnt need the tooltip. By ignoring the issue, you get a tooltip all the time. By giving a 1px grace to the calculation, you get situations where the text is cutoff (ellipsis) but no tooltip with full text is shown. In either case the UX suffers.
Would you benefit from using a fixed table layout (check out table-layout: fixed; in relation with text-overflow: ellipsis)? It sounds like using a CSS solution would solve a lot of your problems. Check out: stackoverflow.com/questions/10209831/…
No, table-layout: fixed wouldn't solve the issue, as the whole point is to have Divs (or other elements) that are dynamically sized/resized based on the window. As they resize, text may now overflow (causing an ellipsis). Dynamically adding a tooltip allows a way for user to see full text, even when viewing at smaller window sizes. Using the mouseenter + javascript calculation keeps everything light and keeps it from overloading the browser. The linked suggestion has the issue that you must transfer all inherited CSS correctly, which can be extremely difficult and not as light as srollWidth
|
2

Found a workable workaround for the issue that would work in ie9+. Requires checking the elements getBoundingClientRect() width in addition to the scroll and offset width.

var boundingClientRectWidth = element.getBoundingClientRect().width; var iScrollWidth = div.scrollWidth; var iOffsetWidth = div.offsetWidth; var amIOverflowing = (iScrollWidth > iOffsetWidth) && (boundingClientRectWidth == iOffsetWidth); 

By check in IE if the boundingClient is forced to be the same size as the iOffsetWidth (instead of having a fractional width) we can ensure that we don't use the incorrect scroll width that is rounding up instead of down e.g. 273.36...

See this jsfiddle: http://jsfiddle.net/gskfke6L/1/

Comments

1

Try to set the padding-right: 1px; for the class .base.

.base{ font-size: 16px; overflow: hidden; padding-right: 1px; } 

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.