Fully responsive images
What if I told you images could be cropped by their parent div omni-directionally, behaving like background-size: cover, but retaining the feature set of an IMG element? There's object-fit for that.
What if I told you images could be cropped by their parent DIV omni-directionally, behaving like background-size: cover, but retaining the feature set of an IMG element? There's object-fit for that.
Why not just use background-size?
Background-size can be a godsend for responsive image display, with omnidirectional cropping & a range of positioning controls making a design look polished & considered. But this approach to image display has its drawbacks, too. Using CSS to reference an image requires creating a class for each image, which can become difficult to manage longterm. Replacing images requires digging into the styles. Background images aren't ideal for accessibility, lacking alt text support. Nor are they ideal for load times, bypassing Webflow's built-in SRCSET responsive image support, which delivers optimized images according to the user's device.
In short, background-size leaves a number of boxes unticked.
Enter object-fit
Object-fit, on the other hand, offers the best of both worlds: the display flexibility of background-size & the feature set of an IMG element. It's not yet supported by Webflow natively, but with a single line of code, we can enable a host of features that will allow for flexibility in displaying images.
Among its benefits, Object Fit is useful for 1) defining an image's aspect ratio according to its parent div, 2) adjusting these aspect ratios across different viewports, 3) cropping an image omni-directionally according to its parent div's flex or grid properties, & 4) displaying a single image at multiple aspect ratios according to different use cases.
This becomes especially convenient when you have, for instance, a photo associated with an article that needs to be displayed at 21x9 as a hero graphic, as a 1x1 square in a related content area, & as a 4x3 graphic on the news page. We can use a single image for all 3 uses, allowing Webflow's responsive image support to display a pre-resized image closest to the display size. Of course, using cropping images in browser can produce unexpected results, crop-wise, so some foresight is required with the original crop, oftentimes meaning positioning crucial content in the center of the image. In these situations, we'll create a PSD with overlays for all of the different uses, which helps us foresee potential cropping issues. And in certain situations, we might decide to left- or right-align an image within the parent div. But despite the cropping challenges, managing a single crop per article can eliminate a number of headaches & save a lot of time in the long run.
To illustrate these features, we've built a prototype using a hi-res scan of Paul Calle's 1969 painting, “The Great Moment.”
The setup
There are 3 parts to implementing object fit: 1) a parent div that defines the bounds of the images, 2) an image, & 3) an embed element with some custom code declaring Object Fit, since it's not a Webflow-native feature.
The parent div
The parent div can either be flexible or a fixed aspect ratio, but either way will need to be set to overflow: hidden to crop the image & position: relative to contain the absolutely positioned image. We'll often define a set of classes for different aspect ratios that include overflow: hidden, position: relative, & a top padding to dictate the div's shape. Since top padding is defined relative to the width of the element, 100% top padding will get us a 1x1 image. 56.25% top padding will get us 16x9. And so forth.
Tip: For any specific aspect ratio, just divide the height by the width & multiply by 100.
For images that need to display in different aspect ratios according to viewport (i.e. 16x9 at desktop/tablet, 1x1 at mobile), we'll name those parent divs according to their function (i.e. Blog Header Photo Wrapper), rather than their aspect ratio.
CSS:
.photo-wrapper---1x1 {
overflow: hidden;
position: relative;
padding-top: 100%;
}
For any parent div that is set to stretch vertically, the top padding can serve as a minimum height for the image. So as text increases, for instance, in an adjacent column within a grid, the image will grow vertically & crop horizontally (instead of leaving negative space below the image), but as text disappears, it will never shrink down below a defined, acceptable aspect ratio.
The image
For the images, we'll use one class across all images we intend to inherit this functionality: Object Fit - Cover (.object-fit---cover in the style sheet). First, we'll need to set the class to absolute positioning, & then define a centering point by applying 50% spacing to the top & left, then center the image itself by applying -50% top & left move transforms. This positioning technique will ensure that the image, as it's cropped, will crop evenly from the top & bottom or the left & right. If the positioning step is skipped, the image will align top left & crop bottom right. This step can also be adjusted to allow for other other alignments.
Next, we'll apply 100% height & 100% width, which will distort the image to the size of the parent div (uncropped). Once we add the Object Fit line in an HTML embed, the image will stretch out to its proper proportions & autocrop itself.
CSS:
.object-fit---cover {
position: absolute;
left: 50%;
top: 50%;
transform: translate(-50%, -50%);
height: 100%;
width: 100%;
}
The HTML embed
We'll now add some code in a custom embed in order to make the magic happen...
HTML:
<style>
.object-fit---cover {
object-fit: cover;
}
</style>
And voila! We should have functioning Object Fit across all implementations.
Tip: The reason we do this in a custom embed instead of on of Webflow's custom code fields is because the Webflow Designer ignores the custom code fields, but does apply custom CSS inside HTML embeds. So we'll get to see our CSS impact the design in realtime instead of having to publish in order to see. This is generally advisable during the design phase, & we typically keep an HTML embed Symbol across all pages to manage custom CSS. (This symbol can be emptied later & the code moved into the Head of the document if need be.)
Enabling support for non-modern browsers
Not supporting object-fit, it will be important to use javascript to detect Internet Explorer &, where object-fit is used, to set the distorted image opacity to 0 & apply it as background-size: cover to the parent div. You can find documentation on this fallback here: Neat trick for CSS object-fit fallback on Edge (and other browsers).
With Object Fit supported in all major modern browsers, this approach to image display can open up a world of possibilities for responsive image display, & we've come to rely on it heavily. Check out the project to see it in action.