Styling Images with CSS

Size and crop images with object-fit and object-position, round them, add filters such as grayscale and blur, build hover effects and image overlays.

Lesson 29 of 49Beginner15 min read

Images make or break a page. Product photos, profile pictures, blog thumbnails and hero banners all have to fit neatly into a design, but real photos come in every shape and size. Put a tall portrait and a wide landscape into the same card grid and, without CSS, one gets squashed and the other stretched.

Modern CSS gives you precise control. object-fit crops or fits a photo inside a box without distorting it, the way a photo frame works. object-position chooses which part of the photo stays visible. border-radius rounds the corners or makes a perfect circle, and filters such as grayscale(), blur() and brightness() change how an image looks without opening an image editor.

In this lesson you'll use all of these, plus overlays for captions on top of photos and smooth hover effects. The responsive images lesson then covers making images fluid and fast on every screen.

object-fit: fitting photos into boxes

ValueResult
fillThe default. The image stretches to the box's exact shape and may look distorted.
coverFills the box completely and crops whatever doesn't fit. Best for thumbnails and banners.
containShows the whole image inside the box, leaving empty space if the shapes differ. Best for logos and product shots.
noneKeeps the image's natural size and crops it.
scale-downLike contain, but never makes the image bigger than its natural size.

object-fit only does something when the image box has a different shape from the photo, so pair it with a set width and height, or with aspect-ratio.

object-position

With object-fit: cover, the browser keeps the centre of the photo and crops the edges. object-position moves the focus:

CSS
img { object-fit: cover; object-position: top; }      /* keep faces near the top */
img { object-fit: cover; object-position: 20% 80%; }  /* a custom point */

It works like background-position: keywords such as top, left and center, or percentages for exact control.

CSS filters

CSS
img { filter: grayscale(100%); }
img { filter: blur(4px); }
img { filter: brightness(1.2) contrast(1.1) saturate(1.3); }
FilterWhat it does
grayscale(100%)Black and white
sepia(100%)Old-photo brown tone
blur(4px)Soft focus
brightness(0.6)Darker (below 1) or brighter (above 1)
contrast(1.4)More or less contrast
saturate(2)More or less colour
hue-rotate(90deg)Shifts every colour around the colour wheel
drop-shadow(...)A shadow that follows the shape of transparent PNGs and SVGs

Combine several filters in one declaration, separated by spaces. backdrop-filter applies the same effects to whatever is behind an element, which creates the frosted glass look.

Rounded images and overlays

border-radius: 12px rounds the corners; border-radius: 50% on a square image makes a circle. For a caption on top of a photo, put the image and caption inside a position: relative wrapper, then place the caption with position: absolute. A dark gradient behind the caption keeps white text readable on any photo.

CSS Images Syntax

Image styling

.thumb { width: 100%; aspect-ratio: 4 / 3; object-fit: cover; object-position: center; }
.logo { width: 120px; height: 60px; object-fit: contain; }
.avatar { width: 64px; height: 64px; border-radius: 50%; object-fit: cover; }
.muted { filter: grayscale(100%) brightness(0.9); }
.glass { backdrop-filter: blur(10px); }

CSS Images Summary

  • object-fit: cover fills a box and crops; contain fits the whole image inside.
  • object-position decides which part of a cropped image stays visible.
  • border-radius: 50% on a square image makes a circle.
  • filter changes how an image looks: grayscale, blur, brightness and more.
  • Overlays use a relative wrapper and an absolutely positioned caption.

CSS Images Examples

Each example runs in the page. Edit the code and press Run to see what changes.

Example 1

object-fit compared

The same wide photo in three square boxes.

.row { display: flex; gap: 12px; flex-wrap: wrap; font: 14px sans-serif; }
figure { margin: 0; text-align: center; }

img {
  width: 140px;
  height: 140px;
  background: #e5e7eb;
  border-radius: 10px;
}

.fill { object-fit: fill; }
.cover { object-fit: cover; }
.contain { object-fit: contain; }
ResultEdit the code, then press Run or Ctrl+Enter
Line-by-line explanation
  1. Lines 5 to 6Each box is square, but the photo is twice as wide as it is tall.
  2. Line 11Fill squashes the photo into the square.
  3. Line 12Cover fills the square and crops the sides.
  4. Line 13Contain shows the whole photo with grey space above and below.
Example 2

Filters and a hover effect

Hover over the photos.

.gallery { display: grid; grid-template-columns: repeat(auto-fit, minmax(140px, 1fr)); gap: 10px; }

.gallery img {
  width: 100%;
  height: auto;
  border-radius: 8px;
  filter: grayscale(100%) brightness(0.9);
  transition: filter 0.3s, transform 0.3s;
}

