Published: 1/28/2018
Sometimes you don't have an option to crop images on the server-side so you need to do the cropping in the browser instead. Here are a few examples of how to create cropped image thumbnails using CSS only. All the examples are responsive and work for most image aspect ratios. Cropped images are scaled and centered to maximize the visible area of the image. Notes about browser support and other limitations are marked below.
None of the examples are superior so it's mostly a matter of personal preference which one to use. Though there are minor variations in browser support.
All the solutions except SVG require the usage of a transparent placeholder image. It's possible to alter the aspect ratio of the thumbnail by changing the placeholder image size. The examples are built to show images in the grid.
The smallest image size available should be used when using CSS cropping because it will affect image loading time.
Embedded content: https://codepen.io/teroauralinna/pen/goXJQL
<div class="image-grid">
<a href="#" class="image-bg" style="background-image:url(https://url.to.image/image.jpg)">
<img class="image-bg-placeholder" src="https://url.to.image/placeholder.png" alt="" />
<img class="image-bg-img sr-only" src="https://url.to.image/image.jpg" alt="Cropped image as a background example" />
</a>
</div>
.image-grid {
display: flex;
flex-wrap: wrap;
margin: 0 auto 35px;
max-width: 920px;
}
.sr-only {
position: absolute;
width: 1px;
height: 1px;
padding: 0;
overflow: hidden;
clip: rect(0,0,0,0);
white-space: nowrap;
clip-path: inset(50%);
border: 0;
}
.image-bg {
background-position: center center;
background-size: cover;
flex: 0 0 auto;
margin: 5px;
width: calc(25% - 10px);
}
.image-bg-placeholder {
height: 100%;
visibility: hidden;
width: 100%;
}
The object-fit
is a similar property than background-size
which allows to choose how element should be resized to its container.
Object-position
property allows to alter image position same way as background image.object-fit
nor object-position
(image will be shown distorted). Polyfills are available: object-fit-images, objectFitPolyfill.object-fit
and object-position
.<div class="image-grid">
<a href="#" class="image-fit">
<img class="image-fit-placeholder" src="https://url.to.image/placeholder.png" alt="" />
<img class="image-fit-img" src="https://url.to.image/image.jpg" alt="Cropped image using object-fit example" />
</a>
</div>
.image-grid {
display: flex;
flex-wrap: wrap;
margin: 0 auto 35px;
max-width: 920px;
}
.image-fit {
flex: 0 0 auto;
margin: 5px;
position: relative;
width: calc(25% - 10px);
}
.image-fit-placeholder {
height: 100%;
visibility: hidden;
width: 100%;
}
.image-fit-img {
bottom: 0;
height: 100%;
left: 0;
object-fit: cover;
object-position: center;
position: absolute;
right: 0;
top: 0;
width: 100%;
}
max-height
and max-width
so that they work with aspect ratios I have used. But you need to choose if the horizontal or vertical image is displayed correctly. Alternatively, you can add a CSS class into the image if you check the aspect ratio on the server-side or with the Javascript. Then you could implement different styles for vertical and horizontal images.<div class="image-grid">
<a href="#" class="image">
<img class="image-placeholder" src="https://url.to.image/placeholder.png" alt="" />
<img class="image-img" src="https://url.to.image/image.jpg" alt="Cropped image using absolute positioning example" />
</a>
</div>
.image-grid {
display: flex;
flex-wrap: wrap;
margin: 0 auto 35px;
max-width: 920px;
}
.image {
flex: 0 0 auto;
margin: 5px;
overflow: hidden;
position: relative;
width: calc(25% - 10px);
}
.image-placeholder {
height: 100%;
visibility: hidden;
width: 100%;
}
.image-img {
left: 50%;
max-height: 150%;
max-width: 177%;
position: absolute;
top: 50%;
transform: translate(-50%, -50%);
}
Using the SVG is a new idea for me. Thanks for Cloud Four: Cropping Image Thumbnails with SVG blog post where I noticed this technique.
I enhanced the example a little bit by making it responsive and added SVG title for accessibility. Title works as an alt text.
<div class="svg-image-grid">
<a href="#" class="image-svg">
<svg viewBox="0 0 1 1" role="img">
<title>Cropped image using SVG example</title>
<image xlink:href="https://url.to.image/image.jpg" width="100%" height="100%" preserveAspectRatio="xMidYMid slice" />
</svg>
</a>
</div>
.svg-image-grid {
clear: both;
margin: 0 auto 35px;
max-width: 920px;
overflow: hidden;
position: relative;
}
.image-svg {
float: left;
margin: 5px;
padding-bottom: calc(25% - 10px);
position: relative;
width: calc(25% - 10px);
svg {
bottom: 0;
display: block;
height: 100%;
left: 0;
position: absolute;
right: 0;
top: 0;
width: 100%;
}
}
It would be interesting to know if you have used any other techniques successfully or have use cases when you can't use certain examples mentioned here.
Be the first commenter?
I am an experienced web developer with an eye for solid UI/UX design. I have specialized in front-end development, responsive web design, design systems, modern web frameworks, and content management systems. I also have experience in mobile apps development and back-end coding with PHP, Node.js, and Java. So I have a full stackish background, but I'm enjoying most building robust and beautiful front-ends with performance, accessibility, and testability in mind.
© Tero Auralinna
Auralinna.fiSunset with Bubbles: Travel and Photography Blog