CSS Photo-Caption Zoom

"Photo Zoom 2" (PZ2)

June 15, 2005

Pure CSS Photo-Caption Zoom (Version 2)

Demonstration of the technique

The Holy Grail of photo zooms, has been to develop a technique that allows the photo to OVERLAY the text (all previous zoom techniques, with the exception of the Stu Nicholls design - which uses two image files - PUSHES the text out of the way, on Zoom). I finally found a way to use a single image file, overlay the text AND include a hidden caption. Sweet!

Here is the result. I think you'll agree that having the photo OVERLAY the text is visually cleaner. It's also much easier on the page design, because (1) the layout doesn't shift and (2) on Zoom, the image is completely taken out of the document flow, which means it can overlay menus, headers, ANYTHING. (You can display much larger images).

As with most things, there are trade-offs and PZ2 is no exception. Mainly, the CSS & HTML is more complex. First, because the technique flips between relative and absolute positioning, an extra "container DIV" is needed, as a placeholder, to keep the text from collapsing into the void created when the image is zoomed. Also, the CSS must compensate for a Z-index on hover problem in IE. The "solution" isn't ideal, but necessary.

Still, you may find the results worth the extra CSS coding and extra HTML specifications. We do, as PZ2 is now the de-facto standard on our blog and you can find interesting examples of the code in use here, here and here

Using multiple class names, I've made the CSS code more robust, allowing toggles for (1) Brdr/noBrdr (border on/off); (2) Cap/noCap (caption on/off); and Link/noLink (cursor active/non-active for when the photo links to a site). As a result, this code is much more powerful than the original version, but also more involved to use.

(April 2006) Note: PZ2 has been superceded by PZ3 (version three) PZ3 solves the IE z-index bug, allows thumb/zoom sizes to be defined in the HTML and does it all with approximately 70% less code). At this time of writing, it is recommended over PZ2.

Notes on the method

Photo-Caption Zoom 2 (PZ2) Code


CSS Notes:

  • This is the final production code. You should be able to cut-n-paste it into an existing CSS file.
  • It allows a range of thumbnail sizes (100-350px, every 50px) and a range of zoomed image sizes (100-700px, every 50px).

/* Photo-Caption PZ2 CSS */

/* PlaceHolder Div */
.fill.left { float:left;
    margin:5px 10px 0 0; }
.fill.right { float:right;
    margin:5px 0px 5px 20px; }

/* MSIE z-index work-a-round */
/* reversing natural z-index */
.PZleft,.PZright { position:relative; }
.PZ1 { z-index:900; }
.PZ2 { z-index:890; }
.PZ3 { z-index:880; }
.PZ4 { z-index:870; }
.PZ5 { z-index:860; }
.PZ6 { z-index:850; }
.PZ7 { z-index:840; }
.PZ8 { z-index:830; }
.PZ9 { z-index:820; }
.PZ10 { z-index:810; }
.PZ11 { z-index:800; }
.PZ12 { z-index:790; }
.PZ13 { z-index:780; }
.PZ14 { z-index:770; }
.PZ15 { z-index:760; }
.PZ16 { z-index:750; }
.PZ17 { z-index:740; }
.PZ18 { z-index:730; }
.PZ19 { z-index:720; }
.PZ20 { z-index:710; }

/* Mozilla z-index bliss */
.PZleft a,.PZright a { z-index:0; }
.PZleft a:hover,.PZright a:hover
    { position:absolute; z-index:900; }

.PZoom a { position:absolute; cursor:default; }
.PZoom.Link a { cursor:pointer; }

.PZleft .PZoom a:hover,.PZright .PZoom a:hover {
    border:0; background:none;
    text-decoration:none; }

.PZright .PZoom { float:right;
    margin:5px 0px 5px 10px;
    position:relative; left:16px; top:-3px; }

.PZleft .PZoom { float:left;
    margin:0; position:relative; }
.PZleft .t100 { right:115px; }
.PZleft .t150 { right:165px; }
.PZleft .t200 { right:215px; }
.PZleft .t250 { right:265px; }
.PZleft .t300 { right:315px; }
.PZleft .t350 { right:365px; }

