2

I have two flex children. I don't know the size of those children, but I want the .right (which contains unknown, but finite number of e.g. status icons) to not break, and fit on line, while .left child (which contains label of potentially too-long text) to break so that the .right child fits.

In the snippet, the .left should break the text so that the .right fits. Neither of the two children should overflow the .container.

I'm able to accomplish this by using word-break: break-word on .left, but that's non-standard. I can also use word-break: break-all, but that doesn't try to wrap the word on next line (as word-wrap does), first, which is undesirable. word-wrap: break-word doesn't do anything.

As stated, I cannot use width: calc( 100% - <right-width> ) on .left, because I don't know width of .right child.

note: the children's height: 20px is just to see the parent container. It's not part of the requirement.

Bonus: in the example the width of .container is known, but it may potentially not be known, either (i.e. it may inherit it in some way).

.container {
  display: flex;
  width: 200px;
  height: 40px;
  background: pink; 
}

.left {
  background: rgba(0,255,0,.1);
  height: 20px;
  
  // word-break: break-word; // works in WebKit, but non-standard
  word-wrap: break-word;
}

.right {
  background: rgba(0,0,255,.1);
  height: 20px;
}
  
<div class="container">
  <div class="left">xoxoxoxoxoxoxoxoxoxoxoxoxoxoxox</div>
  <div class="right">rarararara</div>
</div>
dwelle
  • 6,894
  • 2
  • 46
  • 70
  • something like this? https://jsfiddle.net/g6gyf2cq/4/ – Michael Benjamin Mar 11 '18 at 22:23
  • I'm a little confused as to what the difference is for you between using `word-break: break-all` and `word-break: break-word`. Both seem to have the desired effect for me. Also, I fail to see why it being non-standard is a concern, considering it actually has **better** support than flexbox itself... – Obsidian Age Mar 11 '18 at 22:24
  • @Michael_B I want the `.left` text to wrap instead of ellipsis. @ObsidianAge `word-break: break-word` is [not implemented](https://developer.mozilla.org/en-US/docs/Web/CSS/word-break) **at all** in FF and Edge, and `word-break: break-all` has minor, but significant (and undesirable) different behavior ([see the docs](https://developer.mozilla.org/en-US/docs/Web/CSS/word-break)) – dwelle Mar 11 '18 at 22:30
  • Yup, I understand. It was an option I put out there for a potential simple solution. – Michael Benjamin Mar 11 '18 at 22:31

1 Answers1

2
  • the min-width: 0 on left ensures the element doesn't auto-resize to the parent flex container, and wraps as needed. It can be substituted with overflow: hidden, which has same effect.

    If left to auto (default min-width flex value), it would overflow the container if it got too big. (thanks @Michael_B)

  • flex: 1 (shorthand for flex: 1 0 0, or flex-grow: 1; flex-shrink: 0; flex-basis: 0) ensures the left grows and pushes the right element to the right (thanks @LGSon)
  • right has initial flex values (flex: 0 1 auto) which ensures it doesn't word-break and doesn't grow above its content size, either.

    WTBS, if it gets too big, it will also need word-wrap: break-word; min-width: 0 same as left.

Note: removed the 20px height which was not part of the OP requirement.

.container {
  display: flex;
  width: 200px;
  background: pink; 
}

.left {
  background: rgba(0,255,0,.1);
  word-wrap: break-word;  
  min-width: 0;
  flex: 1;
}

.right {
  background: rgba(0,0,255,.1);
}
<div class="container">
  <div class="left">aaaaaaaa bbbbbbbbbbbbbbbbbbbb</div>
  <div class="right">cccccc ccccc</div>
</div>
dwelle
  • 6,894
  • 2
  • 46
  • 70
  • ah, the min-width that make sense :) i forget about it ... as the flexbox apply a value to it .. but since @Michael_B didn't provide a solution i thought it won't be direct and easy :p – Temani Afif Mar 11 '18 at 23:10
  • also no need flex:none ... the min-width is enogh ;) – Temani Afif Mar 11 '18 at 23:11
  • here is for more information https://stackoverflow.com/a/36247448/8620333 – Temani Afif Mar 11 '18 at 23:21
  • If you want to make IE11 play along, it needs `word-break` ... and can be added like this to not mess with the rest of the browsers: https://jsfiddle.net/02zxppn2/ – Asons Mar 12 '18 at 06:39
  • 1
    If you can use `flex: 1` on `left`, which will always push the `right` to the right side no matter content width in `left`, you can drop `word-break`, as that will work in IE11 too: https://jsfiddle.net/02zxppn2/2/ – Asons Mar 12 '18 at 07:02
  • thanks... updated answer to reflect your points – dwelle Mar 12 '18 at 09:28