The Figcaption Problem
The Figcaption Problem êŽë š
There is this problem with this, when it comes to layout:
<figure>
<img src="image.jpg" alt="good description of image" />
<figcaption>This is a pretty long caption that I want for the image. It's such a long bit of text that it's likely going to wrap in the layout.</figcaption>
</figure>
The problem isnât with the HTML, thatâs fine.
The problem is when the image is less wide than the container and we want the figcaption to only be as wide as the image is.
We want this:

We want that orange buddy. Thatâs the <figure>
element sitting in the middle of this article, centered, with an <img>
inside that isnât the full width of the article, and a <figcaption>
inside that wraps at the edges of the image.
How hard can that be?!
Well â it certainly is weird.
This all started with a post from Jeff Bridgforth that piqued my interest:
See, Iâd run into this myself. On my own blog, I often post photos that are not the full width of the page and want to center them or float them to a side or something. And the thing that limits the width of the <figcaption>
is the parent <figure>
itself, not the <img>
. So how do you limit the <figcaption>
width?
On my own blog, I was just like screw it and set a max-inline-size
on them.

figcaption { max-inline-size: 300px; }
For the most part I chalked it up as a design decision that had kind of a cool look. But it still bugged me. Like the image above where the figcaption still ends up wider than the image.
There is a proper solution here.
Jeff was smart enough to blog the entire conversation and solutions that came out of his post. And frankly he did a good job and this blog post probably isnât entirely necessary. But hey if it helps more people when they run into this, thatâs cool.
Allow me to jump straight to the end and showcase the best solution, by Stephanie Eckles:
There it is, the perfect solution here.
figure {
inline-size: fit-content;
margin-inline: auto;
}
figcaption {
contain: inline-size;
}
/* Probably in your reset stylesheet, which is good. */
img {
max-width: 100%;
}
Wouldnât you think you could just min-content
the <figure>
?
Like:
figure {
inline-size: min-content;
}
Thatâs what my brain does and I heard from others the same. The image would be the smallest content within the figure (otherwise it would be just a word), so the figure should kinda shrink-wrap around the image.
The thing is⊠you can and it works⊠unless⊠you use the classic reset stylesheet thing:
img {
max-width: 100%;
}
Iâm a fan of this. Itâs protection against a too-wide image busting out of a container. Itâs a classic, and itâs important. This is more like reality, where width
and height
attributes are on the image, because thatâs a best-practice for maintaining aspect ratio space as the image is loading.
<img src="..." alt="..." width="4000" height="2000" />
img {
/* prevent blowouts */
max-width: 100%;
/* maintain aspect ratio */
height: auto;
/* opinionated, but removes line-height space below block images */
display: block;
}
But if we do this, weâre essentially wiping away the intinstic size of the image and the min-content
width becomes based on the figcaption
instead and we get smashy-smashy thin time:

Whatâs with mixing logical properties like inline-size
in some places and non-logical properties like max-width
in others? Iâm a fan of almost always using logical properties, but for most images, even changing to a vertical writing mode shouldnât rotate images, so properties like width
make sense.
The Best Tricks Are About Using The Images Intrinsic Size Instead Of The Figcaption
The core of the trick is:
figcaption {
contain: inline-size;
}
That says: donât factor in the figcaption in determining the intrinsic inline-size of the parent.
There was a way to do this before, as Temani Afif pointed out, with weirder trickery:
figcaption {
inline-size: 0; /* or width */
min-inline-size: 100%; */ or min-width */
}
Combined Demos
Video
While I was wrapping my mind around all this, I popped on a stream (chriscoyier) to do it. This isnât like a straightforward tutorial, itâs the exploratory poking around and trying stuff that lead to my own better understanding (and the demos and this blog post).