2

I have 2 flexboxes and a flexbox inside one. I want the text to break into multiple lines if it is bigger than it's parent. For some reason it works if I sent a fixed value (e.g. 250px) as width. If I set the width to 100%, it will not break into multiple lines.

This is the code I have:

#flexparent {
  display: flex
}

#flexchild1 {
  flex: 1;
  background-color: green;
}

#flexchild2 {
  flex: 1;
  background-color: red;
  display: flex;
  flex-flow: column
}

#flexchild3 {
  background-color: purple;
  width: 100%;
  word-wrap: break-word;
}
<div id="flexparent">
      <div id="flexchild1">
        FLEXCHILD1
      </div>
      <div id="flexchild2">
        FLEXCHILD2
        <div id="flexchild3">
 ThisisasuperlongsentenceLoremipsumdolorsitametconsecteturadipisicingelitAsperioresnecessitatibusneueodioImpeditistenesciuntescorruptiessecumrepudiandaequidolorumIllumtemporibusquoerrorcumqueeximpeditmagnamLoremipsumdolorsitametconsecteturadipisicingelitAsperioresnecessitatibusneueodioImpeditistenesciuntescorruptiessecumrepudiandaequidolorumIllumtemporibusquoerrorcumqueeximpeditmagnamtstLoremipsumdolorsitametconsecteturadipisicingelitAsperioresnecessitatibusneueodioImpeditistenesciuntescorruptiessecumrepudiandaequidolorumIllumtemporibusquoerrorcumqueeximpeditmagnamLoremipsumdolorsitametconsecteturadipisicingelitAsperioresnecessitatibusneueodioImpeditistenesciuntescorruptiessecumrepudiandaequidolorumIllumtemporibusquoerrorcumqueeximpeditmagnamtst
        </div>
      </div>
    </div>

This is how I want it but without the spaces in the long sentence.

#flexparent {
  display: flex
}

#flexchild1 {
  flex: 1;
  background-color: green;
}

#flexchild2 {
  flex: 1;
  background-color: red;
  display: flex;
  flex-flow: column
}

#flexchild3 {
  background-color: purple;
  word-wrap: break-word;
}
<div id="flexparent">
      <div id="flexchild1">
        FLEXCHILD1
      </div>
      <div id="flexchild2">
        FLEXCHILD2
        <div id="flexchild3">
 Thisisasuperlongsentence Loremipsum dolorsitametcon secteturadipisicingelitAsperi   resnecessitatibusneu eodioImpeditistenes ciuntescorru ptiessecumrepudia ndaequidolor umIllumtempori busquoerrorcumqu eeximpeditmagnam Lore mipsumdo lorsitam etconsecteturadipisicing elitAsperioresne cessitatibusneueodi oImpeditisten esciuntescorruptiessecumrepudia ndaequidolorumIll umtemporibusq uoerrorc umqueeximpe ditmagn amtstLoremipsu mdolorsitametcon secteturadipisici ngelitAsperio resnecessitati busn 
        </div>
      </div>
    </div>

Here are the codepens I made for this.

Michael Benjamin
  • 346,931
  • 104
  • 581
  • 701
tomzinho
  • 47
  • 1
  • 6
  • `width: 100%` has to go on `#flexparent`, not on `#flexchild3`, there is no `width: 100%` on a child when the parent is allowed to grow (`flex: 1` on `#flexchild2`) to infinity. – Adam Jenkins Dec 14 '17 at 19:35
  • 1
    You just need to add `min-width: 0` to `#flexchild2`, as indicated below by @LGSon. Here's a complete explanation: https://stackoverflow.com/q/36247140/3597276 – Michael Benjamin Dec 14 '17 at 19:58
  • add word-break:break-all to your first snippet , right after or instead word-wrap ... and see it working . At least in FF. https://codepen.io/gc-nomade/pen/qpdVLL – G-Cyrillus Dec 14 '17 at 20:18
  • @LGSon not sure that the min-width is the one thing here (and duplicate) : https://codepen.io/gc-nomade/pen/qpdVLL It has to do with the layout somehow but also on the rule used . here you may just need word-break. – G-Cyrillus Dec 14 '17 at 20:23
  • 1
    @G-Cyr The downside with `word-break:break-all;` is that it also break the words improper, which i.a. happens in Chrome, and as the issue here is actually the _implied minimum size_, the best is to solve it the proper way. – Asons Dec 14 '17 at 20:31

2 Answers2

10

This is a min-width issue, where a flex item can't be smaller than its content.

The default value of min-width is auto, and in this case it happens to the flex item #flexchild2

Give it min-width: 0 and it will work.

Also, the width: 100% is not needed, since a flex "column" item's align-items default to stretch, and as such automatically take full width of its parent, and can be removed.

Stack snippet

#flexparent {
  display: flex
}

#flexchild1 {
  flex: 1;
  background-color: green;
}

#flexchild2 {
  flex: 1;
  background-color: red;
  display: flex;
  flex-flow: column;
  min-width: 0;                   /*  added  */
}

