Jump to content

responsive image captions


Peter Falkenberg Brown
 Share

Recommended Posts

Dear PW Gurus,

I'm having loads of fun upgrading to PW 2.7.2. I love it. I'm also using the CKEditor now, instead of TinyMCE, and in my newly reworked responsive website (using PocketGrid), I've run into an issue with image captions.

To scale images responsively, I'm using the max-width: 100% directive, which works fine.

When I place a caption, using PW and CKEditor, the figure / figcaption works very well...

... EXCEPT when the caption is very long. I use float: left or float:right on my images. With long captions, the text extends way past the width of the image.

- So, I messed around for hours, with CSS options, using both figure/figcaptions, and nested divs.

I was able to get the long captions to adhere to the parent image width once I used CSS settings for position: relative on the parent, and position: absolute on the caption div.

However, with that, the caption div was overwritten by the surrounding text.

=> So, it seems that the only way available is to reset the height of the parent div (or figure) of *each* of the multiple images on the page, whenever the browser is resized and/or loaded (or used with different devices), by using some type of JQuery function to click through all of the images that have a certain class.

But... after extensive Googling, I haven't found that routine, or plugin.

Does anyone have any pointers to finished code, or any thoughts? I'm not a Javascript or JQuery person.

I was surprised that I couldn't find dozens of answers about this, given the importance of responsive design and the usefulness of captions.

Thanks!!!

Peter

Link to comment
Share on other sites

Hi tpr,

Thanks... Here's a development page:

http://dev.significatojournal.com/corporate/about-us/peter-falkenberg-brown/

If you search on the word "Richard," you'll see an image of Richard the Lion Hearted, with the caption below it, with other text overlaying it.

That image is the only image that I've worked on, on that page. All the other images are either standalone, or in are in tables.

The code around that image is:

<figure class="align_left">
<img alt="Richard the Lion Hearted" src="/site/assets/files/5804/richard_coeur_de_lion.jpg" width="259" />
<figcaption>Richard the Lion Hearted, Peter's 2nd cousin, 24 times removed ...</figcaption>
</figure>

The CSS file is here:

http://dev.significatojournal.com/site/templates/styles/wcp.css

The CSS in use for the figure is:

figure {
      position: relative;
}

figure img {
      max-width: 100%;
      display: block;
      width: auto;
      height: auto;
}

figure figcaption {
      position: absolute;
      width: 100%;
      max-width: 100%;
      font-family: Verdana, Arial, Helvetica, sans-serif;
	font-size: 0.7em;
      color: #003333;
      font-style: italic;
      font-weight: normal;
	text-align: center;
	line-height: 1.2em;
	padding-top: 3px;
}

I also tried using nested divs, with position relative and absolute, and got the same behavior, with the caption text being overwritten.

My impression is that the parent div (or figure) needs to have a height attribute that includes the height of the caption, so that text wraps around the caption.

Without that height value, the caption, which is absolute, can't have text wrapped around it.

The primary issues are:

- there is more than one image with captions on the page

- as the page is viewed in responsive devices, the image sizes will scale down, and thus the caption widths *and heights* need to scale as well, and thus the image sizes are not known in advance, and will change.

... and, the images on that page are a mess, because the prior hard-coded table widths are conflicting with the new responsive design.

Thanks!

Peter

Link to comment
Share on other sites

Couldn't fix it myself but this one works:

figure {
  display: table;
}
figcaption {
  display: table-caption;
  caption-side: bottom;
}

http://stackoverflow.com/a/21533437/4731155

Also remove position: absolute from figcaption to make it work.

CSS caption-side is supported from IE8 so it should work everywhere nowadays, but check it yourself to make sure.

https://msdn.microsoft.com/en-us/library/cc304060%28v=vs.85%29.aspx?f=255&MSPPError=-2147217396

Link to comment
Share on other sites

Dear tpr,

I just tried it again, with the same url as above, with the Richard image, using this code:

figure {
      display: table;
      max-width: 100%;
}

