mattgadient.com

Getting shadowbox working with HTML5 (how to make it validate)

Update: As Dave mentions in the comments below, this change can prevent shadowbox from triggering in IE7. 

If you’ve been delving into the process of converting any of your pages or sites into HTML5, you’ve probably run into a few… headaches along the way.

If you’ve been using shadowbox (Web Archive) and trying to validate through the w3c’s validator, one of these headaches might look like this:

Shadowbox not validating as html5

The message is “Bad value shadowbox for attribute rel on element a: Keyword shadowbox is not registered.

What does this mean? Well, there are only certain things you’re technically allowed to put in a “rel” tag. For example, the following is okay:

<a href=”image.png” rel=”nofollow”>

“nofollow” is a valid “rel” attribute. You’ll find other valid attributes in the links provided by the W3C validator. Unfortunately, you won’t find things like lightbox, shadowbox, etc as valid rel attributes. And as you’re probably aware, the W3C’s validator can be rather picky.

The first thing I tried was looking for an alternative. Fancybox ended up being one of the few which appeared to use id’s and classes instead of rel, but for the life of me, I couldn’t get it working. Maybe it doesn’t recognize the new html5 doctype (it mentions it’s picky). Or maybe I just messed up trying to implement it (yeah yeah, probably this).

What I tried next, and what ended up working, was looking through shadowbox’s js file. I figured that “rel” must be mentioned in the file somewhere, and maybe it would be as simple as changing anything that says “rel” into “class“.

As it turned out, it was that easy.

There were 2 instances of “rel“, which I changed into “class“. After making the changes, saving the file, editing my html to change every rel=”shadowbox” into class=”shadowbox”, and re-validating through W3C, I got the following:

Success!
(the 1 warning was the W3C’s standard message about the HTML5 validator being experimental right now)

If you’re looking to do the same thing, it’s pretty easy. The shadowbox.js file is minified, so rather than hurting your eyes trying to find the right places to change, simply use your favorite editor to do a quick search (and replace) of “rel” to “class”. Save it, update your html, and you should be golden.

Of course, if you upgrade Shadowbox.js in the future, you’ll have to remember make the change to the new version.

Incidentally, whether it’s worth it to begin with is something you’ll have to decide on your own – being 100% compliant isn’t necessarily critical – I mean… I don’t forsee your site crashing browsers or even rendering wrong simply because you have rel attributes you technically shouldn’t. And heck, even Google’s main search page fails the html5 check (with 37 errors no less).

