Gallery

<div class="
         gallery
         
             gallery--vertical
     ">
    <div class="
             gallery__stage
             
                 gallery__stage--vertical
         ">
        <div class="gallery__frame">
            <div class="lazyload-wrapper ">
                <img class="
            image
            lazyload
            
        " src="" data-src="/images/product/product_432x648.jpg" alt="">
            </div>

        </div>
    </div>

    <div class="
            gallery__nav
                gallery__nav--vertical
            
         ">

        <button class="button button--icon gallery__thumb-arr" type="button" aria-label="check more images">
            <svg class="icon gallery__icon-arrow gallery__icon-arrow--vertical" role="presentation" focusable="false">
                <use href="/images/icons-sprite.svg#angle-up"></use>
            </svg>

        </button>

        <div class="
                        gallery__thumb
                            gallery__thumb--vertical
                            gallery__thumb--active
                    ">
            <div class="lazyload-wrapper ">
                <img class="
            image
            lazyload
            
        " src="" data-src="/images/product/product_64x96.jpg" alt="">
            </div>

        </div>
        <div class="
                        gallery__thumb
                            gallery__thumb--vertical
                    ">
            <div class="lazyload-wrapper ">
                <img class="
            image
            lazyload
            
        " src="" data-src="/images/product/product_64x96.jpg" alt="">
            </div>

        </div>
        <div class="
                        gallery__thumb
                            gallery__thumb--vertical
                    ">
            <div class="lazyload-wrapper ">
                <img class="
            image
            lazyload
            
        " src="" data-src="/images/product/product_64x96.jpg" alt="">
            </div>

        </div>
        <div class="
                        gallery__thumb
                            gallery__thumb--vertical
                    ">
            <div class="lazyload-wrapper ">
                <img class="
            image
            lazyload
            
        " src="" data-src="/images/product/product_64x96.jpg" alt="">
            </div>

        </div>
        <button class="button button--icon gallery__thumb-arr" type="button" aria-label="check more images">
            <svg class="icon gallery__icon-arrow gallery__icon-arrow--vertical" role="presentation" focusable="false">
                <use href="/images/icons-sprite.svg#angle-down"></use>
            </svg>

        </button>

    </div>
