1

I am creating a simple form, where I want to have this kind of layout

screenshot1

So far so good, very simple 2 columns with a nested 2 columns, all of them defined with 0.5fr which should be the half of "free-space" if I understood correctly.

But, if I try to reduce the screen, this happens. even if I have NO media queries.

screenshot2

if you debug with chrome devtools you can see it's creating a 3rd column from nowhere without any element. Any idea?

https://stackblitz.com/edit/js-zzm4gy?file=index.html

h1, h2 {
  font-family: Lato;
}


.form{
  border: 1px solid black;
  text-align: center;
  display: grid;
  grid-template-rows: 1fr;
  grid-gap: 1em;
}

.two-field{
  display: grid;
  grid-template-columns: 0.25fr 0.75fr;
}

/********************/
/* Four elements row*/
/********************/
.four-field{
  display: grid;
  grid-template-columns: 0.5fr 0.5fr;
}

.four-field .left{
  display: grid;
  grid-template-columns: 0.5fr 0.5fr;
}

.four-field .right{
  display: grid;
  grid-template-columns: 0.25fr 0.75fr;
}
/********************/
/********************/
/********************/

/********************/
/******Buttons*******/
/********************/
.buttons{
  display: grid;
  grid-template-columns: 0.25fr 0.75fr;
}

.button-column{
  display: grid;
  grid-template-columns: 0.5fr 0.5fr;
  grid-column-gap: 1em;
}
/********************/
/********************/
/********************/
<div id="app">
 <form class="form">
  <div class="two-field">
   <label>First name:</label>
      <input type="text" name="firstname">
    </div>

    <div class="four-field">
      <div class="left">
        <label>Postal code:</label>
        <input type="text" name="Postal code">
      </div>
      <div class="right">
        <label>Place:</label>
        <input type="text" name="Place" >
      </div>
    </div>

    <div class="two-field">
      <label>Phone</label>
      <input type="text" name="phone">
    </div>

    <div class="buttons">
      <div class="empty"></div>
      <div class="button-column">
        <button type="submit">Confirm</button>
        <button>Abort</button>
      </div>
    </div>
  </form>
</div>
kukkuz
  • 41,512
  • 6
  • 59
  • 95
Luca Trazzi
  • 1,240
  • 1
  • 13
  • 30
  • 2
    Questions seeking code help must include the shortest code necessary to reproduce it **in the question itself** preferably in a **Stack Snippet**. Although you have provided a link, if it was to become invalid, your question would be of no value to other future SO users with the same problem. See [**Something in my website/example doesn't work can I just paste a link**](http://meta.stackoverflow.com/questions/254428/something-in-my-web-site-or-project-doesnt-work-can-i-just-paste-a-link-to-it). – Paulie_D Mar 05 '19 at 16:42
  • 1
    Fr doesn't mean free space, it means "fractional unit". Add all your fractional units together, and that's the number of total fractional units you'll have for that dimension. So, `grid-template-columns: 1fr 2fr 2fr 8fr` means the grid has 13 fractional units, and 1fr = 1/13 of the grid width. – Kerri Mar 05 '19 at 17:08
  • Thanks for the explanation, this explained me several things :) – Luca Trazzi Mar 06 '19 at 08:41

1 Answers1

3

The minimum size of a grid item is as much as its content; which means that min-width and min-height resolves to auto.

To provide a more reasonable default minimum size for grid items, this specification defines that the auto value of min-width/min-height also applies an automatic minimum size in the specified axis to grid items whose overflow is visible and which span at least one track whose min track sizing function is auto.

MDN

And note that input elements have an instrinsic width. So here you can add min-width: 0 to input elements to fix the issue - see demo below:

h1, h2 {
  font-family: Lato;
}


.form{
  border: 1px solid black;
  text-align: center;
  display: grid;
  grid-template-rows: 1fr;
  grid-gap: 1em;
}

input {
  min-width: 0; /* ADDED */
}

.two-field{
  display: grid;
  grid-template-columns: 0.25fr 0.75fr;
}

/********************/
/* Four elements row*/
/********************/
.four-field{
  display: grid;
  grid-template-columns: 0.5fr 0.5fr;
}

.four-field .left{
  display: grid;
  grid-template-columns: 0.5fr 0.5fr;
}

.four-field .right{
  display: grid;
  grid-template-columns: 0.25fr 0.75fr;
}
/********************/
/********************/
/********************/

/********************/
/******Buttons*******/
/********************/
.buttons{
  display: grid;
  grid-template-columns: 0.25fr 0.75fr;
}

.button-column{
  display: grid;
  grid-template-columns: 0.5fr 0.5fr;
  grid-column-gap: 1em;
}
/********************/
/********************/
/********************/
<div id="app">
 <form class="form">
  <div class="two-field">
   <label>First name:</label>
      <input type="text" name="firstname">
    </div>

    <div class="four-field">
      <div class="left">
        <label>Postal code:</label>
        <input type="text" name="Postal code">
      </div>
      <div class="right">
        <label>Place:</label>
        <input type="text" name="Place" >
      </div>
    </div>

    <div class="two-field">
      <label>Phone</label>
      <input type="text" name="phone">
    </div>

    <div class="buttons">
      <div class="empty"></div>
      <div class="button-column">
        <button type="submit">Confirm</button>
        <button>Abort</button>
      </div>
    </div>
  </form>
</div>

Suggestion

But there is no need for a lot of nesting here (I am suggesting a change in markup here) - you can make this work in a simple 4-column grid layout like below:

.form {
  border: 1px solid black;
  text-align: center;
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  grid-gap: 1em;
  padding: 10px;
}

input {
  min-width: 0;
}

input[name=firstname],
input[name=phone] {
  grid-column: span 3;
}

.button-column {
  grid-column: 2 / 5;
  display: grid;
  grid-template-columns: 1fr 1fr;
  grid-gap: 1em;
}
<div id="app">
  <form class="form">
    <label>First name:</label>
    <input type="text" name="firstname">
    <label>Postal code:</label>
    <input type="text" name="Postal code">
    <label>Place:</label>
    <input type="text" name="Place">
    <label>Phone</label>
    <input type="text" name="phone">
    <div class="button-column">
      <button type="submit">Confirm</button>
      <button>Abort</button>
    </div>
  </form>
</div>
kukkuz
  • 41,512
  • 6
  • 59
  • 95
  • 1
    Thanks for your snippet, I'll try to use this layout and see if will fit my needs. In the meantime, you didn't answer the question, why there's the hidden column? :( – Luca Trazzi Mar 06 '19 at 06:47
  • 1
    @LucaTrazzi sorry for the late reply, have added the explanations, check it out... – kukkuz Mar 07 '19 at 03:41