Story Show Gallery View demo gallery

Story Show Gallery

Javascript & React vertical gallery created by Roman Flössler
Known Vulnerabilities

Story Show Gallery is a vertical gallery lightbox optimized for smart­phones (including notch area). SSG will support your brand and marketing. It has optimally placed captions, full screen mode, no ugly arrows, EXIF support.

Download SSG: GitHub - NPM - Wordpress plugin

Story Show Gallery versus usual gallery lightbox. SSG can utilize whole smartphone display - even notch area. usual gallery lightbox
SSG versus usual gallery lightbox. Do you want more icons or more from a photo? Story Show Gallery can use whole smartphone display - even notch area.

Your photos in the main role

Give your photos maximum space with responsive SSG full screen lightbox. There are no ugly ← → arrows next to a photo, vertical slider is subtle and cursor can be too. SSG has 4 visual themes.

On smartphones, full screen mode works like on YouTube. It activates after rotating a phone into landscape mode. Also is possible to start the gallery in full screen portrait or forced landscape mode.

The gallery doesn't have an icon for full screen mode, according to statistics users simply don't use it. So it's up to you, if the gallery will go into full screen.

Neverending story

Behind the last image Story Show Gallery can load a HTML signpost to other photo galleries. See a sample signpost behind ssg

Browsing without clicking and thinking

Scrolling is the most natural interaction with a webpage. Story Show Gallery works like Facebook - as a user scrolls down new pictures are constantly loading.

Story Show Gallery is vertical and therefore great for use with mobile phones. In portrait mode a user usually sees a part of the next photo, so he keeps scroll­ing to see it whole.

Brand building and social sharing

SSG can display your logo or some text (emoji) over images. You can configure it in the SSG settings. photo watermark

Social sharing icon is not put aside, it is part of a content, but subtle. A spectator's eyes will literally crash into the share icon at the end of a caption or in the corner of a photo. It can be disabled in the settings. social share icon

You can deep link into the gallery to show a part­icular pict­ure. Just use image name in the hashtag:  🐑 https://FaroeIslands.io#klaksvik deep linking

Complete your photos with captions

With captions you can tell the whole story behind pictures or amuse a spec­tator with some fun fact. Captions can also contain EXIF data (camera info, exposure, iso, etc.) with link to EXIF listing. EXIF Example

Google treats captions as a text content. Especially when you haven't much text on your page, captions will help a lot your page to rank higher in Google search.

SSG is probably the only gallery which can place each caption individually according to image size vs. screen size. It is really important on smartphones.

SSG is fully responsive - it compares image size vs. screen size and place a caption to an optimal position.

Easy implementation

SSG has very easy setup, it binds onto image hyper­links on the page auto­mati­cally and runs the gallery. You can control this proccess by CSS classes. Define sepa­rate galleries, activate full screen mode, selectively deactivate SSG, etc.

There are 3 ways how a photo gallery can be created. Auto­matically from images on the page, by passing an array of images into SSG, or by combi­nation of both.

No e×it mode: You can write just minimal HTML code and SSG will crea­te a vertical gallery which behaves like a simple webpage. Because there is not much to dis­play without SSG, the gallery can run in the no e×it mode.

Story Show Gallery supports Goo­gle analytics to measure views of each photo. SSG optionally detects and uses GA tracking code on your site. Google Analytics

License

You can use Story Show Gallery freely within open source GNU GPL-3.0 license.
There is one exception from the license: Distributing Story Show Gallery within a Wordpress plugin or theme is only allowed for the author of Story Show Gallery.

Implementation and configuration

All you need to do, is add ssg.min.css and jQuery in the <head> of the HTML page and ssg.min.js before </body>. If you want to display EXIF data (camera info, exposure, iso, etc.), Exifr library is also needed.

You can link files directly from CDN (faster loading), just copy these lines into your HTML:

// ------- inside <head>
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/story-show-gallery@3/dist/ssg.min.css">

// SSG requires jQuery library at least in version 1.7
<script src="https://code.jquery.com/jquery-3.5.1.min.js"> </script>

// ------- before </body>
<script src="https://cdn.jsdelivr.net/npm/story-show-gallery@3/dist/ssg.min.js"> </script>

