Search code examples
htmlcssflexboxgridcss-grid

Image inside Grid stretches grid item size disproportionately to others


#hi {
      display: grid;
    grid-template-columns: auto auto;
}

#hi > div {
      border: 1px solid red;
    min-height: 300px;
    display: flex;
    flex-flow: column;
    justify-content: center;
    align-items: center;
  min-height: 300px;
}

img {
  width: 100%;
  height: auto;
}
<div id='hi'>
  <div><img src='http://wvs.topleftpixel.com/photos/scotia_plaza_tall_stitched.jpg'></div>
  <div>erhbv</div>
  <div>erhbv</div>
  <div></div>
</div>

NOTE - image doesnt work correctly on embed - CODEPEN URL WORKS: https://codepen.io/anon/pen/vVeWpL

I'm new to grids and love them so far, but am very confused about this problem. For some unknown reason, the grid is stretched by the image, despite it having a width of 100%. Even if I change the width to 10%, the grid is still stretched. I've also tried ensuring the parent is 100% wide only by adding width 100%, but this also fails.

Can someone help make the grid width be 50/50, and explain what happened?


Solution

  • Can someone help make the grid width be 50/50, and explain what happened?

    To address the first part of your question/request; to divide the grid into two equally-sized columns you could simply specify discrete dimensions, for example in place of:

    grid-template-columns: auto auto;
    

    You could instead use:

    grid-template-columns: 1fr 1fr;
    

    #hi {
      display: grid;
      grid-template-columns: 1fr 1fr;
    }
    
    #hi>div {
      border: 1px solid red;
      min-height: 300px;
      display: flex;
      flex-flow: column;
      justify-content: center;
      align-items: center;
      min-height: 300px;
    }
    
    img {
      width: 100%;
      height: auto;
    }
    <div id='hi'>
      <div><img src='http://wvs.topleftpixel.com/photos/scotia_plaza_tall_stitched.jpg'></div>
      <div>erhbv</div>
      <div>erhbv</div>
      <div></div>
    </div>

    JS Fiddle demo.

    Or make use of the repeat() function to do the same thing:

    grid-template-columns: repeat(2, 1fr);
    

    #hi {
      display: grid;
      grid-template-columns: repeat(2, 1fr);
    }
    
    #hi>div {
      border: 1px solid red;
      min-height: 300px;
      display: flex;
      flex-flow: column;
      justify-content: center;
      align-items: center;
      min-height: 300px;
    }
    
    img {
      width: 100%;
      height: auto;
    }
    <div id='hi'>
      <div><img src='http://wvs.topleftpixel.com/photos/scotia_plaza_tall_stitched.jpg'></div>
      <div>erhbv</div>
      <div>erhbv</div>
      <div></div>
    </div>

    JS Fiddle demo.

    While I've used the fr unit in the above examples other dimensions could, of course, be used (such as 50% 50%/repeat(2, 50%) and so on); 1fr simply allocates a fractional unit, determined by the preceding number, of the available space.

    With regards to the latter part of your question, I can only offer an observation as to what happened — but without reference to the specifications — but I believe that the use of the auto keyword allowed the contents of the grid-item (the <div> containing the <img>) to dictate the size of that element. Quite why it produced the end-result, though, I'm afraid I don't know (I suspect others, however, will offer a far better explanation).

    Reference: