Search code examples
cssflexboxcss-gridvertical-alignmentfigure

Vertically align <figure> within CSS Grid


I am trying to vertical align images in a grid. I am using the <figure> HTML element with caption for the images. The images replace checkboxes.


My code:

/* @media (min-width: 600px) { */

.grid {
  display: grid;
  grid-template-columns: 1fr 1fr 1fr 1fr;
  gap: 2%;
  padding: 1%;
}


/* } */

figure.item {
  border: 1px solid #000;
  /* To horizontally center images and caption */
  text-align: center;
  margin: 0;
  padding: 0;
}


/* hack to make images flexible: width: 100%;*/

img {
  width: 100%;
}

.caption {
  /* visibility: hidden; */
}

img,
figcaption {
  transition-duration: 0.2s;
  transform-origin: 50% 50%;
  opacity: 0.5;
}

:checked+label img,
:checked+label figcaption {
  opacity: 1;
}

input[type=checkbox] {
  display: none;
}
<div class="grid">
  <figure class="item">
    <input type="checkbox" id="1" class="box" />
    <label for="1">
      <img src="https://picsum.photos/seed/100/100" />
      <figcaption>Text below the image1</figcaption>
    </label>
  </figure>
  <figure class="item">
    <input type="checkbox" id="2" class="box" />
    <label for="2">
      <img src="https://picsum.photos/seed/100/100" />
      <figcaption>Text below the image1</figcaption>
    </label>
  </figure>
  <figure class="item">
    <input type="checkbox" id="3" class="box" />
    <label for="3">
      <img src="https://picsum.photos/seed/100/100" />
      <figcaption>Text below the image1</figcaption>
    </label>
  </figure>
  <figure class="item">
    <input type="checkbox" id="4" class="box" />
    <label for="4">
      <img src="https://picsum.photos/seed/100/100" />
      <figcaption>Text below the image1</figcaption>
    </label>
  </figure>
</div>


As you can see the 4 images are in a row (which is correct) but on top of the page. I want it verticaly centered (also when another row is added, both rows should be aligned in the middle). I have tried things like:

display: flex;
align-items: center;

But nothing seems to work. What am I missing?



Solution

  • The problem is with the height of the div and before that we should take care of its parent which is body and a level higher, html:

    so:

    html, body {
      height: 100%;
    }
    
    .grid {
      height: 100%;
      align-items: center;
    }
    

    here is the working example: https://jsfiddle.net/s9pyLe07/1/


    also the code snippet:

    html,
    body {
      height: 100%;
    }
    
    
    /* @media (min-width: 600px) { */
    
    .grid {
      display: grid;
      grid-template-columns: 1fr 1fr 1fr 1fr;
      gap: 2%;
      padding: 1%;
      height: 100%;
      align-items: center;
    }
    
    
    /* } */
    
    figure.item {
      border: 1px solid #000;
      /* To horizontally center images and caption */
      text-align: center;
      margin: 0;
      padding: 0;
    }
    
    
    /* hack to make images flexible: width: 100%;*/
    
    img {
      width: 100%;
    }
    
    .caption {
      /* visibility: hidden; */
    }
    
    img,
    figcaption {
      transition-duration: 0.2s;
      transform-origin: 50% 50%;
      opacity: 0.5;
    }
    
    :checked+label img,
    :checked+label figcaption {
      opacity: 1;
    }
    
    input[type=checkbox] {
      display: none;
    }
    <div class="grid">
      <figure class="item">
        <input type="checkbox" id="1" class="box" />
        <label for="1">
                <img src="https://picsum.photos/seed/100/100" />
                <figcaption>Text below the image1</figcaption>
            </label>
      </figure>
      <figure class="item">
        <input type="checkbox" id="2" class="box" />
        <label for="2">
                <img src="https://picsum.photos/seed/100/100" />
                <figcaption>Text below the image1</figcaption>
            </label>
      </figure>
      <figure class="item">
        <input type="checkbox" id="3" class="box" />
        <label for="3">
                <img src="https://picsum.photos/seed/100/100" />
                <figcaption>Text below the image1</figcaption>
            </label>
      </figure>
      <figure class="item">
        <input type="checkbox" id="4" class="box" />
        <label for="4">
                <img src="https://picsum.photos/seed/100/100" />
                <figcaption>Text below the image1</figcaption>
            </label>
      </figure>
    </div>