// add also Exifr library if you want to display EXIF data
<script src="https://cdn.jsdelivr.net/npm/exifr@7/dist/lite.umd.js"> </script>

// if you need IE11 compatibility, instead of story-show-gallery@3 use story-show-gallery@2.10. But it is without the EXIF support.

Story Show Gallery looks for all hyper­links (<a> tags) on the page that points to a picture file (extensions: jpg, jpeg, JPG, JPEG, png, PNG, gif, GIF, webp). And adds to all these hyper­links an onclick function which runs the gallery. Unless nossg class is used.

A photo caption is taken from a thumbnail's alt att­ribute, link text or data-caption attribute. The data-caption has top priority, if it is empty then no caption will appear.

You can also add author's name - enter it into data-author attribute of hyperlink. SSG will create a gallery from all these four images (BigImage1~4):

<a href='BigImage1.jpg'> <img alt='img caption' src='thumb.jpg'> </a>
<a href='BigImage2.jpg data-author='photo by…''> Another caption </a>
<a href='BigImage3.jpg'></a> (an empty link, no caption)
<a href='BigImage4.jpg data-caption='img caption'> text </a>
// Hyperlinks with <Picture> tag inside are also supported.

Default SSG configuration and language localization is at the begining of ssg.js file. Settings are com­mented. You can edit settings in ssg.js file and then minify it. Or copy selected settings into your HTML to override default config­uration. Place it after ssg.min.js, as it is shown on the following picture.
Complete example of SSG implementation and configuration:

HTML5 example - this alt won't be a caption, it is for seo

Enable EXIF

  1. Add Exifr library as it is shown above.
  2. By default EXIF is disabled. Set SSG.cfg.captionExif option to enable it.
  3. Image files has to be on the same domain as website, otherwise reading of EXIF data is blocked by CORS policy.

SSG files and minifying

Story Show Gallery consists of three files placed in the src directory:


There are other three files which are for React:


There are minified files in the dist directory ready for deployment on your website. If you modify source files, you may want to minify the result. Use existing npm script:

npm install // it will install uglify-JS and uglify-CSS npm modules which are needed for minifying
npm run-script dist // it will minify the source files and put them into the dist directory.

Controling SSG by CSS classes

By default SSG will make one big gallery from all linked images on the page. CSS classes can change this behaviour. There are nine classes: ssg, nossg, gossg, vipssg, fs and four themes. Classes have to be assigned to a hyper­link tag or to any tag which contains image hyper­links - they all will be affected:

<a href='outsideImg.jpg' class='fs' > caption </a>
<section class='ssg fs vipssg ssgblack'>
  <div>
    <a href='insideImg.jpg'> caption </a>
  </div>
  <a href='insideImg2.jpg'> caption </a>
</section>

The ssg class creates a separate gallery, assign it to some parent element of many picture hyper­links. In the gallery will show only the pictures that are inside the element with the ssg class. Outside images creates a gallery with id#0.

The fs class will activate full screen mode. There are some exceptions, tablets & mobile landscape go everytime in full screen, it solves problems with mobile browsers

Image hyperlinks that aren't part of any separate gallery, will bind to the gallery (or hyperlinks) with vipssg class. So that they won't display alone.
If you click on the outsideImg.jpg hyperlink, it will display in the gallery together with inside images. But when you click on some inside image hyperlink, only images inside section.ssg will display in the gallery.

SSG will ignore image hyperlinks (or the whole gallery) with nossg class. Images will open normally into browser's tab. Example of nossg

Image hyperlinks with the gossg class can be only an initial image of the gallery. If a user want to see it and clicks on it. Otherwise image hyperlinks with gossg class won't show in the gallery.

SSG offers four themes and each has its own class, which you can assign to some gallery:
light theme -> class: ssglight, dim theme -> class: ssgdim, dark theme -> class: ssgdark and black theme -> class: ssgblack.

Gallery events