.gallery img:hover {
  filter: none;
  transform: scale(1.04);
}
ResultEdit the code, then press Run or Ctrl+Enter
Line-by-line explanation
  1. Line 7Photos start in black and white and slightly darker.
  2. Line 8Filter and size changes animate smoothly.
  3. Lines 12 to 13On hover, the colour returns and the photo grows a little.
Example 3

An avatar and a captioned card

.person { display: flex; align-items: center; gap: 10px; font: 600 16px sans-serif; margin-bottom: 16px; }
.avatar {
  width: 56px; height: 56px;
  border-radius: 50%;
  object-fit: cover;
  object-position: top;
}

.card { position: relative; margin: 0; max-width: 360px; }
.card img { display: block; width: 100%; height: auto; border-radius: 12px; }
.card figcaption {
  position: absolute; inset: auto 0 0 0;
  padding: 24px 14px 12px;
  color: white; font: 600 16px sans-serif;
  background: linear-gradient(transparent, rgb(0 0 0 / 0.7));
  border-radius: 0 0 12px 12px;
}
ResultEdit the code, then press Run or Ctrl+Enter
Line-by-line explanation
  1. Lines 3 to 5A tall portrait becomes a neat circle without stretching.
  2. Line 6The top of the photo, where the face is, stays visible.
  3. Line 9The card is the positioning context for the caption.
  4. Line 12The caption sits along the bottom edge.
  5. Line 15A dark fade keeps the white text readable.

Common CSS Images Mistakes

Stretched thumbnails

Don't
.thumb { width: 200px; height: 200px; } /* photos of other shapes get distorted */
Do
.thumb { width: 200px; height: 200px; object-fit: cover; }

Circle from a rectangle

Don't
.avatar { width: 80px; height: 60px; border-radius: 50%; } /* an oval */
Do
.avatar { width: 80px; height: 80px; border-radius: 50%; object-fit: cover; }

A circle needs equal width and height.

Text in images instead of real text

Don't
/* a banner photo with "Summer sale" painted into the image */
Do
.banner { position: relative; }
.banner h2 { position: absolute; bottom: 20px; left: 20px; color: white; }

Real text is searchable, translatable, readable by screen readers and sharp at any size.

CSS Images in Real Projects

Images on real sites

Online shops use object-fit: contain for product shots on white, so nothing is cropped, and cover for lifestyle photos. Social networks crop profile pictures into circles with object-fit: cover. News sites put headlines over photos with a gradient overlay, and photo galleries use grayscale-to-colour hover effects. backdrop-filter: blur() creates the frosted glass navigation bars seen in many modern apps.

CSS Images Exercises

Answer each one and check it instantly. If you get stuck, open the hint before the answer.

Fill in the blankseasy

Fill the box and crop the image without stretching it.

.thumb {
  object-fit: ;
}
Multiple choiceeasy

Which value shows the whole image without cropping?

Multiple choicemedium

How do you make a black and white image?

Multiple choicemedium

Which property keeps faces visible when a tall photo is cropped?

Fix the bugmedium

The avatar should be an 80px circle, cropped rather than stretched, and in black and white. Fix it.

.av {
  width: 80px;
  height: 60px;
  border-radius: 5%;
  object-fit: fill;
  filter: sepia(100%);
}
ResultEdit the code, then press Run or Ctrl+Enter
Checks
  • Square 80px box
  • Round
  • Cropped, not stretched
  • Black and white

CSS Images Quiz

5 questions to check what you learned.

  1. What is the default object-fit value?

    • cover
    • fill
    • contain
    • auto
  2. What does filter: brightness(0.5) do?

    • Makes the image twice as bright
    • Makes the image darker
    • Removes colour
    • Blurs the image
  3. What does backdrop-filter affect?

    • The element's own content
    • Only images
    • The page background colour
    • What is behind the element
  4. Why add a gradient behind a caption on a photo?

    • It's required for figcaption
    • It loads faster
    • It keeps white text readable on light parts of the photo
    • It makes the image smaller
  5. Why add width and height attributes to img when CSS sets the size?

    • The browser reserves space before the image loads, preventing layout jumps
    • They override CSS
    • They make the image sharper
    • They're needed for object-fit

CSS Images Challenge

A product card image

  1. Make .photo width: 100%, with an aspect-ratio of 1 / 1 and object-fit: cover
  2. Round its corners with border-radius: 12px
  3. Make .logo use object-fit: contain
  4. Make .sold images grayscale(100%)
ResultEdit the code, then press Run or Ctrl+Enter
Checks
  • Square cropped photo
  • Fills the card width
  • Rounded corners
  • Logo is contained
  • Sold photo is grey