Accessible Off-canvas Grid Gallery with jQuery and CSS3

File Size: 4.12 KB
Views Total: 4163
Last Update:
Publish Date:
Official Website: Go to website
License: MIT
   
Accessible Off-canvas Grid Gallery with jQuery and CSS3

A jQuery & CSS3 based accessible off-canvas grid gallery that reveals the large version of your image as you click on a thumbnail and pushes the thumbnail grid to the left.

How to use it:

1. Create a list of thumbnails for the grid gallery as follow.

<main role="main" id="main">
  <section class="tiles-a">
    <ul>
      <li> <a href="#" style="background: url('thumb-1.jpg'); background-size: cover;" 
              aria-controls="aside" 
              aria-expanded="false">
        <div class="details visually-hidden"> <img src="large-1.jpg" alt="Image Alt">
          <div class="text-copy wrapper">
            <h3>Title 1</h3>
            <p>Descriptiont 1</p>
          </div>
        </div>
        </a> 
      </li>
      <li> <a href="#" style="background: url('thumb-2.jpg'); background-size: cover;" 
              aria-controls="aside" 
              aria-expanded="false">
        <div class="details visually-hidden"> <img src="large-2.jpg" alt="Image Alt">
          <div class="text-copy wrapper">
            <h3>Title 2</h3>
            <p>Descriptiont 2</p>
          </div>
        </div>
        </a> 
      </li>
      <li> <a href="#" style="background: url('thumb-3.jpg'); background-size: cover;" 
              aria-controls="aside" 
              aria-expanded="false">
        <div class="details visually-hidden"> <img src="large-3.jpg" alt="Image Alt">
          <div class="text-copy wrapper">
            <h3>Title 3</h3>
            <p>Descriptiont 3</p>
          </div>
        </div>
        </a> 
      </li>
    </ul>
  </section>
</main>

2. Create an off-canvas area to place the large images.

<aside role="complementary" id="aside" 
       aria-hidden="true" 
       aria-expanded="false"> 
  <a href="#" class="close">
    <img src="close.svg" alt="Close button">
      <span class="visually-hidden">Return to main content
      </span>
  </a>
  <div class="aside--details" tabindex="0" 
       aria-live="polite" 
       aria-atomic="true" 
       aria-label="Image details"> 
  </div>
</aside>

3. The primary CSS / CSS3 styles.

* { box-sizing: boder-box; }

body { margin: 0; }

#main {
  position: relative;
  z-index: 20;
  background: #fff;
  -webkit-transition: -webkit-transform .6s ease;
  transition: transform .6s ease;
}
@media (min-width: 640px) {

#main { padding: 1em; }
}

.fake-section {
  background: #eee;
  height: 300px;
}

.tiles-a {
  width: 100%;
  position: relative;
  overflow: hidden;
}

.tiles-a ul {
  margin: 0;
  padding: 0;
}

.tiles-a li { list-style: none; }
@media (min-width: 640px) {

.tiles-a li {
  float: left;
  width: 33.33%;
}
}

.tiles-a a {
  margin: 1em;
  display: block;
  background: #222;
  padding-top: 73%;
  height: 0;
}

#aside {
  position: fixed;
  top: 0;
  right: 0;
  width: 60%;
  height: 100%;
  background: #eee;
  overflow-y: scroll;
  z-index: 10;
}

#aside img {
  width: 100%;
  height: auto;
  vertical-align: top;
}

#aside .wrapper { padding: 1em; }

#aside .close {
  width: 25px;
  display: block;
  position: absolute;
  top: 1em;
  right: 1em;
  background-color: rgba(0, 0, 0, 0.5);
  border-radius: 50%;
}

.show-detail { overflow: hidden; }

.show-detail #main {
  -webkit-transform: translateX(-60%);
  -ms-transform: translateX(-60%);
  transform: translateX(-60%);
}

.visually-hidden {
  position: absolute;
  overflow: hidden;
  clip: rect(0 0 0 0);
  height: 1px;
  width: 1px;
  margin: -1px;
  padding: 0;
  border: 0;
}

4. Include jQuery library and the toggleAria.js script at the bottom of the web page.

<script src="jquery-2.1.4.min.js"></script> 
<script src="toggleAria.js"></script> 

5. Active the off-canvas grid gallery.

var $parent = $("#main"),
    $aside = $("#aside"),
    $asideTarget = $aside.find(".aside--details"),
    $asideClose = $aside.find(".close"),
    $tilesParent = $(".tiles-a"),
    $tiles = $tilesParent.find("a"),
    slideClass = "show-detail";

// tile click
$tiles.on("click", function(e){
  e.preventDefault();
  e.stopPropagation();
  if(!$("html").hasClass(slideClass)){
    $tiles.removeClass("active");
    $(this).addClass("active");
    $(this).attr("aria-expanded","true");
    loadTileData($(this));
  }else{
    killAside();
    $(this).attr("aria-expanded","false");
  }
});

// kill aside
$asideClose.on("click", function(e){
  e.preventDefault();
  killAside();
});

// load data to aside
function loadTileData(target){
  var $this = $(target),
      itemHtml = $this.find(".details").html();
      $asideTarget.html(itemHtml);
      showAside();
}

// show/hide aside
function showAside(){
  if(!$("html").hasClass(slideClass)){
    $("html").toggleClass(slideClass);
    $aside.attr("aria-hidden","false");
    focusCloseButton();
  }
}
    
// handle esc key
window.addEventListener("keyup", function(e){

  // grab key pressed
  var code = (e.keyCode ? e.keyCode : e.which);
  
  // escape
  if(code === 27){
    killAside();
  }

}, false);

// kill aside
function killAside(){
  if($("html").hasClass(slideClass)){
    $("html").removeClass(slideClass);
    sendFocusBack();
    $aside.attr("aria-hidden","true");
    $tiles.attr("aria-expanded","false");
  }
}

// send focus to close button
function focusCloseButton(){
  $asideClose.focus();  
}

// send focus back to item that triggered event
function sendFocusBack(){
  $(".active").focus();
}

// handle body click to close off-canvas
$parent.on("click",function(e){
  if($("html").hasClass(slideClass)){
    killAside();
  }
});

This awesome jQuery plugin is developed by joe-watkins. For more Advanced Usages, please check the demo page or visit the official website.