City of Ghent Style Guide

Image gallery

When to use this component

Use the image gallery component on detail pages to present a set of images in a modal image gallery format (lightbox) using thumbnails of the first images.

When not to use this component

Do not use the image gallery component to present a set of images that should be all visible at once without any interaction except scrolling.

Do not use the image gallery component on overview pages or filter pages. Only use the image gallery component on detail pages.

How it works

  • An image gallery is a list of images presented by using figures.
  • The images can have different aspect ratios.
  • Thumbnails are used to preview the set of images.
  • The thumbnails must have aspect ratio 8:5.
  • The number of thumbnails that are shown depends on the device’s screen resolution.
  • Up to 5 thumbnails can be shown.
  • If there are hidden images an overlay is placed on the last visible thumbnail indicating the total number of images.
  • Clicking a thumbail or the overlay on the last visible image shows all images in a modal image gallery (lightbox). The images are all fully shown in their respective aspect ratio.

Implementation

  • Using the class ‘image-gallery’ on the list element triggers lightbox initialisation on page load.

Accessibility

  • The images are placed in a unordered list.
  • When a image caption is provided, this is also used as aria-label for the lightbox link.
  • All lightbox links are described by a hidden span to identify it’s purpose (e.a.: ‘open gallery), add this to the bottom of your page template (above scripts).
  • Hidden images are not only visually hidden.
  • The lightbox can be closed by use of the escape key.
  • Navigating through images in the lightbox can be done by using the arrow keys.
  • The focus cannot be placed on elements which are hidden from view by the lightbox.
{% extends items ? '@image-gallery--multiple' : '@image-gallery--single' %}
<div class="image-gallery--wrapper single image-gallery--secondary">
    <div class="image-gallery js-lightbox">
        <a href="https://via.placeholder.com/800x500&text=8:5+(800x500)" aria-labelledby="image-gallery__open-gallery" class="gallery-link">
            <figure>
                <div class="image-wrapper" data-ratio="8:5"><img src="https://via.placeholder.com/800x500&text=8:5+(800x500)" alt="placeholder image alternative text" /></div>
                <figcaption>image caption</figcaption>
            </figure>
        </a>
    </div>
