Having figure match width of contained image
Posted 5 days ago
On Monday, I was working on a layout where the client wanted an image centered in the page. I also had another use case where the image would be floated to let the other content beneath flow around the image. The image also had a caption. I knew that I wanted to put the image within a figure
element and use figcaption
for the caption.
<figure>
<img src="foo.jpg" alt="" />
<figcaption>A caption for my image</figcaption>
</figure>
I wanted a way to make the figure
had the same width as the image and have the figcaption
wrap if it had a longer width than the image. I could not use a width: max-content
on the figure because it would take on the width of the figcaption
. Or if the text was long enough to need 2 lines to wrap inside the larger content container, putting a width: min-content
on the figure without also putting a max-width: 100%
would cause the figcaption
and figure to overflow the content container.
See the Pen figcaption overflow by Jeff Bridgforth (@webcraftsman) on CodePen.
Overflow contained
See the Pen figcaption overflow by Jeff Bridgforth (@webcraftsman) on CodePen.
I decided to try to look up a solution. Because AI is now built into the browser, it gave me a possible solution and I was curious to see if it actually worked. The solution applied display: table
to the figure
and display: table-caption
and caption-side: bottom
to the figcaption
. I tried it out and it did work. The figure
takes on the width of the image and centers image and figcaption
.
figure {
display: table;
margin-block: 0;
margin-inline: auto;
}
img {
height: auto;
max-width: 100%;
}
figcaption {
display: table-caption;
caption-side: bottom;
margin-block-start: .5em;
}
See the Pen figcaption overflow by Jeff Bridgforth (@webcraftsman) on CodePen.
But I wanted to see if others had solved the problem. So I asked a couple of CSS wizards on Bluesky. My initial post set off a chain of responses by many people who I did not mention in my original post.
The first response I got was from Chris Coyier:
See the Pen figure/figcaption issue by Chris Coyier (@chriscoyier) on CodePen.
Nils Binder responded to Chris simple use case.
See the Pen figure/figcaption issue by Nils Binder (@enbee81) on CodePen.
figure {
/* this *should* do it */
display: flex;
flex-direction: column;
max-width: min-content;
}
Ana Tudor also chimed in:
See the Pen Untitled by Ana Tudor (@thebabydino) on CodePen.
From his Stackoverflow:
Make the container
inline-block
(or any shrink-to-fit configuration liketable
,inline-grid
,inline-flex
,float
,absolute
etc) then force the width of text to be0
so the width of the container is defined by the image (the text doesn’t contribute to the width) then force the width again to be100%
usingmin-width
…We can also use
contain: inline-size
that will do the same job aswidth:0; min-width:100%;
See the Pen figure/figcaption issue by Temani Afif (@t_afif) on CodePen.
figure {
display: inline-block; /* shrink to fit element */
}
figcaption {
contain: inline-size; /* no size contribution for figcaption */
}
img {
max-width: 100%; /* you can have max-width */
}
Then Stephanie Eckels replied to T. Arif:
See the Pen figure/figcaption issue by Stephanie Eckles (@5t3ph) on CodePen.
figure {
/* original - shrink to fit element */
/* display: inline-block; */
/* Update - Swap to fit-content to retain margin access */
inline-size: fit-content;
margin-inline: auto;
}
figcaption {
/* no size contribution for figcaption */
contain: inline-size;
}
img {
/* you can have max-width */
max-width: 100%;
}
As you can see, there are many different ways to solve this problem. They all work. And as Andy Bell reminded me recently, If it works, it’s right.
I think if I had to pick the solution that I favor the most, it would be Stephanie’s solution. It uses a logical property, inline-size
, instead of width. It uses the clever contain
, which I have never used before. And it is very simple. It does not require changing the display
property and is very straightforward.
See the Pen figcaption overflow by Jeff Bridgforth (@webcraftsman) on CodePen.
And with the figure floating to wrap other content:
See the Pen Match figure to image width and wrap figcaption by Jeff Bridgforth (@webcraftsman) on CodePen.
Comment on this post