The Figcaption Problem

Chris Coyier Chris Coyier on

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>Code language: HTML, XML (xml)

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:

Has anyone come up with a trick to make the width of a figure element fit the content of contained image even when figcaption has more width? I want figcaption to wrap. @kevinpowell.co @bell.bz @ishadeed.com @michelleb.bsky.social @chriscoyier.net @5t3ph.bsky.social

Jeff Bridgforth (@jeffbridgforth.com) 2025-06-09T14:08:35.238Z

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.

Me going, eh, screw it: 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%; 
}Code language: CSS (css)

Wouldn’t you think you could just min-content the <figure>?

Like:

figure {
  inline-size: min-content;
}Code language: CSS (css)

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%;
}Code language: CSS (css)

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" />Code language: HTML, XML (xml)
img {
  /* prevent blowouts */
  max-width: 100%;

  /* maintain aspect ratio */
  height: auto;

  /* opinionated, but removes line-height space below block images */
  display: block;
}Code language: CSS (css)

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:

A small image of flowers with a caption below describing the content.
Nope.

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;
}Code language: CSS (css)

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 */
}Code language: JavaScript (javascript)

Combined Demos

Video

While I was wrapping my mind around all this, I popped on a stream 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).

Looking for a complete course on getting into web development?

Frontend Masters logo

We have a complete intro course to web development by renowned developer Brian Holt from Microsoft. You'll learn how to be a successful coder knowing everything from practical HTML and CSS to modern JavaScript to Git and basic back-end development.

7-Day Free Trial

4 responses to “The Figcaption Problem”

  1. Phil says:

    Very cool, tried it without the margin-inline: auto; and it works fine too.

  2. Chris, thanks so much for your kind words. I think this post is entirely necessary because you have taken the time to understand the solution, learn new techniques, and add more to the conversation.

    I am amazed to see how my simple question has evolved into various approaches to solving it, and people learning new things along the way. Thanks for adding more to the conversation. I hope that all of this encourages others to ask questions out loud and for lots of people to “listen in” and learn together.

  3. Sven Kannengiesser says:

    The Universe sometimes is a weird thing! You ask it for help, and then you get an answer.

    The day before yesterday I had the same exact issue, solved it with display: inline-flex and flex-direction: column, but saw the potential drawbacks of an inline element.

    And the yesterday I stumbled upon your video/stream and was amazed by the simplicity and beauty of Stephanie‘s solution. This came at the right time.

  4. Chris Coyier says:

    Just a thought that I didn’t articulate well in the article:

    The goal here is sizing a parent element based on the size of a child element — but getting to choose which child element.

Leave a Reply to Jeff Bridgforth Cancel reply

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

Did you know?

Frontend Masters Donates to open source projects. $363,806 contributed to date.