Search code examples
htmlcsscss-grid

CSS Grid: Grid-gap causing items to overflow?


Got a bit of a problem with my form layout if anyone can spare a bit of help: My understanding was that if I had a fixed width container, using fr instead of a percentage width for grid-template-columns would take into account only the free space available, and so grid-gap would not cause the grid to overflow its container, as described in this answer:

As a solution, instead of percentage units, try using fr units, which apply only to free space. This means that fr lengths are calculated after any grid-gap lengths are applied.

and also here:

The fr unit works only with the free space in the container.

But my code still seems to cause the grid to overflow (horizontally is all I care about):

https://codepen.io/nwoodward/pen/bGLpBbP

* {
  margin: 0;
}

.container {
  display: flex;
  justify-content: center;
  width: 100%;
  height: 100vh;
  background-color: firebrick;
}

.form {
  display: flex;
  flex-direction: column;
  padding: 2rem;
  margin: 2rem;
  width: 25rem;
  background-color: white;
}
.content {
  border: 1px solid red;
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  grid-gap: 4rem;
  width: 100%;
}
<div class="container">
  <form class="form">
    <div class="content">
      <div class="field">
        <label for="title" class="label">Title</label>
        <input type="text" placeholder="Job Title" id="title" class="input">
        <i class="icon icon--success"></i>
        <i class="icon icon--fail">
        </i>
        <small class="error-msg"></small>
      </div>
      <div class="field">
        <label for="company" class="label">Company</label>
        <select name="company" id="company" class="input">
            <!-- options added in js -->
        </select>
        <i class="icon icon--success"></i>
        <i class="icon icon--fail"></i>
        <small class="error-msg"></small>
      </div>

      <div class="field">
        <label for="location" class="label">Location</label>
        <select name="location" id="location" class="input">
            <!-- options added in js -->
        </select>                        
        <i class="icon"></i>
        <i class="icon"></i>
        <small class="error-msg"></small>
      </div>

      <div class="field">
        <label for="wage" class="label">Wage</label>
        <input type="text" placeholder="Wage" id="wage" class="input">
        <i class="icon icon--success"></i>
        <i class="icon icon--fail"></i>
        <small class="error-msg"></small>
      </div>

      <div class="field">
        <label for="type" class="new-job__label">Type</label>
        <select name="type" id="type" class="input">
          <!-- options added in js -->
        </select>
        <i class="icon icon--success"></i>
        <i class="icon icon--fail"></i>
        <small class="error-msg"></small>
      </div>

      <div class="field">
        <label for="position" class="label">Position</label>
        <select name="position" id="position" class="input">
          <!-- options added in js -->
        </select>
        <i class="icon icon--success"></i>
        <i class="icon icon--fail"></i>
        <small class="error-msg"></small>
      </div>

      <div class="field">
        <label for="pqe" class="label">PQE</label>
        <select name="pqe" id="pqe" class="input">
            <!-- options added in js -->
        </select>
        <i class="icon icon--success"></i>
        <i class="icon icon--fail"></i>
        <small class="error-msg"></small>
      </div>

      <div class="field">
        <label for="featured" class="label">Featured</label>
        <select name="featured" id="featured" class="input">
          <!-- options added in js -->
        </select>
        <i class="icon icon--success"></i>
        <i class="icon icon--fail"></i>
        <small class="error-msg"></small>
      </div>
    </div>
    <button class="new-job__submit">Submit</button>

  </form>
</div>

I guess that part of the issue is that the input elements have a fixed minimum width of some sort, but even if that is true, fixing the width of either the .field or the inputs to a smaller value that does fit isn't really what I'm after at all.


*EDIT: Overflowing with inputs overflow

**EDIT: Not overflowing with divs not overflowing


Solution

  • Update the code like below (related question to understand the first code adjustment: Why does minmax(0, 1fr) work for long elements while 1fr doesn't?)

    * {
      margin: 0;
    }
    
    .container {
      display: flex;
      justify-content: center;
      background-color: firebrick;
    }
    
    .form {
      display: flex;
      flex-direction: column;
      padding: 2rem;
      margin: 2rem;
      width: 25rem;
      background-color: white;
    }
    .content {
      border: 1px solid red;
      display: grid;
      grid-template-columns: repeat(2, minmax(0,1fr)); /* here */
      grid-gap: 4rem;
    }
    
    /* here */
    input {
      max-width: 100%;
      box-sizing: border-box;
    }
    <div class="container">
      <form class="form">
        <div class="content">
          <div class="field">
            <label for="title" class="label">Title</label>
            <input type="text" placeholder="Job Title" id="title" class="input">
            <i class="icon icon--success"></i>
            <i class="icon icon--fail">
            </i>
            <small class="error-msg"></small>
          </div>
          <div class="field">
            <label for="company" class="label">Company</label>
            <select name="company" id="company" class="input">
                <!-- options added in js -->
            </select>
            <i class="icon icon--success"></i>
            <i class="icon icon--fail"></i>
            <small class="error-msg"></small>
          </div>
    
          <div class="field">
            <label for="location" class="label">Location</label>
            <select name="location" id="location" class="input">
                <!-- options added in js -->
            </select>                        
            <i class="icon"></i>
            <i class="icon"></i>
            <small class="error-msg"></small>
          </div>
    
          <div class="field">
            <label for="wage" class="label">Wage</label>
            <input type="text" placeholder="Wage" id="wage" class="input">
            <i class="icon icon--success"></i>
            <i class="icon icon--fail"></i>
            <small class="error-msg"></small>
          </div>
    
          <div class="field">
            <label for="type" class="new-job__label">Type</label>
            <select name="type" id="type" class="input">
              <!-- options added in js -->
            </select>
            <i class="icon icon--success"></i>
            <i class="icon icon--fail"></i>
            <small class="error-msg"></small>
          </div>
    
          <div class="field">
            <label for="position" class="label">Position</label>
            <select name="position" id="position" class="input">
              <!-- options added in js -->
            </select>
            <i class="icon icon--success"></i>
            <i class="icon icon--fail"></i>
            <small class="error-msg"></small>
          </div>
    
          <div class="field">
            <label for="pqe" class="label">PQE</label>
            <select name="pqe" id="pqe" class="input">
                <!-- options added in js -->
            </select>
            <i class="icon icon--success"></i>
            <i class="icon icon--fail"></i>
            <small class="error-msg"></small>
          </div>
    
          <div class="field">
            <label for="featured" class="label">Featured</label>
            <select name="featured" id="featured" class="input">
              <!-- options added in js -->
            </select>
            <i class="icon icon--success"></i>
            <i class="icon icon--fail"></i>
            <small class="error-msg"></small>
          </div>
        </div>
        <button class="new-job__submit">Submit</button>
    
      </form>
    </div>