Closed Bug 1136818 Opened 5 years ago Closed 5 years ago

Word wrap break word doesn't work in flexbox, fieldset

Categories

(Core :: Layout, defect)

defect
Not set

Tracking

()

RESOLVED INVALID

People

(Reporter: olegbl, Unassigned)

References

(Blocks 1 open bug)

Details

Attachments

(1 file)

Attached image FireFox repro
User Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_9_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/40.0.2214.111 Safari/537.36

Steps to reproduce:

Apply word-wrap: break-word to a div and then insert a frameset or display: flex div inside of that. Finally, insert a non-breaking string that's too long to fit in container inside of that.

JSFiddle with repro: http://jsfiddle.net/6aohg6dq/


Actual results:

Framesets or divs with display: flex / display: inline-flex don't wrap properly.


Expected results:

All 6 test cases in the fiddle should wrap.
See jsfiddle in Chrome/Safari for correct behavior.
P.S. I suppose this wouldn't be a problem if word-break: break-word was supported.
So what happens here is:
 - you're getting an "anonymous flex item" that wraps the text.
 - That flex item has the (new default) "min-width:auto", and on flex items, that makes them *refuse* to shrink smaller than their min-content size -- the length of the text.

Chrome hasn't implemented "min-width:auto" yet, which is why you don't see this behavior there.

To work around this & allow the flex item to shrink, you need to do two things:
 (1) Put the raw text inside of an *explicit flex item* (e.g. a <div>), rather than putting it directly inside of the flex container -- so that you can style it. (You can't style an anonymous flex item.)
 (2) Style that flex item with "min-width:0".

(This fixes your "display:flex" example, but you'll still see overflow in "inline-flex", for the same reason that you see it with "inline-block" -- an inline-level element's auto-width isn't sized to its container. If you want your "inline-flex" version to work, you'll need to give the "inline-flex" element an explicit width, I think.)

I'm resolving this as INVALID since we're following the spec here. Hopefully the above makes sense.
Status: UNCONFIRMED → RESOLVED
Closed: 5 years ago
Resolution: --- → INVALID
That resolves why the flex breaks.
However, that says nothing about why the fieldset breaks.
Here's the jsfiddle with the flexbox stuff fixed per comment 2:
 http://jsfiddle.net/6aohg6dq/2/
(and with an auto-width "inline-block" for comparison with your auto-width "inline-flex")

As for fieldset: Chrome agrees with us on the rendering, if you remove the (nonstandard & unsupported-in-firefox) "word-break: break-word".

So it doesn't look like we're disagreeing with Chrome there, aside from the fact that we don't support "word-break:break-word".
Component: Untriaged → Layout
OS: Mac OS X → All
Product: Firefox → Core
Hardware: x86 → All
Summary: Word wrap break word doesn't work in flexbox, frameset → Word wrap break word doesn't work in flexbox, fieldset
Version: 36 Branch → Trunk
So, given that Firefox doesn't support word-break: break-word (why btw? it's supported in chrome, safari, etc...), how would one make break-word work inside a fieldset? That seems very much a bug if that's impossible to do.
Here's a fiddle demonstrating the fieldset scenario a little better, as compared to a simple wrapper-block (without any "word-wrap"/"word-break" -- just seeing how things are sized):
  http://jsfiddle.net/6aohg6dq/5/

Firefox & Chrome agree that the wrapper-block (the lime border) does *not* grow to accomodate its contents' min-content width, whereas the fieldset (red border) *does* grow.

So, stuff overflows from the wrapper-block, which is what triggers it to wrap when you provide "word-wrap". But in the fieldset case, nothing is overflowing *from the fieldset* (since it's sized to its contents' min-content width) which is why we don't have any breaks there.

In your original testcase, if you use "word-break: break-word" in Chrome (or if you add "word-break: break-all" to do something somewhat-similar in Firefox), then that tells the content that it can break more eagerly, which reduces its min-content width -- so the fieldset is shrinkwrapping something with a smaller min-content width and ends up smaller, which means we get a break opportunity.

Anyway, hopefully that makes things a bit clearer. Bottom-line, the reason Firefox differs from Chrome on the fieldset examples is that we don't support the non-standard value "word-break:break-word".

(In reply to olegbl from comment #5)
> So, given that Firefox doesn't support word-break: break-word (why btw? it's
> supported in chrome, safari, etc...)

"etc..." is "nothing", I think. I don't know a lot about "word-break:break-word", but as I recall, it's a webkit-only extension (which Blink got via forking webkit), and it's not part of the standard. I'm not entirely sure why or what the history is there.

> how would one make break-word work
> inside a fieldset? That seems very much a bug if that's impossible to do.