SSG offers seven gallery events, you can use them to run your functions. SSG events are part of the configuration.

  1. SSG.cfg.onGalleryStart fires before loading and displaying of the first image.
  2. SSG.cfg.onImgLoad fires when an image is completely loaded from a server.
  3. SSG.cfg.onImgScrollsIn fires when the next/previous/first image starts scrolling in to display (doesn't apply on manual scrolling).
  4. SSG.cfg.onImgView fires when an image is viewed.
  5. SSG.cfg.onOrientationChange fires when a device orientation changes.
  6. SSG.cfg.onBeyondGallery fires when a user gets beyond the gallery - usually on a signpost. If a page is longer than the gallery, a user can manually scroll beyond the gallery into a "void".
  7. SSG.cfg.onGalleryExit fires on the gallery exit.
Example:

SSG.cfg.onGalleryStart = function(data) { console.log( data.imgCount + ' images in the gallery. Starting with image: ' + data.imgName); }; // data object: data.imgCount // count of images in the gallery data.imgGalleryId // ID of current Image in the gallery data.imgPageId // ID of current image on the page data.GalleryId // ID of a gallery which belongs to initial image data.imgPath // whole path to current image data.imgName // image name of current image (no extension) data.imageCaption // image caption for current image // If a user is beyond the gallery data is just true or false. // True if a HTML file (signpost) is displayed behind the gallery. // Otherwise data is false.

SSG auto­mati­cally numbers image hyperlinks and galleries on the page, so IDs comes from this process. But you can also give some ID to current gallery run initiated via SSG.run function.

You can find complete example in the source code of this page (at the end). It writes a little statistic of the gallery usage into the JS console.

Order of photos in the gallery

The picture a user clicked on is shown first, then Story Show Gallery displays following pictures and then the rest. Example: A user clicked on the fourth picture. Pictures are shown in the following order - 4,5,6,7 and then it continues with picture 1,2,3.
If a picture is part of a separate gallery (.ssg class), SSG prefers to show first three pictures of a gallery together. Example: if a user click on the third image, the order of images in the gallery will be 3,1,2,4,5,6. This behaviour can be deactivated in the settings.

Deep linking into Story Show Gallery

SSG can be initiated by a link with photo's name in a hashtag. For example this link FaroeIslands.io/#klakkur-kalsoy will activate Story Show Gallery and show the photo named klakkur-kalsoy. It is enough to have in the hashtag crucial part of the name - #klakkur.

An address of each photo is shown in a browser’s navi­gation bar while browsing through the gallery. In full screen mode you can get a picture address via social share icon.

Full screen mode cannot be activated without a user click, so SSG will show a full screen offer if the deep linked image has fs class. A full screen offer is also shown in case of tablets and mobile phones in landscape mode. It solves problems with mobile browsers.

Vertical scrolling through the gallery

There are two options. Classic vertical scrolling with scrollbar or finger. And then jump scroll. A mouse wheel and arrow keys have an altered function, they scroll from one image to next image.

Move to the next image:
mouse wheel, down arrow key, right arrow, PgDn key or spacebar.
Move to the previous image:
mouse wheel, up arrow key, left arrow, or PgUP key.

For touch screens there are two invisible areas: the top and bottom half of the screen. After tapping somewhere into the bottom (top) half, SSG jump scroll to the next (previous) picture.

SSG.run() method

You can run the gallery by Javascript calling SSG.run method. SSG.run without para­meters shows photos from all image hyperlinks on the page. Excluded are image hyperlinks with nossgg and gossg class.

SSG.run()

The fs:true parameter will activate full screen mode. Use the fsa parameter instead, if the gallery is initiated without an active click from a user. That active click is needed for entering fullscreen mode. The fsa para­meter will ask if a user wants to switch into fullscreen mode.

The id parameter assigns to gallery an ID, which identifies the gallery within SSG events. Otherwise the ID of this gallery run would be -1.

SSG.run( { fs:true, id:'4all8' } )

The gallery can run in the no e×it mode - no close icon, no ESC key - see sample gallery. No e×it mode is useful, when a html page is just a plain list of image links without any design and the gallery starts immediately after a page loads. In this case the fsa parameter is needed for activating full screen mode.

<body onload='SSG.run( { noExit:true, fsa:true } )'>

Use initImgId parameter to set the initial image and also the gallery. SSG auto­mati­cally numbers image hyperlinks on the page, the first image link has ID 0. In this case, the first image will have page ID 13, even if it has gossg class.

The initImgID parameter respects .ssg classes and shows only pictures from the gallery, which contains initImgID picture. Also the gallery theme is taken from css class of the related gallery. The gallery ID will be 3, because 13th image link is in the third gallery.

SSG.run( { initImgID: 13 } )

With the cfg parameter you can override global configuration, it applies only for the current gallery run. The cfg is an object which have the same properties as the global configuration. Following gallery has photos shaped into ellipse with thick border at its top and bottom.

SSG.run( { initImgID:8, fs:true, cfg: { imgBorderWidthX: 32, imgBorderWidthY:0, imgBorderColor:'#adadad', imgBorderRadius:50, watermarkOffsetX:50, watermarkOffsetY:-23, watermarkFontColor: 'white', watermarkOpacity:1 }} )

You can pass into SSG an array of images and captions to show them in the gallery via imgs parameter. If you also add imgsPos parameter, images can be combined with photos from the page. The imgsPos:'start' places imgs before photos from the page, imgsPos:'end' after them. The imgsPos:'whole' shows in the gallery just imgs. It is a default parameter, which is no need to use. If you don't define imgs parameter, imgsPos will be ignored.

The initImgID parameter defines, that after traelanipa.jpg will be image with page id 13 and other photos which belongs into the same gallery.

SSG.run( { imgs: [ { href: 'traelanipa.jpg', alt: 'Trælanípa Cliff' } ], imgsPos:'start', initImgID: 13, cfg: {theme: 'dark'} });

Without the imgsPos parameter, in the gallery will be only photos from array iceland. The initImgID works even with arrays.

SSG.run( { imgs: iceland, id: 'iceland', fs:true, initImgID: 1 }); -------- iceland = []; iceland[ 0 ] = { href: 'img/reynisdrangar-black-beach.jpg', alt: 'Black beach Reynisfjara, Reynisdrangar rocks' }; iceland[ 1 ] = { href: 'img/Seljalandsfoss.jpg', alt: 'Aurora behind Seljalandsfoss waterfall', author: 'photo by Flor' }; iceland[ 2 ] = { href: 'img/iceland-horses.jpg' };

SSG.restart() method

Restart method ends the running SSG gallery and then calls SSG.run with new parameters. It has the same parameters as the SSG.run method. On this page the restart method is used in singpost after the gallery. It runs another gallery without exit fullscreen mode or reloading a page.

Gallery for React and Next.js

Story Show Gallery can also work as a React Component. It is also compatibile with Next.js and Typescript. How to use it:

// install npm package:
npm i story-show-gallery

// import into React app:
import StoryShowGallery, { SSG } from "story-show-gallery/src/react";

// if you want EXIF support use:
import StoryShowGallery, { SSG } from "story-show-gallery/src/react-exifr";

// and also import CSS file:
import "story-show-gallery/src/ssg.css";
// if you use Next.js, you have to import it into _app.tsx as a global CSS

// use StoryShowGallery component and configure the gallery:
<StoryShowGallery config={{ theme: 'light', watermarkText: 'xxx' }} />

You can import story-show-gallery into the root component (app.js or _app.js in the case of Next.js) so that the whole application can use it. Or just import it into any component / page where you want an image gallery.

There is a sample imple­mentation ( SsgReact­Example.js ) in the example directory of the story-show-gallery npm package.

Story Show Gallery for React works the same way as it is described above. Just add the Story­Show­Gallery component into you React app and every image hyperlink on the entire page will be assigned an onclick function, which opens image into the gallery. Image hyperlinks can be controlled by CSS classes, as it is described above.

If you don't want to use image hyperlinks in your code, use the SSG.run function with an array that defines urls and captions of photos. SSG.run para­meters and its use are described above. SSG.run parameters are local - only for the current gallery run.

Global parameters go into the <Story­Show­Gallery/> component, they are common to all SSG.run and to galleries activated by image links. Global para­meters can be overridden by ones within the SSG.run function or by gallery classes. The <Story­Show­Gallery/> compo­nent has one config prop that contains the configuration object with all parameters. List of all possible para­meters - use just param name without SSG.cfg prefix.

Important: if you use routing in React or Next.js, observeDOM should be set to true, otherwise SSG won't work (only SSG.run will).
Routing is changing the whole DOM, so SSG has to use observer to know about the image link changes. SSG.run don't need any observer, because you call SSG manually with all images specified. If you use imgsPos:'start'(end) inside SSG.run, observer is also needed.

// setting of observing DOM:
<Story­Show­Gallery config={{ theme: 'light', observeDOM: true }} />


Theme: Dim Dark Black Light

 ⭕ Extreme example of image border, radius and watermark settings

Gallery with text links

Story Show Gallery also supports text hyper­links. All four follow­ing pict­ures will appear in separate gallery (because of .ssg class):

🐰 Massive pink rabbit man‑eater - a text link to a photo.
Enlightment inside Bankang cave - with empty data-caption
🔗 A broken link - You will notice it before site visitors do
an empty (invisible) link to the picture with SSG logo.

  1. SSG features, sample gallery
  2. License
  3. Implementation + configuration
  4. Enable EXIF
  5. ⚙️Live SSG configuration ⧉
  6. Switch on fancy borders:
  7. SSG files and minifying
  8. Controling SSG by CSS classes
  9. Gallery events
  10. Order of photos in the gallery
  11. Deep linking, scrolling
  12. SSG.run & SSG.restart method
  13. StoryShowGallery for React
  14. 🎨 Visual themes
SSG logo

Global SSG configuration as it is at the begining of ssg.js file: ×

Click on underlined values to change them. It will affect all galleries on this page. // duration of scroll animation in miliseconds. Set to 0 for no scroll animation. SSG.cfg.scrollDuration = 500 ; // Force SSG to always display in fullscreen - true/false SSG.cfg.alwaysFullscreen = false; // Force SSG to never display in fullscreen - true/false There is an exception for smartphones and tablets SSG.cfg.neverFullscreen = false; // When a mobile phone is in portrait mode, start SSG in fullscreen mode. But only if FS is demanded - fs class or fs:true. // rotating into landscape works better, if mobilePortraitFS is set to true. SSG.cfg.mobilePortraitFS = false; // Force full screen landscape mode on smartphones (only if FS is demanded). // Even if a user is holding his phone in portrait mode, the gallery will run in FS landscape mode. SSG.cfg.forceLandscapeMode = false; // Visual theme of the gallery - four possible values: dim, light, black, dark (default) SSG.cfg.theme = "dark" ; // unobtrusive cross cursor SSG.cfg.crossCursor = false; // URL of the HTML file to load behind the gallery (usually a signpost to other galleries). // HTML file has to be loaded over http(s) due to a browser's CORS policy. Set to null if you don't want it. SSG.cfg.fileToLoad = null; // display social share icon and menu SSG.cfg.socialShare = true; // hide image captions, it doesn't impact global caption or exif SSG.cfg.hideImgCaptions = false; // EXIF info (or just the EXIF icon) appears as a part of the caption with link to full EXIF listing // 4 possible values: 'none' (no exif, default), 'standard', 'trim' (reduced lens info to save space), 'icon' SSG.cfg.captionExif = "none" ; // Enlarge image above its original resolution. But only if the image is smaller than two third of screen. It doesn't work on mobiles and tablets. SSG.cfg.enlargeImg = false; // background opacity in range 0-100% SSG.cfg.bgOpacity = 100 ; // relative font size - 100% is base font size, you can increase or decrease it. SSG.cfg.fontSize = 100 ; // Protect photos from being copied via right click menu - true/false SSG.cfg.rightClickProtection = true; // Caption location depends on a photo size vs. screen size and SSG.cfg.preferedCaptionLocation. // Negative number => more likely side caption. Positive number => more likely caption below the photo. // If the number will be too large (eg: 300 or -300 ) a caption will be only in one location. SSG.cfg.preferedCaptionLocation = 3 ; // Side caption for smaller, landscape oriented photos, where is enough space below them as well as on their side. SSG.cfg.sideCaptionforSmallerLandscapeImg = false; // false means caption below, true side caption // an author signature (or some text), which will appear in every caption. The data-author attribute overrides it. SSG.cfg.globalAuthorCaption = "" ; // Show first 3 images of a separate gallery together - e.g. third image clicked - image order will be 3,1,2,4,5,6... SSG.cfg.showFirst3ImgsTogether = true; // Locking the scale of mobile viewport at 1. Set it to true if the gallery has scaling problem on your website. SSG.cfg.scaleLock1 = false; // log image views into Google Analytics - true/false. SSG supports only ga.js tracking code. SSG.cfg.logIntoGA = true; // SSG will observe DOM for changes, to know about image hyperlinks changes after page loads / render. // if you use routing in React or Next.js, observeDOM should be true, otherwise SSG won't work (only SSG.run will). SSG.cfg.observeDOM = false; // image border width in pixels SSG.cfg.imgBorderWidthX = 1 ; SSG.cfg.imgBorderWidthY = 1 ; // image border color in CSS format (eg: #366988 or black) SSG.cfg.imgBorderColor = "" ; // image outline color in CSS format - imgBorderWidthX and imgBorderWidthY should be the same, otherwise outline won't fit SSG.cfg.imgOutlineColor = "" ; // Light effect on image border - it looks good mainly on thicker borders SSG.cfg.imgBorderLightFx = false; // radius is in vh unit, but above 33 is in percent of image size, so it is possible to achieve circle/ellipse (50) SSG.cfg.imgBorderRadius = 0 ; // display shadow around the image (border) as it is defined in the theme SSG.cfg.imgBorderShadow = true; // Watermark - logo configuration. Enter watermark text or image URL to display it SSG.cfg.watermarkWidth = 147; // image watermark width in pixels, it is downsized on smaller screens. SSG.cfg.watermarkImage = "" ; // watermark image URL e.g. 'https://www.flor.cz/img/florcz.png' SSG.cfg.watermarkText = "" ; // watermark text, use <br> tag for word wrap SSG.cfg.watermarkFontSize = 20 ; // font size in pixels SSG.cfg.watermarkFontColor = "" ; // text watermark color, it will deactivate dark text-shadow from theme. SSG.cfg.watermarkOffsetX = 1.8; // watermark horizontal offset from left border in percents of photo, for align to right use value near 100 SSG.cfg.watermarkOffsetY = 0.6; // vertical offset from bottom border in percents of photo, for align to top use value near 100 // Watermark can be also positioned inside image border, use negative values to do so. Negative values are in pixels - as border width SSG.cfg.watermarkOpacity = 0.42; // opacity // Here you can translate SSG into other language. Leave tags <> and "" as they are. SSG.cfg.hint1 = "Browse through Story Show Gallery by:"; SSG.cfg.hint2 = "a mouse wheel <strong>⊚</strong> or arrow keys <strong>↓→↑←</strong>"; SSG.cfg.hint3 = "or <strong>TAP</strong> on the bottom (top) of the screen"; SSG.cfg.hintTouch = "<strong>TAP</strong> on the bottom (top) of the screen<br> to browse through Story Show Gallery."; SSG.cfg.hintFS = "For a better experience <br><a><abbr>⎚</abbr> go full screen</a>" SSG.cfg.toTheTop = "Scroll to top"; SSG.cfg.exitLink = "Exit the Gallery"; // share link dialog SSG.cfg.imageLink = "The link to selected image:"; SSG.cfg.copyButton = "⎘ Copy the link to clipboard"; SSG.cfg.linkPaste = "…and you can paste it anywhere via ctrl+v"; // in the portrait mode the gallery suggest to turn phone into landscape mode SSG.cfg.showLandscapeHint = true; SSG.cfg.landscapeHint = '<i>↻</i> photos look better in landscape mode <span>📱</span>'; // SSG events - see complete example of SSG events in the example directory SSG.cfg.onGalleryStart = null; // fires on the gallery start before loading and displaying of the first image. SSG.cfg.onImgScrollsIn = null; // fires when the next/previous/first image starts scrolling in to display (doesn't apply on manual scrolling) SSG.cfg.onImgView = null; // fires when an image is viewed SSG.cfg.onOrientationChange = null; // fires when a device orientation changes SSG.cfg.onBeyondGallery = null; // fires when a user gets beyond the gallery - usually on a signpost SSG.cfg.onGalleryExit = null; // fires on the gallery exit