Handling Imagery with CSS
John Serrao
Posted on June 22, 2021
Problem Set
I've been teaching people to code for almost seven years now, which has exposed me to hundreds of junior developers. The number one area where I see people either not understanding or overthinking solutions is with imagery.
Below are some common ways to deal with images. I'll try to keep this updated as techniques improve over time.
Portrait or Landscape?
These terms refer to the aspect ratio of the image where landscape photos are typically are wider than they are tall, while portrait photography is typically taller than it is wide. There are also square images, which would be as tall as they are wide. You can classify any image into one of those three categories.
Basic Responsive Image (landscape)
Most imagery is in landscape aspect ratio and you need a baseline technique for dealing with them. I treat them as a full-width break on the page and have them 'snap' to the size of the screen.
img {
display: block;
height: auto;
max-width: 100%;
}
This is tried and true, works across any device and is an ideal pair with responsive, landscape images in the foreground of your page. They create impact and work just about anywhere.
Responsive Background Image (landscape) With Clipping
Background images are a bit trickier because they don't take up any space. They are in the background of an HTML element, just window dressing. So you have to get more inventive.
If you don't mind some clipping of your image, try background-size: cover
:
.container-with-bg {
background-image: url(path/to/your-image.jpg);
background-position: center center;
background-size: cover;
height: 50vh;
}
This says to the browser:
Make the element take 50% of the height of the screen (100% width is default) and center the background image into that space.
The key part to understand is that background-size
puts the browser in charge of your display. The height and width are variable in this example so the sides of the images will occasionally be trimmed (at really wide or narrow screens). This can be acceptable for a lot of background images.
Responsive Background Image (landscape) - Exact Sizing
If you have a background image AND you know the aspect ratio of it, you can put a little hack into use. A little known but powerful quirk of HTML elements is that their padding-top
and padding-bottom
values equal the width of the container.
/**
* How did I get 66.67% for the padding-top?
* Original dimensions of the image (4242 x 2828px)
* Get aspect ratio (2828/4242 * 100)
*/
.container-aspect-ratio {
background-image: url(path/to/your-image.jpg);
background-position: center center;
background-repeat: no-repeat;
background-size: contain;
height: 0px;
padding-top: 66.67%;
}
Looks a bit weird, right? If we have a container that is 1000px wide, the padding-top: 50%
would actually equal 500px
when rendered. Don't believe me? Check it out.
If you're curious, you probably notice that this padding hack creates an aspect-ratio, where the container is half as tall as it is wide. We can use this to our advantage:
- Set
height: 0
on your container (so the padding-top will become the only part of the container you see). - Add
background-size: contain
which will size your image EXACTLY to it's container - Set the padding-top to the aspect ratio of your image
Now you've got a perfect background-image that doesn't clip your image. (CSS-tricks.com has a more thorough rundown if you want it.)
How to Get Text on Top of Background Image with No Clipping
Our previous example creates a container with no height - so how do we get text on top of it? You can absolutely position the text on top of the relatively positioned container with the background image in it:
.text {
bottom: 0;
position: absolute;
width: 100%;
}
Working Demo - same as above.
Posted on June 22, 2021
Join Our Newsletter. No Spam, Only the good stuff.
Sign up to receive the latest update from our blog.