CSS Images

Images are a core part of every website. CSS gives you full control over how images display, scale, align, and behave — from making them responsive to adding decorative effects, captions, and hover interactions.

Making Images Responsive

A responsive image scales down on small screens but never grows larger than its natural size.

img {
  max-width: 100%;
  height: auto;
}
DIAGRAM — Responsive image behavior:

Image natural size: 800px wide

On a 1200px screen:
  ┌──────────────────────┐
  │  Image (800px)       │  ← stays at natural 800px width
  └──────────────────────┘

On a 600px screen:
  ┌────────────────┐
  │ Image (600px)  │  ← scales down to fit the screen
  └────────────────┘

On a 300px screen:
  ┌────────┐
  │ (300px)│  ← scales down further, never overflows
  └────────┘

This is the single most important CSS rule for images. Add it to your reset stylesheet so every image on the page is responsive by default.

Image as a Block Element

Images are inline elements by default, which creates a small gap at the bottom (due to the text baseline). Setting them to display: block removes this gap.

img {
  display: block;     /* removes bottom whitespace gap */
  max-width: 100%;
  height: auto;
}

Centering Images

/* Block-level centering */
img {
  display: block;
  margin: 0 auto;
}

/* Inside a flex container */
.container {
  display: flex;
  justify-content: center;
}

Circular Images

The classic profile picture — a square image clipped to a circle.

.avatar {
  width: 80px;
  height: 80px;
  border-radius: 50%;
  object-fit: cover;       /* prevents distortion */
  object-position: top;    /* keep face visible */
}
DIAGRAM — Square image → circle:

Before:               After border-radius: 50%:
┌──────┐                    ╭────╮
│ Photo│         →          │Pho-│
│      │                    │ to │
└──────┘                    ╰────╯

Image with Border and Padding

.framed {
  border: 4px solid #ddd;
  padding: 6px;
  background: white;
  box-shadow: 0 2px 8px rgba(0,0,0,0.15);
}

/* Polaroid-style */
.polaroid {
  padding: 8px 8px 32px;
  background: white;
  box-shadow: 0 4px 12px rgba(0,0,0,0.2);
  display: inline-block;
}

Image Hover Effects

/* Zoom in on hover */
.zoom-img {
  overflow: hidden; /* clips the zoomed image */
  border-radius: 8px;
}

.zoom-img img {
  transition: transform 0.4s ease;
  display: block;
  width: 100%;
}

.zoom-img:hover img {
  transform: scale(1.08);
}
DIAGRAM — Zoom hover effect:

Normal:
┌──────────────┐
│ 🏔 photo     │

On hover (image zooms, container clips it):
┌──────────────┐
│  🏔 zoomed  │  ← corners stay put, image grows inside
└──────────────┘
/* Darken on hover (overlay technique) */
.overlay-wrap {
  position: relative;
  display: inline-block;
}

.overlay-wrap::after {
  content: "";
  position: absolute;
  inset: 0;
  background: rgba(0, 0, 0, 0);
  transition: background 0.3s;
}

.overlay-wrap:hover::after {
  background: rgba(0, 0, 0, 0.4);
}

Image Caption with figure and figcaption

The semantic way to add a caption to an image uses <figure> and <figcaption>.

<figure class="image-caption">
  <img src="photo.jpg" alt="A mountain at sunrise">
  <figcaption>Mount Fuji at sunrise, Japan.</figcaption>
</figure>

.image-caption {
  margin: 0;
}

.image-caption img {
  width: 100%;
  display: block;
  border-radius: 8px 8px 0 0;
}

.image-caption figcaption {
  font-size: 0.85rem;
  color: #666;
  padding: 8px 12px;
  background: #f5f5f5;
  border-radius: 0 0 8px 8px;
  text-align: center;
}

Image with Text Overlay

.card {
  position: relative;
  overflow: hidden;
  border-radius: 10px;
}

.card img {
  width: 100%;
  height: 250px;
  object-fit: cover;
  display: block;
}

.card-label {
  position: absolute;
  bottom: 0;
  left: 0;
  right: 0;
  padding: 16px;
  background: linear-gradient(transparent, rgba(0,0,0,0.7));
  color: white;
}
DIAGRAM — Text overlay on image:

┌────────────────────────┐
│                        │
│    🏔 Mountain Photo   │
│                        │
│████████████████████████│  ← gradient overlay
│  Card Title            │
│  Subtitle text         │
└────────────────────────┘

Aspect Ratio Box

The aspect-ratio property keeps an image container at a fixed ratio regardless of screen width.

.video-wrapper {
  aspect-ratio: 16 / 9;
  overflow: hidden;
}

.video-wrapper img {
  width: 100%;
  height: 100%;
  object-fit: cover;
}

/* Square thumbnail */
.thumbnail {
  aspect-ratio: 1;
}

CSS Shapes with Images — clip-path

/* Hexagonal image */
.hex-img {
  clip-path: polygon(50% 0%, 100% 25%, 100% 75%, 50% 100%, 0% 75%, 0% 25%);
  width: 200px;
  height: 200px;
  object-fit: cover;
}

Grayscale Image with Color on Hover

.team-photo {
  filter: grayscale(1);
  transition: filter 0.3s ease;
}

.team-photo:hover {
  filter: grayscale(0);
}

Lazy Loading Images

The HTML loading="lazy" attribute tells the browser to defer loading offscreen images until the user scrolls near them. CSS handles the visual placeholder while the image loads.

<img src="photo.jpg" alt="Description" loading="lazy">
/* Placeholder background while image loads */
img {
  background: #f0f0f0;
  min-height: 200px;
}

Image as Background vs img Tag

DIAGRAM — When to use each:

<img> tag:
  ✅ Content images (products, photos, people)
  ✅ Images that need alt text for accessibility
  ✅ Images that should be indexed by search engines

background-image:
  ✅ Decorative images (patterns, textures, hero backgrounds)
  ✅ Images that must fill a container with object-fit behavior
  ✅ Images that do not add meaning to the content

Responsive images, clean hover effects, and proper use of object-fit are the three pillars of CSS image handling. Master these and your images will look sharp and professional on every screen size.

Leave a Comment

Your email address will not be published. Required fields are marked *