As a frontend developer, I often need to work with images. And sometimes it gets tricky when an image is scaled and positioned differently across the application. For example, an ecommerce website might require a larger version of an image on the product page and a zoomed-in version of the same image when displaying a list of products.
Before Chrome 104, my go-to solution to crop/zoom an image was to apply it as background-image
in a div and then adjust the background-position
and background-size
properties. Here’s an example:
<div id="cropped"></div>
#cropped { width: 500px; aspect-ratio: 3/2; background-image: url("https://images.unsplash.com/photo-1611604548018-d56bbd85d681?ixlib=rb-4.0.3&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=2070&q=80"); background-size: 1250px; background-position: 66% 67%; background-repeat: no-repeat; }
It works fine, but let’s just say this solution to crop/zoom images leaves something to be desired. It’s not exactly what you’d call tidy. Also, this won’t work with just an <img/>
tag. There are other workarounds, but none of them is as simple and clean as object-view-box
.
In this article, we’ll cover:
object-view-box
property?
object-view-box
?object-view-box
property?The release of Chrome 104 introduced a native approach to zoom or pan within the content of an element. The CSS object-view-box
property makes this possible by specifying a view box over an element and enabling us to adjust the positioning and scaling to meet our specific needs.
In simple words, just like a camera lens can be adjusted to zoom in or out or pan across the view outside, the object-view-box
property allows us to zoom in on specific parts of an element or pan around to display different parts of the element.
object-view-box
?To specify a view box over an element, object-view-box
the inset()
function to control the four edges.
inset()
is a shorthand way to specify values for the element’s top
, right
, bottom
, and left
properties, in that order. It follows the same syntax as the padding and margin properties, which allows it to accept from one to four values:
These values can be expressed using any valid CSS length unit, such as pixels (px), ems (em), rems (rem), and percentages (%), among others.
Let’s apply this property to the same image above and try to achieve the same result:
<img id="cropped" src="https://images.unsplash.com/photo-1611604548018-d56bbd85d681?ixlib=rb-4.0.3&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=2070&q=80" alt="toys">
#cropped { width: 500px; object-view-box: inset(40% 20% 20% 40%); }
If the cropped version of the image is a square, the image will appear distorted, i.e., stretched or squeezed:
#cropped { aspect-ratio: 1; width: 500px; object-view-box: inset(40% 20% 20% 40%); }
Here, we can use the help of the object-fit
property, which defines how an element should be resized to fit its container. The property can be set with one of these values: fill
, contain
, cover
, none
, or scale-down
.
For our scenario, we can use cover
, which resizes the image to fit the aspect-ratio
of the container and if the image’s aspect-ratio
doesn’t match the container’s, then it will be clipped to fit:
#cropped-fit-cover { aspect-ratio: 1; width: 500px; object-fit: cover; object-view-box: inset(40% 20% 20% 40%); }
Isn’t this a convenient way to crop/zoom an image? It only requires one property and is easy to visualize. No additional properties or elements are needed, unlike workarounds.
Using the object-view-box
property is a native solution; the browser does the hard work, and the developers get a clean solution.
There are popular workarounds among devs, like using an HTML element — e.g., <div/>
— and applying CSS properties to achieve a cropped image. But that’s still just a workaround, an unconventional solution to overcome the limitation of the browser.
With this update, the browser has worked on that limitation and offers a built-in solution.
There is a concern that, to make this work, you need to know the exact dimension of the original container and the new container. But isn’t that a prerequisite to crop an image? To determine how much to crop, we’ll always need that information.
So, how will this work when the container is resized (change in the viewport)?
As the object-view-box
uses inset()
to draw a view-box
over an image, cropping always happens on the intrinsic size (original width and height) of the image. To make it responsive, we can use this property along with media queries and crop accordingly.
object-view-box
?The ability to crop/zoom an image can come in handy in many cases:
There have been workarounds to cropping and zooming images in past, but I welcome this native and convenient solution. Also, please keep in mind that this is an experimental release, and therefore, it may not be widely supported across all browsers. Visit caniuse.com for up-to-date browser support tables.
As web frontends get increasingly complex, resource-greedy features demand more and more from the browser. If you’re interested in monitoring and tracking client-side CPU usage, memory usage, and more for all of your users in production, try LogRocket.
LogRocket is like a DVR for web and mobile apps, recording everything that happens in your web app, mobile app, or website. Instead of guessing why problems happen, you can aggregate and report on key frontend performance metrics, replay user sessions along with application state, log network requests, and automatically surface all errors.
Modernize how you debug web and mobile apps — start monitoring for free.
Hey there, want to help make our blog better?
Join LogRocket’s Content Advisory Board. You’ll help inform the type of content we create and get access to exclusive meetups, social accreditation, and swag.
Sign up nowToast notifications are messages that appear on the screen to provide feedback to users. When users interact with the user […]
Deno’s features and built-in TypeScript support make it appealing for developers seeking a secure and streamlined development experience.
It can be difficult to choose between types and interfaces in TypeScript, but in this post, you’ll learn which to use in specific use cases.
This tutorial demonstrates how to build, integrate, and customize a bottom navigation bar in a Flutter app.