144

I'm trying to retain the first 2 child elements on the same row while the third element is in its own below at full width, all while using flex.

I'm particularly interested in using the flex-grow and flex-shrink properties on the first 2 elements (which is one of my reasons for not using percentages) however the third element really must be full width and below the first two.

The label element is added programmatically after the text element when there's an error and I can't change the code.

How do I force the label element to span a 100% width below the other two elements which are positioned using flex?

.parent {
  display: flex;
  align-items: center;
  width: 100%;
  background-color: #ececec;
}

.parent * {
  width: 100%;
}

.parent #text {
  min-width: 75px;
  flex-shrink: 2.25;
}
<div class="parent">
  <input type="range" id="range">
  <input type="text" id="text">
  <label class="error">Error message</label>
</div>
MPaul
  • 2,553
  • 3
  • 20
  • 34

2 Answers2

254

When you want a flex item to occupy an entire row, set it to width: 100% or flex-basis: 100%, and enable wrap on the container.

The item now consumes all available space. Siblings are forced on to other rows.

.parent {
  display: flex;
  flex-wrap: wrap;
}

#range, #text {
  flex: 1;
}

.error {
  flex: 0 0 100%; /* flex-grow, flex-shrink, flex-basis */
  border: 1px dashed black;
}
<div class="parent">
  <input type="range" id="range">
  <input type="text" id="text">
  <label class="error">Error message (takes full width)</label>
</div>

More info: The initial value of the flex-wrap property is nowrap, which means that all items will line up in a row. MDN

Michael Benjamin
  • 346,931
  • 104
  • 581
  • 701
  • 3
    “And enable `wrap` on the container.” <-- That is what I was missing. Why do we need that‽ – Fernando Basso Aug 19 '20 at 11:09
  • Because `flex-wrap: nowrap` is the default setting in a flex container. @FernandoBasso – Michael Benjamin Aug 19 '20 at 12:07
  • 1
    I see, thanks. I was working on something that had _only_ one flex item inside a flex container, and setting `width: 100%` or `flex-basis: 100%` was not enough, and it only worked when I set `wrap` to the flex container. Just tried on a simple example and the flex child goes 100% width _without_ `wrap` on the container. There must have been something else going on in my case then. – Fernando Basso Aug 20 '20 at 10:26
  • what if you don't want the component to wrap but to overflow and scroll, and still to be 100% width of parent? .col .wrapper { display: flex; flex-direction: row; width: ???; overflow-x: auto; } – Dane411 Jan 03 '21 at 22:44
  • 1
    @tao, `flex-shrink` is set to `0`. Nothing wrong with my answer, as the community has noted. – Michael Benjamin Jan 21 '21 at 18:45
  • You chose to provide an alternative answer instead of upvoting an existing one, which clearly worked. You're so full of success. I hope your points bring you happiness. – tao Jan 21 '21 at 19:10
  • @tao My answer was never meant to cause you any problems. I just posted an answer. Considering the closeness of posting time, we were probably drafting our answers at the same time. Best wishes. – Michael Benjamin Jan 21 '21 at 19:47
  • @MichaelBenjamin What if the 3rd div is inside 2nd div and i want to force it to full width, while aligning first and second divs in same row at each end and the div inside 2nd div to the next row for full width. Please help i'm stuck – Shehzadi khushi Oct 11 '21 at 03:21
  • the worst thing is I am using bootstrap and could just use container > col-4, col-4, col-4 but I feel FOMO of not knowing flex – Andy Oct 18 '22 at 09:59
4

Depends if it's

  1. Flex-direction:row (it's by default row) / on parent container
  • Try using justify-self: stretch / on the child that you want full width
  1. Flex-direction-column / on a parent container -Try using align-self: stretch / on the child that you want full width

Hopefully will help someone in some situations, usually helps me

BoxaBole
  • 51
  • 3