How to make image caption width to match image width?
I'm attempting to style this:
<div class="figure">
<img src="/some/image.jpg">
<p class="caption">
<span class="caption-text">Some caption of any length</span>
</p>
</div>
So that the caption is in a shaded box the same width as the image. Note that .figure
can sometimes be inside a <td>
in a table, in case that matters. It also shouldn't exceed the width of the parent element (scaling the image down in necessary).
Here's what I have so far:
.caption-text {
font-size: 14px;
font-family: Lato, proxima-nova, 'Helvetica Neue', Arial, sans-serif;
font-weight: normal;
line-height: 0px;
}
.figure {
max-width: 100%;
display: inline-block;
position: relative;
}
.figure img {
vertical-align: top;
margin-bottom: 3px;
}
.caption {
display: block;
width: 100%;
position: absolute;
padding: 10px;
background-color: #e3e3e3;
box-sizing: border-box;
margin: 0;
}
<div style="width:500px">
<h1>Some Title</h1>
<!--part I want to style-->
<div class="figure">
<img src="https://placeholdit.imgix.net/~text?txtsize=33&txt=350%C3%97150&w=350&h=150">
<p class="caption">
<span class="caption-text">Some caption of any length. Should wrap and push content down when longer than the image.</span>
</p>
</div>
<p>Some text which should always go below the caption. When positioned absolutly the caption overlays this text, instead of pushing it down below.</p>
</div>
The problem is that putting the .caption
as position:absolute;
makes it no longer affect the flow of other elements, so it overlays content underneath it instead of pushing it down.
The html markup is automatically generated and I have no way of editing any of it, so I would like to know if this possible with pure css.
Solution 1:
You can use the CSS display:table
+ table-caption
solution.
.figure {
display: table;
margin: 0;
}
.figure img {
max-width: 100%;
}
.figcaption {
display: table-caption;
caption-side: bottom;
background: pink;
padding: 10px;
}
<h3>Example of small image</h3>
<figure class="figure">
<img src="//dummyimage.com/300x100" alt="">
<figcaption class="figcaption">Lorem ipsum dolor sit amet, consectetur adipiscing elit.</figcaption>
</figure>
<h3>Example of large image</h3>
<figure class="figure">
<img src="//dummyimage.com/900x100" alt="">
<figcaption class="figcaption">Lorem ipsum dolor sit amet, consectetur adipiscing elit.</figcaption>
</figure>
In addition, to remove the tiny white space below the image, you can either use:
.figure img { vertical-align: middle; }
or .figure img { display: block; }
Read this answer for more details.
Solution 2:
I'm including a more generic option that does not require table layout. That means you can add more children without worrying about how the table layout will effect them. You can also choose which children will "expand" the container, and which will not.
All it requires is that the outer element is display: inline-block;
, position: absolute;
, or any other "shrink-to-fit" type of node.
.container {
display: inline-block;
}
.no-expand {
box-sizing: border-box;
width: 0px;
min-width: 100%;
background: pink;
padding: 10px;
}
<h3>Example of small image</h3>
<div class="container">
<img src="//dummyimage.com/300x100" alt="">
<div class="no-expand">Lorem ipsum dolor sit amet, consectetur adipiscing elit.</div>
</div>
<h3>Example of large image</h3>
<div class="container">
<img src="//dummyimage.com/900x100" alt="">
<div class="no-expand">Lorem ipsum dolor sit amet, consectetur adipiscing elit.</div>
</div>