Search code examples
cssfont-faceinternet-explorer-11word-wrap

Text wraps outside containing element in Explorer when using @font-face and different weights


I have had a hairy bug for some weeks where text arbitrarily overflows the containing element somewhat. I'm quite sure it's not a strict css error as It's not consistent across reloads (looks fine most of the time) and as you can see in the screenshot it does wrap the text just not at the correct width.

To clarify it's an explorer only bug (IE 11 is used and we don't care about others as it's an intranet) that only happens intermittently and Chrome doesn't exhibit it at all.

It appears across a lot of elements on the page and I do suspect it's related to heavy loading and race conditions. Often it solves itself with a mouse over and if not that it solves itself when inspecting with dev tools (a lucky screenshot below).

Dev tools screenshot of problem

Things of interest: Not specific to 1 section on page site, affects headings sometimes and paragraph text others. Includes text-captions.

General css is bootstrap 3 based. Layout mostly done through -col classes.

There is some flexbox on the page (mainly in the menu. the part shown in screenshot is pure bootstrap col and row layout)

Font is open-sans loaded from own server. Font loading race is the most likely culprit. Quick test seems to look better.

hyphens: auto is used but it happens with or without that (will hyphenate bout still break the text outside the paragraph).

The screenshot shows the relevant DOM in this case I can't however really provide more specific code sample as the issue is not contained to some elements but rather happens on all sections on the site and I can't really find a common style denominator (except width constrained containers and a @font-face loaded font).

It's not easily reproducible in a smaller test case either as it triggers mostly (only?) on a loaded browser client.


Solution

  • The issue is/was caused by using @font-face declarations with same font-family and different weight/stretch/style and apparently Explorer renders the text as soon as 1 font of that family is loaded (no matter what weight/style is specified).

    It will correct the display of the text when finished loading the real font however it doesn't account for it having a different width with respect to word-wrapping and so just shortens/lengthens the existing lines.

    The fix is to either use unique font-family names for every weight/style open-sans-normal, open-sans-bold ... which will trigger rewrap on load or wait with applying the font until the're all loaded using the font-observer-api (with a polyfill since IE doesnt have it)

    Since we want to wait for all weights in this case code like the following can be used

    Promise.all([
        new FontFaceObserver('open_sans', { weight: 400 }).load(),
        new FontFaceObserver('open_sans', { weight: 600 }).load(),
        new FontFaceObserver('open_sans', { weight: 700 }).load()
    ]).then(function () { $('body').addClass('fonts-loaded') });
    

    and then of course add the font-family to body.fonts-loaded