skip to Main Content

I have a group of form inputs that are displayed on a single line on larger viewports and collapses to a multi-line display on smaller viewports. On the single line display I want a cancel button at the end of the line, but on the multi-line display I want it at the end of the first line, and I want the ends of both lines to be flush with each other.

I can do this by having two cancel buttons and conditionally displaying each based on a media query, as my snippet below shows, but it would be better to only have one button and shift its position based on the media query. Is there a way to do that in an example like mine by leveraging flexbox instead of using multiple cancel buttons? It seems like something that should be possible, but I can’t imagine exactly how to do it.

* {
    box-sizing: border-box;
  }
  input[name="qty"] {
    width: 36px;
  }
  input[name="unit"] {
    width: 192px;
  }
  button {
    width: 72px;
  }
  input[name="item"] {
    width: 300px;
  }
  .group-2 button {
    display: none;
  }

  @media screen and (min-width: 700px) {
    fieldset {
      display: flex;
    }
    .group-1 button {
      display: none;
    }
    .group-2 button {
      display: inline;
    }
  }
<fieldset>
  <div class="group-1">
    <input type="text" name="qty" placeholder="qty" /><input
      type="text"
      name="unit"
      placeholder="unit"
    /><button type="button">CANCEL</button>
  </div>
  <div class="group-2">
    <input type="text" name="item" placeholder="item" /><button
      type="button"
    >
      CANCEL
    </button>
  </div>
</fieldset>

2

Answers


  1. You do not need the second div.

    A single div with flexbox and flex-wrap:wrap will orient the elements as desired but it would be necessary to use order on the button at wider sizes to move it to the end.

    * {
      box-sizing: border-box;
    }
    
    input[name="qty"] {
      width: 36px;
    }
    
    input[name="unit"] {
      width: 192px;
    }
    
    button {
      width: 72px;
    }
    
    input[name="item"] {
      width: 300px;
    }
    
    .group-1 {
      display: flex;
      flex-wrap: wrap;
    }
    
    @media screen and (min-width: 700px) {
      button {
        order: 1;
      }
    }
    <fieldset>
      <div class="group-1">
        <input type="text" name="qty" placeholder="qty" />
        <input type="text" name="unit" placeholder="unit" />
        <button type="button">CANCEL</button>
        <input type="text" name="item" placeholder="item" />
      </div>
    </fieldset>
    Login or Signup to reply.
  2. My attempt using container queries and grid display. Feel free to change gap and flex properties to match your design.

    * { box-sizing: border-box; }
    
    form {
      margin-block-start: 4rem;
      container: group / inline-size;
    }
    
    fieldset {
        border: 0;
        
        input { 
          padding: .25rem;
          min-inline-size: 0; 
        }
    
        [name="qty"]  { flex: 1 }
        [name="unit"] { flex: 2 }
        [name="item"] { flex: 2 }
    
        
    
        @container group (width >= 700px) {
            display: flex;
            gap: .5rem;
            
            [class^="group"] {
              display: contents;
              flex: 1;
            }
        }
        
       
        @container group (width < 700px) {
          display: grid;
          gap: .5rem;
          grid-template-columns: 1fr fit-content(15rem);
          grid-template-areas: 
             "group1 button"
             "group2 group2"; 
         
          }
          
          [class^="group"] {
            display: flex;
            gap: .5rem;
            min-inline-size: 0
          }
          
          [name="unit"] { flex: 5 }
          .group-1 { grid-area: group1; }
          .group-2 { grid-area: group2; }
          button   { grid-area: button;  }
        }
      
    }
    <form >
      <fieldset>
        <div class="group-1">
          <input type="text" name="qty" placeholder="qty" />
          <input type="text" name="unit" placeholder="unit" />
        </div>
    
        <div class="group-2">
          <input type="text" name="item" placeholder="item" />
        </div>
        
        <button type="button">CANCEL</button>
      </fieldset>
    </form>
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search