</div>
<!-- Add this to the bottom of your page template, above scripts -->
<!-- <span hidden id="image-gallery__open-gallery">open gallery</span> -->
{
  "src": "https://via.placeholder.com/800x500&text=8:5+(800x500)",
  "alt": "placeholder image alternative text",
  "caption": "image caption",
  "type": "secondary"
}
  • Content:
    .image-gallery {
      @include clearfix();
    
      position: relative;
      margin: 0;
      padding: 0;
      text-align: center;
    
      li {
        display: inline-block;
        width: calc((100% / 1) - #{$gutter-width});
        margin: calc(#{$gutter-width} / 2);
        float: left;
    
        // mobile first: only show two images
        &:not(.image-gallery__show-more):nth-of-type(n + 3),
        &:first-of-type:nth-last-of-type(-n+3) ~ .image-gallery__show-more {
          display: none;
        }
      }
    
      .image-gallery__show-more {
        position: absolute;
        right: 0;
        bottom: 0;
        width: calc((100% / 1) - #{$gutter-width});
        margin: calc(#{$gutter-width} / 2);
        padding-bottom: calc(((100% / 1) - #{$gutter-width}) / 1.6);
        pointer-events: none;
    
        &::before {
          @include theme('background-color', 'color-primary--darken-3', 'image-gallery-show-more-background-color');
    
          position: absolute;
          top: 0;
          left: 0;
          width: 100%;
          height: 100%;
          content: '';
          opacity: .7;
        }
      }
    
      .show-more__content {
        @include theme('color', 'color-secondary', 'image-gallery-show-more-color');
        @include bold-text;
    
        display: flex;
        position: absolute;
        flex-direction: column;
        align-items: center;
        justify-content: center;
        width: 100%;
        height: 100%;
        font-size: .9rem;
        line-height: 1;
        text-align: center;
    
        .show-more__total {
          width: 100%;
          height: 35%;
          margin-bottom: 5%;
          background: no-repeat center center url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='132' height='100' viewBox='0 0 132 100'%3E%3Cpath fill='%23FFF' fill-rule='evenodd' d='M76.645 15.603a2.13 2.13 0 0 0-2.129-2.128H57.484a2.13 2.13 0 0 0-2.13 2.128 2.13 2.13 0 0 0 2.13 2.127h17.032a2.13 2.13 0 0 0 2.13-2.127zm4.258 0c0 3.519-2.865 6.383-6.387 6.383H57.484c-3.522 0-6.387-2.864-6.387-6.383 0-3.52 2.865-6.383 6.387-6.383h17.032c3.522 0 6.387 2.864 6.387 6.383zm9.936 49.645a2.13 2.13 0 0 0-4.258 0 20.431 20.431 0 0 1-6.028 14.543 2.126 2.126 0 0 0 1.504 3.632c.545 0 1.09-.207 1.506-.623 4.692-4.69 7.276-10.922 7.276-17.552zm36.903-40.425c0-4.301-3.503-7.802-7.807-7.802H94.387c-.917 0-1.73-.586-2.02-1.454-.037-.112-3.91-11.312-12.173-11.312H51.806c-8.263 0-12.136 11.2-12.175 11.315a2.132 2.132 0 0 1-2.018 1.451H12.065c-4.304 0-7.807 3.501-7.807 7.802v5.804c.223-.08.46-.13.71-.13H22a2.13 2.13 0 0 1 2.129 2.127A2.13 2.13 0 0 1 22 34.752H4.968c-.25 0-.487-.051-.71-.13v7.222h12.774a2.13 2.13 0 0 1 2.13 2.128 2.13 2.13 0 0 1-2.13 2.127H4.258v7.223c.223-.08.46-.13.71-.13h12.774a2.13 2.13 0 0 1 2.129 2.127 2.13 2.13 0 0 1-2.13 2.128H4.969c-.25 0-.487-.051-.71-.13v22.825c0 4.3 3.503 7.801 7.807 7.801h27.634c-5.273-6.093-8.473-14.025-8.473-22.695 0-19.163 15.599-34.752 34.774-34.752s34.774 15.59 34.774 34.752c0 8.67-3.2 16.602-8.473 22.695h27.634c4.304 0 7.807-3.5 7.807-7.801v-55.32zM66 95.745a30.379 30.379 0 0 0 19.343-6.93c.172-.235.39-.428.643-.575 6.437-5.595 10.53-13.816 10.53-22.992 0-16.815-13.69-30.496-30.516-30.496s-30.516 13.68-30.516 30.496c0 9.176 4.093 17.397 10.53 22.992.253.147.471.342.643.576A30.386 30.386 0 0 0 66 95.745zm39.742-82.979h8.516v-2.128a3.55 3.55 0 0 0-3.548-3.546h-1.42a3.55 3.55 0 0 0-3.548 3.546v2.128zM132 24.823v55.319c0 6.648-5.412 12.057-12.065 12.057H87.923C81.938 97.072 74.306 100 66 100c-8.306 0-15.938-2.928-21.923-7.801H12.065C5.412 92.199 0 86.79 0 80.142v-55.32c0-6.648 5.412-12.056 12.065-12.056h24.094C37.711 9.126 42.531 0 51.806 0h28.388c9.275 0 14.095 9.126 15.647 12.766h5.643v-2.128c0-4.3 3.503-7.801 7.806-7.801h1.42c4.303 0 7.806 3.5 7.806 7.801v2.128h1.42c6.652 0 12.064 5.408 12.064 12.057zm-63.871 17.73A2.13 2.13 0 0 1 66 44.681c-11.348 0-20.58 9.227-20.58 20.567a2.13 2.13 0 0 1-4.259 0c0-13.686 11.144-24.822 24.839-24.822a2.13 2.13 0 0 1 2.129 2.127z'/%3E%3C/svg%3E%0A");
          background-size: contain;
          font-size: 0;
        }
    
        i {
          font-size: 1.5rem;
          vertical-align: middle;
        }
      }
    
      a.gallery-link {
        @include reset-link-background;
        display: inline-block;
        width: 100%;
        margin: 0;
        padding: 0;
        font-weight: normal;
        text-decoration: none;
    
        &::after {
          content: none;
        }
    
        &:hover,
        &:focus {
          background-color: transparent;
        }
      }
    
      @include phablet {
        // two on each row
        // |____||____|
        li {
          width: calc((100% / 2) - #{$gutter-width} - .5px);
        }
    
        .image-gallery__show-more {
          width: calc((100% / 2) - #{$gutter-width});
          padding-bottom: calc(((100% / 2) - #{$gutter-width}) / 1.6 - .5px);
        }
      }
    
      @include tablet {
        // only show first four images
        li:not(.image-gallery__show-more):nth-of-type(-n + 4) {
          display: inline-block;
        }
    
        // hide 'show more' if there are no more than four images
        li:first-of-type:nth-last-of-type(-n+5) ~ .image-gallery__show-more {
          display: none;
        }
    
        // triple
        // first row: three
        // |__||__||__|
        // subtract .33px to deal with incorrect IE rounding
        li:first-of-type:nth-last-of-type(4),
        li:first-of-type:nth-last-of-type(4) ~ li {
          width: calc((100% / 3) - #{$gutter-width} - .33px);
        }
      }
    
      @include desktop {
        // quintuple
        // first row: two
        // second row: three
        // |____||____|
        // |__||__||__|
        // subtract .33px to deal with incorrect IE rounding
        li:first-of-type:nth-last-of-type(n + 6) ~ li:nth-of-type(n + 3) {
          width: calc((100% / 3) - #{$gutter-width} - .33px);
        }
    
        // only show first five images
        li:not(.image-gallery__show-more):nth-of-type(-n + 5) {
          display: inline-block;
        }
    
        // hide 'show more' if there are no more than five images
        li:first-of-type:nth-last-of-type(-n+6) ~ .image-gallery__show-more {
          display: none;
        }
    
        // subtract .33px to deal with incorrect IE rounding
        li:first-of-type:nth-last-of-type(n + 6) ~ .image-gallery__show-more {
          width: calc((100% / 3) - #{$gutter-width} - .33px);
          padding-bottom: calc(((100% / 3) - #{$gutter-width} - .33px) / 1.6);
        }
      }
    
      // Alternative styling
      &--secondary {
        .show-more__content {
          @include theme('color', 'color-primary', 'link-color');
    
          display: inline-block;
          margin-top: .3rem;
          text-align: right;
    
          .show-more__total {
            display: none;
          }
        }
    
        // single image styling
        .image-gallery {
          text-align: left;
    
          figcaption {
            display: none;
          }
    
          .gallery-link {
            @include mobile {
              max-width: 270px;
            }
    
            @include phablet {
              width: calc(100% / 2 - 1vw);
            }
    
            @include desktop {
              width: calc((100% / 3 - #{$gutter-width} / 1.5) - .33px);
              max-width: 100%;
              margin: calc(#{$gutter-width} / 2) 0 0;
            }
    
            width: 100%;
            margin: 1vw 0 $gutter-width;
          }
    
          // show more content: base settings
          .image-gallery__show-more {
            padding-bottom: 2.3em;
    
            &::before {
              background-color: transparent;
            }
          }
        }
    
        // multiple image styling
        ul.image-gallery {
          margin: 0 -1vw;
    
          // overrule single image styling
          .gallery-link {
            width: 100%;
            margin: 0;
          }
    
          li {
            width: calc(100% - 2vw);
            margin: 1vw;
    
            .gallery-link {
              padding-bottom: 2.3em;
            }
    
            &:first-of-type:nth-last-of-type(-n+3) ~ .image-gallery__show-more {
              display: block;
            }
    
            // only two images
            &:not(.image-gallery__show-more):nth-of-type(n + 2) {
              display: none;
            }
    
            // hide show more if there is only one image
            &:first-of-type:nth-last-of-type(-n+2) ~ .image-gallery__show-more {
              display: none;
            }
          }
    
          // Media Queries
          @include mobile {
            max-width: 13.5rem;
          }
    
          @include phablet {
            max-width: calc(13.5rem * 2 + 2vw);
    
            li {
              &,
              &:first-of-type:nth-last-of-type(4) ~ li,
              &:first-of-type:nth-last-of-type(4) {
                width: calc((100% / 2) - 2vw);
              }
    
              .gallery-link {
                padding: 0;
              }
            }
    
            // only show first two images
            li:not(.image-gallery__show-more):nth-of-type(-n + 2) {
              display: inline-block;
            }
    
            // hide 'show more' if there are no more than two images
            li:first-of-type:nth-last-of-type(-n+3) ~ .image-gallery__show-more {
              display: none;
            }
    
            .image-gallery__show-more {
              padding-bottom: calc(((100% / 2) - 2vw) / 1.6);
    
              &::before {
                @include theme('background-color', 'color-primary--darken-3', 'image-gallery-show-more-background-color');
              }
    
              .show-more__content {
                @include theme('color', 'color-secondary', 'image-gallery-show-more-color');
    
                display: flex;
                margin-top: 0;
                text-align: center;
    
                .show-more__total {
                  display: inline-block;
                }
              }
            }
          }
    
          @include tablet {
            // overrule image gallery
            li:first-of-type:nth-last-of-type(-n+5) ~ .image-gallery__show-more,
            li:first-of-type:nth-last-of-type(-n+6) ~ .image-gallery__show-more {
              display: inline-block;
            }
    
            // hide 'show more' if there are no more than three images
            li:first-of-type:nth-last-of-type(-n+3) ~ .image-gallery__show-more {
              display: none;
            }
          }
    
          @include desktop {
            max-width: calc(100% + #{$gutter-width});
            margin: 0 calc((#{$gutter-width} / 2) * -1);
    
            li {
              &,
              &:first-of-type:nth-last-of-type(4),
              &:first-of-type:nth-last-of-type(4) ~ li {
                width: calc((100% / 3) - #{$gutter-width} - .33px);
                margin: calc(#{$gutter-width} / 2);
              }
            }
    
            // only show first three images
            li:not(.image-gallery__show-more):nth-of-type(-n + 3) {
              display: inline-block;
            }
    
            // hide 'show more' if there are no more than three images
            li:first-of-type:nth-last-of-type(-n+4) ~ .image-gallery__show-more {
              display: none;
            }
    
            .image-gallery__show-more {
              padding-bottom: calc(((100% / 3) - #{$gutter-width} - .33px) / 1.6);
            }
          }
        }
      }
    }
    
  • URL: /components/raw/image-gallery/_image-gallery.scss
  • Filesystem Path: components/41-organisms/image-gallery/_image-gallery.scss
  • Size: 10.4 KB