.t100 img { width:100px; }
.t150 img { width:150px; }
.t200 img { width:200px; }
.t250 img { width:250px; }
.t300 img { width:300px; }
.t350 img { width:350px; }
.PZoom img { border: 1px solid #369; }

.PZoom.noBrdr img { border:none; } /* border off */

.w100 a:hover,.w100 a:hover img { width:100px; }
.w150 a:hover,.w150 a:hover img { width:150px; }
.w200 a:hover,.w200 a:hover img { width:200px; }
.w250 a:hover,.w250 a:hover img { width:250px; }
.w300 a:hover,.w300 a:hover img { width:300px; }
.w350 a:hover,.w350 a:hover img { width:350px; }
.w400 a:hover,.w400 a:hover img { width:400px; }
.w450 a:hover,.w450 a:hover img { width:450px; }
.w500 a:hover,.w500 a:hover img { width:500px; }
.w550 a:hover,.w550 a:hover img { width:550px; }
.w600 a:hover,.w600 a:hover img { width:600px; }
.w650 a:hover,.w650 a:hover img { width:650px; }
.w700 a:hover,.w700 a:hover img { width:700px; }
.PZoom a:hover img,.PZoom img { margin-bottom:-3px; }

.PZoom .PZcap { display:none; }

.PZoom a:hover .PZcap {
     display:block;  background:#369;
     border:1px solid #369;
     font-size:9pt; line-height:12pt;
     color:white; margin-right:-2px; }

.PZoom a:hover .PZpad { display:block;
     padding:3px 5px 5px 5px; }

.PZoom.noCap a:hover .PZcap { display:none; }

/* ZoomOpen Positions */
/* Left */
.PZleft .PZoom a:hover { left:1px; top:1px }
/* Right */
.PZright .t100 a:hover { right:-109px; top:1px; } /*MSIE-specific*/
     .PZright>.t100 a:hover { right:-107px; }     /*Mozilla-specific*/
.PZright .t150 a:hover { right:-159px; top:1px; }
     .PZright>.t150 a:hover { right:-157px; }
.PZright .t200 a:hover { right:-209px; top:1px; }
     .PZright>.t200 a:hover { right:-207px; }
.PZright .t250 a:hover { right:-259px; top:1px; }
     .PZright>.t250 a:hover { right:-257px; }
.PZright .t300 a:hover { right:-309px; top:1px; }
     .PZright>.t300 a:hover { right:-307px; }
/* End Photo-Caption Zoom CSS */


HTML Notes:

  • This is the XHTML code from the example above.
  • The image is not linked to an external site, though it could be. Instead, the link is "killed" using "javascript:void(0)". (OKAY, some picky types might be tempted to say, "Aha, it DOES use javascript!" They'd be correct here, I suppose. But the link could be the image itself or any URL, which nullifies that complaint.)
  • NOTE: "javascript:void(0)" has been replaced by [ <a href="http://randsco.com/blank.html" onclick="return false" > ], which is a nicer way of "killing the link". JavaScript users get a killed link and if visitors have JS turned off, by chance, they'll be directed to "blank.html", which is a page that says (basically) - "You have JS off and it's recommended you have it on. Use your browser's back button to return."
  • In the above example the following toggles are set in the <p> classnames: Brdr/noBrdr; Cap(tion)/noCap(tion); Link/noLink.
  • The only height parameter that needs be set in the XHTML is the "placeholder" DIV height. (This is the thumbnail height and must be calculated prior to entering the XHTML code). This "placeholder" DIV is used to keep the text from collapsing into the void left by the image when it's ZOOMED using 'absolute' positioning (which removes it from the document flow entirely).

<!-- start PZ2 code -->

<div class="fill right" style="height:228px; width:200px;"></div>
<div class="PZ PZ1 PZright">
  <p class="PZoom t200 w400 Brdr Cap noLink">
    <a href="http://randsco.com/blank.html" onclick="return false"> <img src="http://randsco.com/_miscPgs/cssZoomPZ2.jpg" alt=" Topobo " title="" />
      <span class="PZcap"> <span class="PZpad">
        <strong>Bleeding Hearts: </strong>I really don't get it. How did they arrive at this common name for this flower?

<!-- end PZ2 code -->


Because PZ2 is more robust and more complex, a tutorial will be constructed. This tutorial will contain details, show examples and also contain b2evolution-specific instructions.

The tutorial (with special instructions for b2evolution users) is finished and can be found here.