Search code examples
htmlcssflexboxgrid

wrap and stretch inputs on form resize


I have two inputs on form in one row. First one should be stretching on form resize, second is of fixed width. But when form is narrowed to a particular breakpont, second input should wrap to second line and stretch as well as first one. gif wide narrow

Is it possible to achieve using CSS? Tried using grid, but it won't wrap at all. When using flexbox the result is better, but still have to set flex-grow for second input and it's width is not fixed, while inputs are in one row

.box {
  background: grey;
  padding: 20px 20px 20px 20px;
}

.wrapper {
  display: grid;
  grid-column-gap: 6px;
  grid-row-gap: 6px;
  grid-template-columns: minmax(320px, 1fr) 200px;
}

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

.flex1 {
  flex-basis: 320px;
  flex-grow: 10;
  flex-shrink: 0;
}

.flex2 {
  flex-basis: 200px;
  flex-shrink: 0;
  flex-grow: 1;
}
<div class="wrapper">
  <div class="box">One</div>
  <div class="box">Two</div>
</div>

<div class="flexWrapper">
  <div class="flex1 box">One</div>
  <div class="flex2 box">Two</div>
</div>

https://codepen.io/C4off/pen/WNKjJaK


Solution

  • The easiest way to do this is to use a media query. At 600px I've reset the wrapper to be display: block with the children at 100% width which forces them to stack on top of each other. I've set the width of flex2 to 200px to fix it at that.

    .box {
      background: grey;
      padding: 20px 20px 20px 20px;
    }
    
    .flexWrapper {
      display: flex;
      padding-top: 12px;
      column-gap: 6px;
      row-gap:6px;
    }
    
    .flex1 {
      flex: 1;
    }
    
    .flex2 {
      width: 200px;
    }
    
    @media only screen and (max-width: 600px) {
      .flexWrapper {
        display: block;
      }
      .flex1, .flex2 {
        width: 100%;
      }
    }
    <div class="container">
      <div class="flexWrapper">
         <div class="flex1 box">One</div>
         <div class="flex2 box">Two</div>
      </div>
    </div>

    Using flexbox only and the min-width proprty. Note .flex2 will overflow at container widths less than 200px

    .container {
      width: 60%;
      outline: 1px solid red;
    }
    .box {
      background: grey;
      padding: 20px 20px 20px 20px;
    }
    
    .flex-wrapper {
      display: flex;
      padding-top: 12px;
      column-gap: 6px;
      row-gap:6px;
      flex-wrap: wrap;
    }
    
    .flex1 {
      flex: 2 0;
    }
    
    .flex2 {
      min-width: 200px;
      flex-grow: 1;
    }
    <div class="container">
      <div class="flex-wrapper">
         <div class="flex1 box">One</div>
         <div class="flex2 box">Two</div>
      </div>
    </div>

    The final way this can be done is using container queries which are quite well supported now. The max size is applied to the container and not the screen as the example below

    * {
      box-sizing:border-box;
    }
    
    .container {
      container-type: inline-size;
      container-name: my-container;
      width: 60%;
    }
    
    .box {
      background: grey;
      padding: 20px 20px 20px 20px;
    }
    
    .flex-wrapper {
      display: flex;
      padding-top: 12px;
      column-gap: 6px;
      row-gap:6px;
    }
    
    .flex1 {
      flex: 1;
    }
    
    .flex2 {
      width: 200px;
    }
    
    @container my-container (max-width: 600px) {
      .container {outline: 1px solid red;}
      .flex-wrapper {
        display: block;
      }
      .flex1, .flex2 {
        width: 100%;
      }
    }
    <div class="container">
      <div class="flex-wrapper">
         <div class="flex1 box">One</div>
         <div class="flex2 box">Two</div>
      </div>
    </div>