CSS Grid with input fields: alignment question

Viewed 1089

I am using CSS Grid (12 columns) with inputs fields. Due to the way I am creating the form (the form design is in JSON and created on the fly) the input fields are not the direct children of the grid but are wrapped in a div. If I do a grid-column: span of the div I also want the input field to span the columns - but not over the grid-gap. I have tried multiple ways of doing this and the best seems to be width: 100% on the input BUT this ignores the grid gap. Any idea as to how I can get the input field to be the same width as the div?

Sorry if I explained it badly - here is a screenshot of what I mean:

enter image description here

here the code:

   .container {
        display: grid;
        grid-template-columns: repeat(12, 1fr);
        grid-gap: 20px;
        background-color: black;
      }

      .fill-width {
        width: 100%;
      }

      .width-4 {
        grid-column: span 4;
      }
<div class="container">
      <input id="field1" class="width-4" placeholder="field1 (4)" />
      <input id="field2" class="width-4" placeholder="field2 (4)" />
      <input id="field3" class="width-4" placeholder="field3 (4)" />

      <div class="width-4">
        <input id="field5" placeholder="field5 (4)" />
      </div>
      <input id="field6" class="width-4" placeholder="field6 (4)" />
      <input id="field7" class="width-4" placeholder="field7 (4)" />

      <div class="width-4">
        <input id="field1" class="fill-width" placeholder="field1 (4)" />
      </div>
      <div class="width-4">
        <input id="field2" class="fill-width" placeholder="field2 (4)" />
      </div>
      <div class="width-4">
        <input id="field3" class="fill-width" placeholder="field3 (4)" />
      </div>
    </div>

and the codepen example: https://codepen.io/ursus_the_bear/pen/mdRQNXM

2 Answers

Nothing wrong that you are doing, but let me explain why this happens and the solution.

input elements have some css which the browser adds. like border, max-width and stuff. you need to get rid of those, for your inputs to follow your stylesheet strictly.

add this to the CSS for this to work like a charm:

* { /* all element selector */
  box-sizing: border-box; /* border, within the width of the element */
}
input {
  display: block;
  width: 100%
}   

if * {box-sizing: border-box; } looks new to you, you can remove the margin and border from input to get the perfect result.

 input {
  display: block;
  width: 100%;
  border: none;
  margin: 0;
} 

You are almost there. To ensure that the inputs do not overflow into the grid-gap, you could look into the box-sizing property. But since another answer has already demonstrated that, I'll provide an alternative approach.

You could try using flexbox. I made the divs in the container class flex parents, and then gave the inputs in those divs a flex-grow of 1. This ensures that the flex child takes up all the extra space in the flex parent. To make sure that the inputs do not overflow, I gave them a max-width of 100%. I also removed the width declaration for the fill-width class:

.container {
  display: grid;
  grid-template-columns: repeat(12, 1fr);
  grid-gap: 20px;
  background-color: black;
}

.width-4 {
  grid-column: span 4;
}


/* New styles */

.container div {
  display: flex;
  flex-flow: row nowrap;
}

.container div input {
  flex-grow: 1;
  max-width: 100%;
}
<div class="container">
  <input id="field1" class="width-4" placeholder="field1 (4)" />
  <input id="field2" class="width-4" placeholder="field2 (4)" />
  <input id="field3" class="width-4" placeholder="field3 (4)" />

  <div class="width-4">
    <input id="field5" placeholder="field5 (4)" />
  </div>
  <input id="field6" class="width-4" placeholder="field6 (4)" />
  <input id="field7" class="width-4" placeholder="field7 (4)" />

  <div class="width-4">
    <input id="field1" class="fill-width" placeholder="field1 (4)" />
  </div>
  <div class="width-4">
    <input id="field2" class="fill-width" placeholder="field2 (4)" />
  </div>
  <div class="width-4">
    <input id="field3" class="fill-width" placeholder="field3 (4)" />
  </div>
</div>

Related