4

I'm currently up to the problem, that I'm trying to add a caption to an image-element. The caption should wrap if it is larger in width then the image.

<figure class="caption">
    <a href="#" target="_blank">
        <img src="/sample_image" alt="">
    </a>
    <figcaption>This is a sample-caption that should wrap if it's width exceeds the width of the image</figcaption>
</figure>

for normal, some CSS-Code like this should do the job:

figure {
    display: table;
    width: 50px;
}
figcaption {
    display: table-row;
}

The problem is, that this doesn't work in combination with the following CSS, used to auto-scale images for mobile devices:

img {
    max-width: 100%;
}

So the solution as mentioned here https://stackoverflow.com/a/617455/583569 would not work. I know, that is not a good solution, but for now a conversion of all images into various formats would take to much time.

Is there a possible, non-JS, solution to fix this problem?

Community
  • 1
  • 1
  • So you want the text wrapper to always be the width of the image, but the image is not always the full width of its container, correct? – robooneus Aug 27 '13 at 12:47
  • That's nearly correct ... the image is maximum it's own width, or if the surrounding layer is smaller, it is max-width: 100% of the surrounding layer. If the surrounding layer is 900px in width on desktop and the image is 600px in width, the image will only be displayed with the width of 600px. If the same page is viewed on a smartphone f.e. and the surrounding layer is only 300px in width, the image will be displayed with a width of 300px - in this case, the text will be wrapped automatically because no more space is available. – Dominik Habichtsberg Aug 27 '13 at 13:08
  • Exactly, so you just need something to limit the text wrapper to be exactly the width of the image (which it does natively when smaller, but not when the screen is larger). – robooneus Aug 27 '13 at 13:09
  • Haven't looked closely at the answer within this, but seems like it might be what you are looking for: http://stackoverflow.com/questions/5485341/css-div-width-depending-on-image-size-above – robooneus Aug 27 '13 at 13:16
  • It's the same problem - it hangs up itself when `img { max-width: 100%; }` takes effect. – Dominik Habichtsberg Aug 27 '13 at 13:22

2 Answers2

0

I think this may work for you, but this solution has limitations.

If this is your HTML:

<figure class="caption">
    <a href="#" target="_blank">
        <img src="http://placehold.it/300x200" alt="">
    </a>
    <figcaption>This is a sample-caption that should wrap 
                if it's width exceeds the width of the image</figcaption>
</figure>

and apply the CSS:

figure {
    display: inline-block;
    position: relative;
    border: 1px dotted gray;
}
figure a {
    display: inline-block;
}
figure img {
    vertical-align: top;
    width: 100%;
    margin-bottom: 70px;
}

figure figcaption {
    position: absolute;
    bottom: 0;
    left: 0;
    width: inherit;
    height: 70px;
}

See fiddle demo at: http://jsfiddle.net/audetwebdesign/H3Ngz/

Comments

The major problem is that we need to allow the width of figure to shrink-to-fit the image, which is not that hard to do using inline-block elements that shrink-to-fit their content.

However, one would need to wrap the figcaption by the image so as to constrain the width. This can be done if you use absolute positioning by setting width: inherit.

This leads to another problem, what do you do about the height of figcaption?

If you have no content below the caption, you can simply let it expand downward and it will not overlap any other content.

However, because of the absolute positioning, the caption text is out of the content flow so there is way to allow for its height as the text reflows as the view port changes width.

A limited but potential fix is to specify a height for figcaption or allow for scrollbars in the caption.

The problem is that you don't know the length of the caption text...

A little bit of jQuery would fix a log of these restrictions.

Marc Audet
  • 46,011
  • 11
  • 63
  • 83
  • Hey Marc, thank you for your reply. The problem is, that the image is also scalled above it's own maximum dimensions. Please see my comment above I wrote in reply to robooneus - ... the image is maximum it's own width, or if the surrounding layer is smaller, it is max-width: 100% of the surrounding layer. If the surrounding layer is 900px in width on desktop and the image is 600px in width, the image will only be displayed with the width of 600px. If the page is viewed on a smartphone f.e. and the surrounding layer is only 300px in width, the image will be displayed with a width of 300px... – Dominik Habichtsberg Aug 27 '13 at 13:09
  • Based upon your last update I also created a fiddle to show a typical scenario... and as you wrote, the height indeed becomes a problem - damned. [http://jsfiddle.net/47mdm/](http://jsfiddle.net/47mdm/) okay - somehow, it wasn't saved ... one moment please – Dominik Habichtsberg Aug 27 '13 at 13:42
  • You write "A little bit of jQuery would fix a log of these restrictions" ... the problem is, that I hate to use JavaScript to solve styling-questions ... I think javascript should never be the answer to solve styling-issues!? – Dominik Habichtsberg Aug 27 '13 at 13:51
  • 1
    In this case, you are seeing the limitations of how CSS works. No one would blame you for using JavaScript to calculate a width as needed. You could also try the newer `calc` property but it has limited support. – Marc Audet Aug 27 '13 at 14:07
  • hm okay - I'll try to find another solution then. Worst case would be to extend my serverside pre-processing and to attach the width-parameter as fixed property to each figure-element and append the `max-width: 100%` rule to that element. Sth. like this: http://jsfiddle.net/47mdm/7/ – Dominik Habichtsberg Aug 27 '13 at 14:20
0

Try this :

figure {
    display: inline-flex;
    position: absolute;   
}

figure img {
    width: 100%;
    margin-bottom: 70px;
}
figure figcaption {
    position: absolute;
    bottom: 0;
    left: 0;
    height: 60px;
}
Purvi Barot
  • 241
  • 2
  • 9