cssheight

Make a square element with lazy images inside


I'm trying to do a pure css image gallery for a static site. I want to create square elements with centered lazily loaded image previews in them.

My markup works fine when proportional width and fixed height are set, but I can't find a way to achieve fixed aspect ratio for image container.

I've tried:

  1. Rewrite everything to flexboxes. It breaks lazy image loading - seems like at some point every image appears on the viewport causing it to load. Generating previews on server side is not an option for me.
  2. padding-bottom trick. It totally breaks the behavior of object-fit: cover; and image preview centering.
  3. vw kinda works, but my container is already in a flexible container and I can't calculate it accurately.
  4. calc. As expected, it does not work with dynamic values, but I tried it just in case:)

Is where a way to get height to depend on width using pure css?

Here is the code snippet (same on JsFiddle):

div.image_list {
  display: block;
  width: 300px;  /* for example, not set in real case */
}

.image_wrapper {
  float: left;
  width: 30%;
  height: 100px;  /* FIXME: make height always equal to width */
  padding: 2%;
  background: blue;  /* for example only */
}

img {
  object-fit: cover;
  max-width: 100%;
  width: 100%;
  height: 100%;
}
<div class="image_list">
  <div class="image_wrapper">
    <img src="https://bigmemes.funnyjunk.com/pictures/Warning+long+post+short+postmedium+post_ba781a_5089470.jpg" loading="lazy">
  </div>
  <div class="image_wrapper">
    <img src="https://images.opencollective.com/jsbin/fef9bb5/logo/256.png" loading="lazy">
  </div>
  <div class="image_wrapper">
    <img src="http://voidcanvas.com/wp-content/themes/reader/images/logo.png?v=2" loading="lazy">
  </div>
  <div class="image_wrapper">
    <img src="http://voidcanvas.com/wp-content/themes/reader/images/logo.png?v=2" loading="lazy">
  </div>
  <div class="image_wrapper">
    <img src="https://bigmemes.funnyjunk.com/pictures/Warning+long+post+short+postmedium+post_ba781a_5089470.jpg" loading="lazy">
  </div>
  <div class="image_wrapper">
    <img src="https://images.opencollective.com/jsbin/fef9bb5/logo/256.png" loading="lazy">
  </div>

</div>


Solution

  • With modern browsers, one can use aspect-ratio.