figcaption {
      display: table-caption;
      caption-side: bottom ;

      font-family: Verdana, Arial, Helvetica, sans-serif;
	font-size: 0.7em;
      color: #003333;
      font-style: italic;
      font-weight: normal;
	text-align: center;
	line-height: 1.2em;
	padding-top: 3px;
}

but when I size my Firefox browser all the way down to the smallest possible width, the image and caption are wider than the column, and stick out past the right margin.

Yours,

Peter

Link to comment
Share on other sites

I see, this didn't came up in Chrome.

This seems to fix it:

- figure: add display: inline-block;

- figcaption: add width: 100%;

Edit:

Unfortunately this breaks Chrome... I guess you should add new styles using media queries.

Link to comment
Share on other sites

Dear tpr,

In Firefox it looks like it worked because of the combination of inline-block in the figure and display: table-caption; in the figcaption.

But yes, in Chrome, the caption has a weird right hand margin that takes up 1/2 the space of the cell.

I suppose media queries might do something, but the other solution would be to dynamically assign figure heights (or div heights) by using javascript. I think. :-)

I'm amazed that this hasn't been solved in responsive-web-design land already.

Thanks for your help on this...

If anyone else has light bulbs going off, I'd love to hear about it.

Peter

Link to comment
Share on other sites

Hi Peter,

Take a look at this figcap test example and see if it is what you are looking for.

I copied the portion of your original site referring to Richard for the content.

I use bootstrap myself, but you could adapt your styles easily enough. All the styles are inline rather than a separate file for quick reference.

I've tested this in FF, Chrome, and Opera. I don't use internet exploder so I'll leave that up to you. :)

Link to comment
Share on other sites

Dear Rick,

Thanks for this effort! At first, it seemed to be the answer, but I discovered that it only works when the

percentage of max-width is smaller than the image in relationship to the page.

For example, I changed my CSS to:

figure { max-width: 50%; }

and then, when I view the Richard image at full desktop size, the caption text

goes out to the 50% width, leaving the image at its native, smaller width.

Even if I used 25%, it wouldn't work if the image was only 20% of the width of the page.

But... you were close! :-)

Peter

Link to comment
Share on other sites

Things that make you go, "Hmmm".  :)

A few options are:

1. Using responsive tables may work, but I suspect it will yield the same results as you are trading one container for another, and the same issue as described in #2 remains.

2. You may want to use images of much larger dimensions, initially set for the largest target display resolution. The issue appears that you're wanting a subordinate element to conform to it's parent when the parent itself no longer conforms -- hence the Cascade in Css appearing to fail* after a certain point.

3. Lastly, javascript can adjust the desired elements of a certain class/id/name. This was the method commonly used to mask issue #2 before browsers learned to parse more specific css directives and windowing events, such as resizing.

* Technically, css is not failing here. If you were to display a background color for each element, you will see that they occupy the desired space. The figure image should be enlarged to fill the available space to aesthetically resolve this issue.

Link to comment
Share on other sites

Dear Martijn and Rick,

Thank you both for your input.

Rick: I don't want to force images to be a certain size just to make things responsive - I'd rather use a system to match the caption block

to whatever size the image is.

- I tried my very first JQuery routine, and it kind of sort of works in Firefox, but it breaks in Chrome, with one image not working at all, and one image quirky.

If you search on the word "Carl" and then "Richard", you'll see that I moved two images to the "figure" method.

(The Carl image has the grey caption: "Carl Falkenberg Brown, (Peter's Father; during WWII)".)

I added a yellow background to the figures, and a grey background to the caption, to see things better.

Here's my code. I made the figures 50% max-width, so that they didn't scrunch the wrap-around text into a tiny column for small devices.

CSS:

figure {
      position: relative;
      max-width: 50%;
      background-color: yellow;
}

figure img {
      max-width: 100%;
      display: block;
      width: auto;
      height: auto;
}