</div>
<div
    class="
         gallery
         {{ class }}
         {{#if typeHorizontal }}
             gallery--horizontal
         {{else}}
             gallery--vertical
         {{/if}}
     "
     {{{ attributes }}}
>
    <div
        class="
             gallery__stage
             {{ stage.class }}
             {{#if typeHorizontal }}
                 gallery__stage--horizontal
             {{else}}
                 gallery__stage--vertical
             {{/if}}
         "
    >
        <div class="gallery__frame">
            {{ render '@image' imageMain }}
        </div>
    </div>

    <div
        class="
            gallery__nav
            {{#if typeHorizontal }}
                gallery__nav--horizontal
            {{else}}
                gallery__nav--vertical
            {{/if}}
            {{ nav.class }}
         "
   >

        {{#unless dots}}
            {{#if typeHorizontal }}
                {{ render '@button--icon' thumbArrowLeft }}
            {{else}}
                {{ render '@button--icon' thumbArrowUp }}
            {{/if}}
            {{#each thumbs }}
                <div class="
                        gallery__thumb
                        {{#if ../typeHorizontal }}
                            gallery__thumb--horizontal
                        {{else}}
                            gallery__thumb--vertical
                        {{/if}}
                        {{#if imageThumb.active}}
                            gallery__thumb--active
                        {{/if}}
                    "
                >
                    {{ render '@image' imageThumb }}
                </div>
            {{/each}}
            {{#if typeHorizontal }}
                {{ render '@button--icon' thumbArrowRight }}
            {{ else }}
                {{ render '@button--icon' thumbArrowDown }}
            {{/if}}
        {{/unless}}
        {{#if dots}}
            {{#each thumbs}}
                <div
                    class="
                        gallery__thumb-dot
                        {{#if dotThumb.active}}
                            gallery__thumb-dot--active
                        {{/if}}
                    "
                >
                    <div class="gallery__dot"></div>
                </div>
            {{/each}}
        {{/if}}


    </div>
</div>
{
  "typeVertical": true,
  "dots": false,
  "imageMain": {
    "dataSrc": "/images/product/product_432x648.jpg"
  },
  "thumbArrowLeft": {
    "tag": "button",
    "class": "gallery__thumb-arr",
    "attributes": "type=\"button\" aria-label=\"check more images\"",
    "icon": {
      "id": "angle-up",
      "class": "gallery__icon-arrow gallery__icon-arrow--horizontal",
      "hidden": true
    }
  },
  "thumbArrowUp": {
    "tag": "button",
    "class": "gallery__thumb-arr",
    "attributes": "type=\"button\" aria-label=\"check more images\"",
    "icon": {
      "id": "angle-up",
      "class": "gallery__icon-arrow gallery__icon-arrow--vertical",
      "hidden": true
    }
  },
  "thumbArrowRight": {
    "tag": "button",
    "class": "gallery__thumb-arr",
    "attributes": "type=\"button\" aria-label=\"check more images\"",
    "icon": {
      "id": "angle-down",
      "class": "gallery__icon-arrow gallery__icon-arrow--horizontal",
      "hidden": true
    }
  },
  "thumbArrowDown": {
    "tag": "button",
    "class": "gallery__thumb-arr",
    "attributes": "type=\"button\" aria-label=\"check more images\"",
    "icon": {
      "id": "angle-down",
      "class": "gallery__icon-arrow gallery__icon-arrow--vertical",
      "hidden": true
    }
  },
  "thumbs": [
    {
      "imageThumb": {
        "dataSrc": "/images/product/product_64x96.jpg",
        "active": true
      }
    },
    {
      "imageThumb": {
        "dataSrc": "/images/product/product_64x96.jpg"
      }
    },
    {
      "imageThumb": {
        "dataSrc": "/images/product/product_64x96.jpg"
      }
    },
    {
      "imageThumb": {
        "dataSrc": "/images/product/product_64x96.jpg"
      }
    }
  ]
}
  • Content:
    $gallery__width                             : 100% !default;
    $gallery__padding                           : 0 !default;
    $gallery__margin                            : 0 !default;
    
    $gallery--icon-arrow-color                  : $color-primary !default;
    $gallery__icon-arrow-color-hover            : $color-secondary !default;
    
    $gallery__nav-margin-right--vertical\@medium: $spacer--medium !default;
    $gallery__nav-margin--vertical\@medium      : 0 $gallery__nav-margin-right--vertical\@medium 0 0 !default;
    $gallery__nav-margin-right--vertical\@large : $spacer--semi-large !default;
    $gallery__nav-margin--vertical\@large       : 0 $gallery__nav-margin-right--vertical\@large 0 0 !default;
    
    $gallery__stage-margin                      : 0 0 $spacer--medium 0 !default;
    
    $gallery__thumb-border                      : none !default;
    $gallery__thumb-border--active              : 2px solid $color-primary !default;
    $gallery__thumb-spacing                     : $spacer--medium !default;
    $gallery__thumb-margin                      : 0 $gallery__thumb-spacing 0 0 !default;
    $gallery__thumb-margin--vertical            : 0 0 $gallery__thumb-spacing 0 !default;
    $gallery__thumb-width                       : 64px !default;
    $gallery__thumb-width\@medium               : 64px !default;
    
    // dots
    $gallery__thumb-margin--dots                : 0 5px !default;
    $gallery__thumb-dot-size--dots              : 6px !default;
    $gallery__thumb-dot-bg-color--dots          : $gray !default;
    $gallery__thumb-dot-bg-color-active--dots   : $color-primary !default;
    $gallery__thumb-dot-border-radius--dots     : 100% !default;
    $gallery__thumb-border-active--dots         : 0 !default;
    
    $gallery__placeholder-width                 : auto !default;
    $gallery__placeholder-padding-bottom        : $spacer--medium !default;
    $gallery__placeholder-padding-bottom\@medium: 0 !default;
    $gallery__placeholder-transform\@large      : translate(calc(-50% + #{$spacer}), -50%) !default;
    $gallery__placeholder-padding-right\@large  : calc(#{$gallery__thumb-width\@medium + 2px}) !default;
    
  • URL: /components/raw/gallery/_gallery-variables.scss
  • Filesystem Path: build/components/Organisms/gallery/_gallery-variables.scss
  • Size: 2 KB
  • Content:
    @import 'gallery-variables';
    
    .gallery {
        display: flex;
        flex-flow: nowrap;
        flex-direction: column;
        justify-content: flex-start;
        width: $gallery__width;
        margin: $gallery__margin;
        padding: $gallery__padding;
        list-style-type: none;
    
        &__frame {
            position: relative;
        }
    
        &__stage {
            order: 1;
            margin: $gallery__stage-margin;
        }
    
        &__nav {
            order: 2;
            display: flex;
            align-items: center;
            justify-content: center;
        }
    
        &__thumb {
            overflow: hidden;
            margin: $gallery__thumb-margin;
            border: $gallery__thumb-border;
            width: $gallery__thumb-width;
    
            @include mq($screen-m) {
                width: $gallery__thumb-width\@medium;
            }
    
            &:hover,
            &.focus-visible {
                cursor: pointer;
            }
    
            &:last-of-type {
                margin: 0;
            }
    
            &--active {
                border: $gallery__thumb-border--active;
            }
    
            &--vertical {
                margin: $gallery__thumb-margin--vertical;
            }
    
            &--horizontal {
                margin: $gallery__thumb-margin;
            }
        }
    
        &__thumb-arr {
            background: $white;
    
            // TO DO: consult icon hover state
            &:hover {
                &:after,
                &:before {
                    display: none;
                }
                .gallery__icon-arrow {
                    fill: $gallery__icon-arrow-color-hover;
                }
            }
        }
    
        &__icon-arrow {
            transform: translate3d(-50%, -50%, 0) rotate(-90deg);
            &--vertical {
                transform: none;
            }
        }
    
        &__thumb-dot {
            position: relative;
            margin: $gallery__thumb-margin--dots;
    
            &--active {
                border: $gallery__thumb-border-active--dots;
            }
        }
    
        &__dot {
            display: block;
            width: $gallery__thumb-dot-size--dots;
            height: $gallery__thumb-dot-size--dots;
            border-radius: $gallery__thumb-dot-border-radius--dots;
            background-color: $gallery__thumb-dot-bg-color--dots;
    
            &--active {
                background-color: $gallery__thumb-dot-bg-color-active--dots;
            }
        }
    
        &-placeholder {
            position: relative;
    
            .loader {
                z-index: 0;
            }
        }
    
        &__placeholder-image {
            max-height: 100%;
            width: $gallery__placeholder-width;
            padding-bottom: $gallery__placeholder-padding-bottom;
    
            @include mq($screen-m) {
                padding-bottom: $gallery__placeholder-padding-bottom\@medium;
            }
    
            @include mq($screen-l) {
                max-height: none;
            }
    
            &:is(picture).ratio-image {
                width: 100%;
                height: 100%;
            }
    
            &.ratio-image {
                @include mq($screen-l) {
                    top: 50%;
                    // thumbwidth + thumbmargin (fixed in fotorama.js)
                    padding-right: $gallery__placeholder-padding-right\@large;
                    transform: $gallery__placeholder-transform\@large;
                    max-height: 100%;
                    width: auto;
                }
            }
    
            &.lazyload,
            &.lazyloaded,
            &.lazyloading {
                background: none;
            }
        }
    }
    
  • URL: /components/raw/gallery/_gallery.scss
  • Filesystem Path: build/components/Organisms/gallery/_gallery.scss
  • Size: 3.2 KB

Gallery Component

Gallery in Magento 2 is built based on Fotorama. More information about Gallery widget you can find in Magento 2 documentation.

Alpaca’s Gallery use following styles:

  • styles for Magento 2 Gallery based on default Magento 2 .less styles, can be found in: theme-frontend-alpaca/styles/gallery-styles.scss - this file is generated as a separate css file and loaded only on product page, where gallery is used.
  • styles for gallery theme customisation: theme-frontend-alpaca/Magento_Catalog/styles/modules/_fotorama.scss
  • styles from fractal component (used in Magento 2 theme implementation): theme-frontend-alpaca/Snowdog_Components/components/Organisms/gallery/_gallery.scss
  • styles for fractal view (used only in fractal view): theme-frontend-alpaca/Snowdog_Components/docs/styles/docs-only-styles/_gallery.scss

Some classes of fractal component are extended in theme-frontend-alpaca/Magento_Catalog/styles/modules/_fotorama.scss:

  • .gallery__thumb with variants
  • .gallery__thumb-dot with variants
  • .gallery__thumb-arr with variants
  • .gallery__icon-arrow with variants
  • .gallery__dot with variants

It is still a bit complicated. The complication level is caused by the Magento implementation, hope it will be refactor and simplified in future released

All styles can be overwritten in the child theme.

Gallery variants are set in vendor/snowdog/theme-frontend-alpaca/etc/view.xml. Variants can differ depending on breakpoints and variant’s class (&--horizontal, &--vertical) is added dynamically to different elements inside the gallery. Variants’ presentation in fractal is mainly demonstrative. Please take it under consideration customising your Alpaca’s child theme.