You can use "word-break:break-all" to do something similar, though I'm not sure if that does quite what you want.
(break-all probably isn't *really* what you want, since IIRC it also lets you break at places that are silly like in the middle of short words.)

RE "how would one make break-word work inside a fieldset" -- you can also put the fieldset's contents inside of a wrapper-block, and limit the width of that block (e.g. with an explicit "width: 300px", in your testcase)

I'm not sure if it's possible to do what you want without a fixed-size wrapper inside the fieldset, due to how fieldsets shrinkwrap their contents.
Appreciate the clarification! Using word-break: break-all is exactly what I've been doing for a while now and is what I'm trying to solve (need actual word breaking). I suppose I'll just implement fieldsets as divs rather than using the native element (fixed width not an option for me).

As an aside, having "word-break: break-all" but "word-wrap: break-word" definitely feels way hackier than two values on one property - so perhaps the standard is out of date here and should be revised.
(In reply to Daniel Holbert [:dholbert] from comment #2)
> [...]
> To work around this & allow the flex item to shrink, you need to do two
> things:
>  (1) Put the raw text inside of an *explicit flex item* (e.g. a <div>),
> rather than putting it directly inside of the flex container -- so that you
> can style it. (You can't style an anonymous flex item.)
>  (2) Style that flex item with "min-width:0".
> [...]

Suggestion 1 does not work! I've my raw text inside an explicit flex item and the text does not wrap. I thought this would demonstrate it: http://codepen.io/anon/pen/ZGQMOp?editors=110

It want a container which width is relative to the viewport and inside that container one div which width is set and another div (the *fill div*) which width should fill out the remaining width. If a word is to long for the fill div, then it should be broken with a new line. But this doesn't happen in Firefox. The ways to come around this, that I know of, is the suggested "min-width: 0" and "word-break: break-all", but if word-wrap doesn't wrap text just because it is in a flex item, I think that is a bug.
(In reply to olov.gunther-hanssen from comment #9)
> Suggestion 1 does not work! I've my raw text inside an explicit flex item
> and the text does not wrap. I thought this would demonstrate it:
> http://codepen.io/anon/pen/ZGQMOp?editors=110

You missed step (2): add "min-width:0" to the flex item.

Codepen with that fixed: http://codepen.io/anon/pen/gpPBow

> The ways to come around this, that I know of
> is the suggested "min-width: 0" and "word-break: break-all"

Right.

> but if word-wrap doesn't wrap text just
> because it is in a flex item, I think that is a bug.

You're misunderstanding what's going on.  It's not that "word-wrap doesn't wrap text" -- it would be happy to wrap the text, but it doesn't *need* to in your codepen, because there's enough space so that no wrapping needs to happen! (The yellow area is large enough so that text doesn't need to wrap. It's larger than *you* want it to be, sure, but it's large enough that text doesn't need to wrap.)

To prevent it from being that large (sized based on its content), you need to give it "min-width:0".  Otherwise the flexbox default min-sizing behavior will clamp it to the content's minimum intrinsic width, which is the length of the longest word, which is huge in your case.
This may help clarify the "word-wrap doesn't wrap text just because it is in a flex item" issue -- consider this jsfiddle, which uses a float instead of a flex container.
 http://jsfiddle.net/spkmgbvv/

In both Firefox & Chrome, the text doesn't wrap mid-word -- seemingly "just because it's a float". (If you remove the float declaration, it wraps as you'd like it to.)

This isn't a bug with float layout -- it's due to how floats are sized. Their sizing *depends on the intrinsic size of the float's content*, by default -- and this may lead to the float overflowing its viewport (as it does in this instance).  Then, the float's text ends up seeing that it's got enough space, and it doesn't end up *needing* to wrap in the middle of a word.

Similarly: a flex item's size *depends on the intrinsic size of its content*.  (In a slightly different way, via "min-width:auto" behavior as compared to a float's "width:auto" behavior -- but it's similar.)  So the text ends up getting enough space and not needing to wrap.  If you don't like that dependence, you can disable the intrinsic size dependence by giving it "min-width:0", and then the text will have a smaller amount of space and will dutifully wrap.
Whats the situation on this bug? 

I experience it in a complex multilingual web interface. We have word-wrap: break-word; set globally in order to break all the long words in the interface (for example German compound words). In Firefox (most recent version). Because of Firefox's weird behaviour I have to use the min-width: 0; workaround a lot.
(In reply to Felix Niklas from comment #12)
> Whats the situation on this bug? 

The bug is RESOLVED INVALID because it's not a Firefox bug. :)

> Because of Firefox's weird behaviour I have to use the min-width:
> 0; workaround a lot.

Firefox's "weird behavior" on this is required by the spec. Chrome has it implemented in their "dev channel" edition, too, and Microsoft has it in "Edge", their next-gen browser.

If you notice us differing from those versions in some way, please do file a bug.
Personally, I was stumped when I found out that the <br> tag, used for ages suddenly does not wrap text anymore... feels like a bug to me since all other browsers still implement it as expected.
@da.grit: this bug report had nothing to do with <br>.

If you're seeing an issue/incompatibility there, please file a new bug at https://bugzilla.mozilla.org/enter_bug.cgi?product=Core&component=Layout , and be sure to include a testcase (or a link to some external site) where Firefox differs from other browsers.
You need to log in before you can comment on or make changes to this bug.