Handling Imagery with CSS
Tags: backgroundimage, position, backgroundsize, aspectratio
Published: 2021-06-22 14:55:04

---
title: Handling Imagery with CSS
published: true
description: How to address different kinds of imagery in the style layer.
tags: backgroundImage, position, backgroundSize, aspectRatio
---

## 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.

```css
img {
  display: block;
  height: auto;
  max-width: 100%;
}
```

[Working Demo](https://codesandbox.io/s/basic-responsive-image-809no?file=/main.css:0-61)

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`:

```css
.container-with-bg {
  background-image: url(path/to/your-image.jpg);
  background-position: center center;
  background-size: cover;
  height: 50vh;
}
```

[Working Demo](https://codesandbox.io/s/background-image-with-clipping-m5wvv?file=/main.css:123-287)

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**.

```css
/**
 * 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%;
}
```

[Working Demo](https://codesandbox.io/s/background-image-with-aspect-ratio-c83j7?file=/main.css)

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](https://codesandbox.io/s/container-aspect-ratio-wumu7?file=/index.html).

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](https://css-tricks.com/aspect-ratio-boxes/) 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:

```css
.text {
  bottom: 0;
  position: absolute;
  width: 100%;
}
```

[Working Demo](https://codesandbox.io/s/background-image-with-aspect-ratio-c83j7?file=/main.css) - same as above.