#flexchild3 {
  background-color: purple;
  /*width: 100%;                      removed  */
  word-wrap: break-word;
}
<div id="flexparent">
      <div id="flexchild1">
        FLEXCHILD1
      </div>
      <div id="flexchild2">
        FLEXCHILD2
        <div id="flexchild3">
 ThisisasuperlongsentenceLoremipsumdolorsitametconsecteturadipisicingelitAsperioresnecessitatibusneueodioImpeditistenesciuntescorruptiessecumrepudiandaequidolorumIllumtemporibusquoerrorcumqueeximpeditmagnamLoremipsumdolorsitametconsecteturadipisicingelitAsperioresnecessitatibusneueodioImpeditistenesciuntescorruptiessecumrepudiandaequidolorumIllumtemporibusquoerrorcumqueeximpeditmagnamtstLoremipsumdolorsitametconsecteturadipisicingelitAsperioresnecessitatibusneueodioImpeditistenesciuntescorruptiessecumrepudiandaequidolorumIllumtemporibusquoerrorcumqueeximpeditmagnamLoremipsumdolorsitametconsecteturadipisicingelitAsperioresnecessitatibusneueodioImpeditistenesciuntescorruptiessecumrepudiandaequidolorumIllumtemporibusquoerrorcumqueeximpeditmagnamtst
        </div>
      </div>
    </div>
Asons
  • 84,923
  • 12
  • 110
  • 165
-1

The problem is that percentage-based widths are based off of the immediate parent. If the immediate parent has no width, the child cannot know what 100% of an arbitrary value is. flex: 1 is shorthand that contains flex-grow: 1, meaning that #flex2 can grow infinitly without setting this width constraint.

Percentage-based widths bubble up to the point a fixed width is known, so all you have to do is set a width of 100% of #flexchild2 as well in order for #flexchild3 to inherit the width of #flexparent:

This can be seen in the following:

#flexparent {
  display: flex;
}

#flexchild1 {
  flex: 1;
  background-color: green;
}

#flexchild2 {
  flex: 1;
  background-color: red;
  display: flex;
  flex-flow: column;
  width: 100%;
}

#flexchild3 {
  background-color: purple;
  width: 100%;
  word-wrap: break-word;
}
<div id="flexparent">
      <div id="flexchild1">
        FLEXCHILD1
      </div>
      <div id="flexchild2">
        FLEXCHILD2
        <div id="flexchild3">
 ThisisasuperlongsentenceLoremipsumdolorsitametconsecteturadipisicingelitAsperioresnecessitatibusneueodioImpeditistenesciuntescorruptiessecumrepudiandaequidolorumIllumtemporibusquoerrorcumqueeximpeditmagnamLoremipsumdolorsitametconsecteturadipisicingelitAsperioresnecessitatibusneueodioImpeditistenesciuntescorruptiessecumrepudiandaequidolorumIllumtemporibusquoerrorcumqueeximpeditmagnamtstLoremipsumdolorsitametconsecteturadipisicingelitAsperioresnecessitatibusneueodioImpeditistenesciuntescorruptiessecumrepudiandaequidolorumIllumtemporibusquoerrorcumqueeximpeditmagnamLoremipsumdolorsitametconsecteturadipisicingelitAsperioresnecessitatibusneueodioImpeditistenesciuntescorruptiessecumrepudiandaequidolorumIllumtemporibusquoerrorcumqueeximpeditmagnamtst
        </div>
      </div>
    </div>

However, note that due to you using two columns, you'll probably want to give #flexparent a width of 100%, and set your two columns to 20% and 80% respectively. Note that #flexchild3 still inherits 100% of the width of #flexchild2 (which is 80% of the width of #flexparent):

#flexparent {
  display: flex;
  width: 100%;
}

#flexchild1 {
  flex: 1;
  background-color: green;
  width: 20%;
}

#flexchild2 {
  flex: 1;
  background-color: red;
  display: flex;
  flex-flow: column;
  width: 80%;
}

#flexchild3 {
  background-color: purple;
  width: 100%;
  word-wrap: break-word;
}
<div id="flexparent">
      <div id="flexchild1">
        FLEXCHILD1
      </div>
      <div id="flexchild2">
        FLEXCHILD2
        <div id="flexchild3">
 ThisisasuperlongsentenceLoremipsumdolorsitametconsecteturadipisicingelitAsperioresnecessitatibusneueodioImpeditistenesciuntescorruptiessecumrepudiandaequidolorumIllumtemporibusquoerrorcumqueeximpeditmagnamLoremipsumdolorsitametconsecteturadipisicingelitAsperioresnecessitatibusneueodioImpeditistenesciuntescorruptiessecumrepudiandaequidolorumIllumtemporibusquoerrorcumqueeximpeditmagnamtstLoremipsumdolorsitametconsecteturadipisicingelitAsperioresnecessitatibusneueodioImpeditistenesciuntescorruptiessecumrepudiandaequidolorumIllumtemporibusquoerrorcumqueeximpeditmagnamLoremipsumdolorsitametconsecteturadipisicingelitAsperioresnecessitatibusneueodioImpeditistenesciuntescorruptiessecumrepudiandaequidolorumIllumtemporibusquoerrorcumqueeximpeditmagnamtst
        </div>
      </div>
    </div>

Hope this helps! :)

Obsidian Age
  • 41,205
  • 10
  • 48
  • 71
  • 2
    Percentage based width does not suffer from the same issue height based does, and as you can see in this fiddle - [https://jsfiddle.net/58cqrLw0/](https://jsfiddle.net/58cqrLw0/) - e.g. `width: 50%` works just fine. – Asons Dec 14 '17 at 20:00
  • Also worth checking this isn't set white-space: nowrap; – Joel Davey Nov 01 '19 at 13:41