figure figcaption {
      position: absolute;
      width: 95%;
      max-width: 95%;
      font-family: Verdana, Arial, Helvetica, sans-serif;
      font-size: 0.7em;
      color: #003333;
      font-style: italic;
      font-weight: normal;
      text-align: center;
      line-height: 1.5em;
      padding-top: 3px;
      padding-bottom: 3px;
      padding-left: 2.5%;
      padding-right: 2.5%;
      margin-bottom: 5px;
      background-color: #F0F0F0;
}

Here's the JQuery, loaded in the <head> section, looping through all "figure" elements:

<script>

$( window ).ready(function() {

      $("figure").each(function(){

            child = $( this ).children("figcaption");

            figure_height     = $( this ).height();
            figcaption_height = child.height();

            $( this ).height( figure_height + figcaption_height + 10 );

      });
});

</script>

I tried the "resize" event instead of "ready", but it created what looked like a cascade of ever-growing heights - perhaps because of the frequency that resize is triggered?

So, then I used "ready."

Again, this is my first stab at Jquery, so I'm probably missing something.

But it seems like it might be going in the right direction....

Maybe?

Yours,

Peter

Link to comment
Share on other sites

Dear All,

I simplified the method above, and instead of using the figure / figcaption method, I used

a single <div> with the class "caption_left". Then, I placed a <br> code after the image, and pasted the

caption after that -- all in the same div.

It seems to work quite well in FF, IE, Chrome, and Opera, except that the width of the div

has a delay in its adjustment until the image fully loads. I used a combination of CSS and

JQuery code to make the div width the same as the image, so that the captions would

follow the image width.

Because there's no child div to mess with (i.e. figcaption), the vertical div overwrite issue is no longer a problem.

Here's my code.

CSS:

.caption_left {
      float: left;
      max-width: 50%;
      height: auto;
      font-family: Verdana, Arial, Helvetica, sans-serif;
      font-size: 0.7em;
      color: #003333;
      font-style: italic;
      font-weight: normal;
      text-align: left;
      line-height: 1.5em;
      margin-right: 10px;
}

JQuery:

<script>

      $(window).load(function() {

            $(".caption_left").each(function(){

                  image_width = $( this ).find("img").width();
                  $( this ).width( image_width );
            });
      });

</script>

[EDIT]

Because I have both a caption_left and caption_right style, I changed the JQuery to use a wildcard for "caption_":

<script>

      $(window).load(function() {

            $('[class*="caption_"]').each(function(){

                  image_width = $( this ).find("img").width();
                  $( this ).width( image_width );
            });
      });

</script>

[END OF EDIT]

[sECOND EDIT]

I used the above method on a complex page of images with long captions, and sidebar divs

which had images and captions inside them. All worked well, except that at the end of the image

resizing, my page had blank spaces at the bottom of the main content column, because the images

inside the column had resized upward.

Adding a window.resize command fixed it, thus:

<script>

      $(window).load(function() {

            $('[class*="caption_"]').each(function(){

                  image_width = $( this ).find("img").width();
                  $( this ).width( image_width );
            });

            $(window).resize();

      });

</script>

[END OF SECOND EDIT]

Then, in site/modules/InputfieldCKEditor/mystyles.js, I added the two caption styles so that

I could easily apply that style to a div in the body field, into which I would add the image:

CKEDITOR.stylesSet.add( 'mystyles', [
 { name: 'Caption Left', element: 'div', attributes: { 'class': 'caption_left' } },
 { name: 'Caption Right', element: 'div', attributes: { 'class': 'caption_right' } },

The only gotcha that I can see is that when the images have long captions, the div widths take a moment to adjust

down to the image widths, after the images load.

* Anyone know how to make that faster?

* Any thoughts on the solution above?

=> I also noted that my previous figure/figcaption styling messed up the magnific-popup styles that I used, based on this post:

http://processwire.com/talk/topic/5260-how-to-hack-core-or-hook-to-add-classinputfieldfilelink-to-inserted-images-that-link-to-larger-versions/#entry50703

... suggesed by Martijn and Teppo. So, I deleted my figure / figcaption styles, and the popups went back to normal.

Peter

  • Like 1
Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
 Share

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...