How to provide adaptive full-width images with CSS background-image — or otherwise?

814 Views Asked by At

My site has full-width hero images. There are currently served as a CSS background-image with a single image URL that is 2000px wide. Loading one or more of these images on a small device is definitely sub-optimal. I would like to serve a 2000px image, a 1440px image, a 992px image, etc to improve page loading time on mobile.

It seems that I can use -webkit-image-set and image-set, but these only take dpi and 1x, 2x, etc. sizes, so that won't help in this case, as I understand it because this won't ever show smaller images on smaller screens. Alternately, I could serve different images with a media query, but that gets complicated fast if you want to serve images based on viewport and if a device is 2x or 3x. Or I could switch to a img tag instead and use srcset, but I have not been able to find a solution to get a full width image that scales both up and down and fills a fixed height. It seems like this should be possible with object-fit: cover, but no combination of max-width, height, max-height, etc that I have tried has worked.

Here's an example of the CSS background-image that I'm trying to make adaptive:

.hero {
display: block;
min-height: 80px;
width: 100%;
float: left;
position: relative;
padding: 0;
-webkit-background-size: cover;
background-size: cover;
background-position: center center;
background-image: url("https://place-hold.it/500x100");
}
<div style="width: 500px;"> <!-- for this example, is 100% on our page -->
<a class="hero"></a>
</div>

This is on Wordpress with Boostrap.

1

There are 1 best solutions below

1
On BEST ANSWER

Here is how you can do that with a picture tag. I like using this tag because i think it gives you more control over the breakpoints.

Look it up here: https://www.w3schools.com/tags/tag_picture.asp

/* Basic styling for body. not important */

body,
html {
  margin: 0;
  padding: 0;
  width: 100%;
  height: 100%;
}


/* The parent container needs to have position:relative */

.example-container {
  position: relative;
  width: 100%;
  height: 100%;
  overflow: hidden;
  display: flex;
  justify-content: center;
  align-items: center;
  text-align: center;
  color: #fff;
}


/* The content element needs position:relative, and z-index higher than the BG element */

.example-content {
  position: relative;
  z-index: 10;
  margin: 0;
}


/* The picture element */

.image-full,
.image-full img {
  display: block;
  
  /* Absolute position the element with full width/height, and a low z-index */
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  z-index: 1;
  
  /* Object-fit:cover will make the image fill the space */
  object-fit: cover;
  object-position: center;
}
<div class="example-container">
  <h2 class="example-content">Content goes here</h2>
  <picture class="image-full">
    <source media="(min-width:1200px)" srcset="https://i.picsum.photos/id/1002/4312/2868.jpg?hmac=5LlLE-NY9oMnmIQp7ms6IfdvSUQOzP_O3DPMWmyNxwo">
    <source media="(min-width:500px)" srcset="https://i.picsum.photos/id/10/2500/1667.jpg?hmac=J04WWC_ebchx3WwzbM-Z4_KC_LeLBWr5LZMaAkWkF68">
    <img src="https://i.picsum.photos/id/100/2500/1656.jpg?hmac=gWyN-7ZB32rkAjMhKXQgdHOIBRHyTSgzuOK6U0vXb1w">
  </picture>
</div>