If that nice green validation bar makes you feel all warm and fuzzy though (I know it does for me!), hopefully the above instructions help you out.

  • Juan

    You can put the shadowbox.js modified?

  • Juan

    this works!, thanks a lot man

    • Juan:

      Glad you got it working!

      To respond to your previous question, yes the shadowbox.js license allows you to modify it to suit your own purpose. However, it doesn’t allow redistribution (otherwise I would have zipped/uploaded the modified version here to make it a little easier for people). That said, if somebody’s having a really tough time doing the search/replace in their shadowbox.js file (remember, you just have to edit it and find “rel” and change it to “class” in 2 places), leave a comment and I’ll see what I can do to help you out.

  • Esoj

    Thanks for posting this. Great work!

  • Boris Penev

    This is one way to do it, with some disadvantages:

    1) You are messing with the source of the application.
    2) If you want to use shadowbox for a gallery, class=”shadowbox[gallery]” won’t work as class names can’t have brackets.

    There is another workaround:

    Initialize shadowbox and then just call it on a custom element.

    Shadowbox.init({
    skipSetup: true
    });

    Shadowbox.setup(“a.overlay”, {
    gallery: “gallery”
    });

    • Dave

      Could you elaborate a little please.

      In your example would give a link the class=”overlay” to trigger shadowbox, or?

      Thanks.

    • I use galleries and tried it with class=”shadowbox[gallery]” and it works fine!

      Thanks for the tip, awesome. I prefer Shadowbox over other solutions because it’s VERY keyboard accessible…thus you’re not setting up keyboard-only users to get trapped on the site, unlike some others.

  • Dave

    So I did what you said, but I found 14 instances of “rel” in the shadowbox.js file. Should I be looking for something more specific? Any thoughts?

    Thanks!
    Dave

    • Dave:

      Not 100% sure on this, but I’m guessing that you’ve enabled a few more types of content than I did when downloading the shadowbox.js file (I only had to make 2 changes vs your 14), so you’ve probably got a larger/different js file.

      That said, to be a little more specific in the search/replace, you can *try* searching for occurrences of:
      getAttribute(“rel”)

      …and try changing them to:
      getAttribute(“class”)

      Make sure you’ve backed up the original, as this is going largely from memory, and doesn’t amount to much more than a guess.

      Alternately, you could simply try changing all 14 occurrences of “rel”. After making the rel -> class change in my file, I have 0 occurrences of rel left anyway, so it may be worth a shot. Not much harm in giving it a shot anyway (since you can just replace with the original file if things go wonky).

      Good luck!

  • Dan

    Awesome! This is JUST what I needed to get it working and validated! I’m a beginner when it comes to using javascript, query etc., so this guide was perfect for getting it sorted. Cheers!

  • Ikke

    Hi
    for some reason i still cant get it to work
    though i changed rel=link.getAttribute(“class”);

  • Dave

    Matt,

    Do you get this to work with ie7 ?

    I modified the 2 instances of “rel”, and sure enough, it works with, and validates, except for ie7 where it breaks shadowbox for me. (probably ie6 too, but I don’t care..)

    • Dave:

      Good catch.

      Definitely isn’t working in IE7 (it’ll just go to the image instead of triggering SB). And I haven’t the faintest idea as to what might be causing it either (whether it’s an IE7 thing, or whether there’s a workaround in shadowbox.js that gets broken by the change).

      I almost wonder if perhaps that’s the reason the vast majority of alternatives also use “rel” by default. Again, did a bit of peeking, and again found that fancybox is one of the few that’ll do it without “rel” by default (and it works on IE7). Except even on their site, they tend to use ID‘s instead of classes. Only in their FAQ do they make mention of using classes. And for all I know, maybe switching to classes would break IE7 there too.

      I should probably mention that there *is* a fancybox plugin for wordpress, which I’ve tested to have worked on another site (I use a different one here). Uses ID’s, but all the images are auto-numbered by WP anyway, so it’s dead-easy (just enable the plugin, configure anything you want in the options, and you’re done – any images you have & put up are auto-fancyboxed). Works in IE7 too. But getting the rest of WordPress to validate as HTML5…. that’s usually a whole other story.

      • Dave Pitman

        Thanks for the confirmation, Matt.

        I don’t know what is different about ie7 either. That is why I asked the poster above (Boris) about the js option. I don’t have the skills to write js to trigger shadowbox via a specific object/event which is what he seems to be referring to.

        I will have a look at fancybox.

        I have been somewhat successful getting WP sites to validate by adding various filters in functions.php to strip out some of the offending markup that WP spits out by default.

        For example (http://www.ridgestyle.com)

        Shadowbox’s “rel” attribute is one of the last things left. As you say, it works great, but I would also like it to validate.

        Anyway, I’ll check back here from time to time to see what you’ve found.

        Thanks.

  • james

    thanks mate, worked great 🙂

  • Thankyou So Much Dude It works Great Thumbs Up to you (y)

  • Matin Shaikh

    Follow two simple steps

    1.Replace rel attribute to your custom attribute.

    Example.


    2.Go to your shadowbox.js code.
    A.find var rel = link.getAttribute(‘rel’);and replace it with var rel = link.getAttribute(‘data-shadow’);
    B.find rel = el.getAttribute(“rel”); and replace it with rel = el.getAttribute(“data-shadow”);

  • David Dantes

    Thank you for this article — exactly what I was looking for. I’m using shadowbox v3.03, and there are no instances of
    “rel” in shadowbox.js. If you have a version of that file with such references which can be replaced with “class”, could you email it please?

  • David Dantes

    Sorry — please disregard my question. I made a mistake in my search of the shadowbox.js file. The solution is working fine.

  • Brian

    Hi,

    I’m using Shadowbox 3.03 and I have to manage 3 galleries, originally named rel=”shadowbox[web]”, rel=”shadowbox[print]”, rel=”shadowbox[motion]”.

    1) I have replaced all rel=”shadowbox[web]” with class=”shadowbox[web]”.

    In shadowbox.js:
    1) I have replaced var rel = link.getAttribute(“rel”); with var rel = link.getAttribute(“class”);.
    2) I have replaced rel = el.getAttribute(“rel”); with rel = el.getAttribute(“class”);.

    3) I have replaced Shadowbox.init(); with:

    Shadowbox.init({
    skipSetup: true
    });

    Shadowbox.setup(“a.overlay”, {
    gallery: “web”
    });

    Then it doesn’t work. When I click on an image, all I get is the image opened in my browser…
    What is wrong with my changes?

    Thx for the help!

    • Brian: It looks like you’re following Boris’s recommendation. As I understand it, you should only be doing your Step 3 in that case (don’t do the search/replace to change the rel stuff to the class stuff due to the issue Boris mentioned with square brackets in a class name). I’m not sure specifically if additional code is required to call it on a custom element in the HTML, but if Boris comes by again, maybe he can help clarify there.

  • Brian

    So, I made some changes, but it still doesn’t work:

    1) My 3 galleries class=”shadowbox[web]“, class=”shadowbox[print]“ and class=”shadowbox[motion]“
    2) Then, I have recovered my old shadowbox.js with var rel = link.getAttribute(“rel”); etc…

    3) Finally, I have replaced Shadowbox.init(); with:

    Shadowbox.init({
    skipSetup: true
    });

    Shadowbox.setup(“a.overlay”, {
    gallery: “web”
    });

    Shadowbox.setup(“a.overlay”, {
    gallery: “print”
    });

    Shadowbox.setup(“a.overlay”, {
    gallery: “motion”
    });

    But nothing new. Always it opens my picture in a new window instead of triggering shadowbox…
    Any idea? 🙂

  • Brian

    It works! I forgot to insert all the Shadowbox.setup stuffs in a window.onload = function()
    Damn! Working too fast, didn’t see it…

    So, the final code for multiple galleries HTML5 compatible:

    Assuming I have my images encapsulated in a class=”shadowboxWeb”, a class=”shadowboxPrint”, a class=”shadowboxMotion”

    Shadowbox.init({
    skipSetup: true
    });

    window.onload = function() {

    Shadowbox.setup(“a.shadowboxWeb”, {
    gallery: “web”
    });

    Shadowbox.setup(“a.shadowboxPrint”, {
    gallery: “print”
    });

    Shadowbox.setup(“a.shadowboxMotion”, {
    gallery: “motion”
    });

    };

    And it works fine!
    Hope this helps 😉

    P.S: sorry for multiple comments, just delete the others 😉

  • Thank you, Matt for this wonderful coding. It worked