Don't love the Ghost gallery? How about a carousel?

Image options, including a Splide-based carousel in Ghost.

A cartoon Ghost holding a paint brush
CTA Image

This post isn't going to translate well to ActivityPub. (It's also limited in email.) Please come on over to the website to see it in all its glory!

See it on the web

Hello all! Sorry for the gap in posts. It's been a crazy couple weeks. (Months? I've lost count?) The kiddo is back in school, robotics, and gymnastics. The spouse is back to teaching after a year-long hiatus. And we've got a cat with some sort of major medical issue. Everything is half an hour from home, and some days it feels like I spend all the time in my car. (While three hours in a given day is not technically "all the time", it sure feels like it.) Anyway, please enjoy this post, which has been stuck in my drafts for a couple months.

Cats courtesy of placecats.com

In this article:

What's natively available

Using the image card

First, off, a reminder about what's available natively in Ghost, for images within the post body. Images inserted in the body of the post can have one of three widths, which you select by clicking the image:

The three icons on the left are from narrowest to widest.

In many themes, that'll get you column width, wider than column width, and full screen width, but it can vary a bit, since a post template with a sidebar isn't very compatible with full width content. How images display on the web is under theme control. (As always, for email and ActivityPub, it's not under theme control. In email, all three images will be the same column width.)

The image card accommodates captions (optional) and alt text (which you should always add unless the image is strictly decorative). To set alt text (used by screen readers) for an image, click the 'alt' button next to the caption.

A tabby cat with darker brown stripes on lighter brown fur.  He is lying down, looking directly at the camera.
A gorgeous chonky boy. (First width)
A tabby cat with darker brown stripes on lighter brown fur.  He is lying down, looking directly at the camera.
A gorgeous chonky boy. (Wide width)
A tabby cat with darker brown stripes on lighter brown fur.  He is lying down, looking directly at the camera.
A gorgeous chonky boy. (Full width)

Image galleries

Dragging one image onto another will start a gallery. Galleries are limited to no more than 9 images, and do not show individual captions.

Note that the gallery will appear as a column of images in email. Although you can put a caption on an image before dragging it into the gallery, it won't display anywhere.

You can and should put alt text on your gallery images, if the gallery content is something that should be accessible for screen readers. To do so, load each image into an image card, set the alt text, then drag the image into the gallery.

Other options for images:

You can also use cards that accommodate images, including the "call to action" cards and the product card. Here are a couple quick demos:

Some text goes here, unless you turn it off
CTA Image

This is the main body of the call to action card, layout #1. It looks a little silly with a cat, but can work nicely for logos.

Some text goes here, unless you turn it off
CTA Image

This is the main body of the call to action card, layout #1. It looks a little silly with a cat, but can work nicely for logos.

Product card!

This is the description of a product card. It has a title, but no options for background color, etc. Tradeoffs.

Unfortunately, neither the call to action card nor the product card gives you the ability to set alt text on the image. That's a shortcoming I'd like to see remedied.

The example below should give you a fairly well-formatted carousel on web. As usual, ActivityPub readers should come on over to the website to see it. I'm not actually sure what'll happen in ActivityPub, but I'm sure it won't be functional, and it might be missing. For those of you ignoring my pleading to come visit the site, here's how it should look:

Non-function screenshot above!

Here's the functional version below, for my web readers. Notice that each image can have its own alt text, and that hovering reveals a caption for each image.

This chonky boy has alt text.
This chonky boy needs a caption.
This chonky boy has alt text, too.
This chonky boy needs a caption.
This sweet kitty is licking a mysterious yellow object.
mmmmm. tasty
This sweet orange kitty is playing with a green mousie.
I lurvz my mousie.

I'm inserting each image using a regular Ghost image card, which lets me set alt text and captions for each image. To make it behave as a gallery, I use two HTML snippets, one above the images, and the other below. Here they are. Make snippets for most convenient use.

Above:

<script src="https://cdn.jsdelivr.net/npm/@splidejs/[email protected]/dist/js/splide.min.js"></script>
<link href="https://cdn.jsdelivr.net/npm/@splidejs/[email protected]/dist/css/splide.min.css" rel="stylesheet">
<div class="splide">
  <div class="splide__track">
    <div class="splide__list">

Below:

</div><div class="splide__arrows"></div></div>

</div>
<style>
  figure.splide__slide  {
    width: 100%;
    height: 100%;
    object-fit: contain;
    background-color: #000;
  }
.splide__slide img {
    width: 100%;
    height: 100%;
    object-fit: contain;
}
.splide {
        max-width: 100%
}
.splide__slide figcaption {
    position: absolute;
    display: none;
    padding: 16px;
  width: 100%;
}
.splide__slide:hover figcaption{
    display:block;
    bottom:0;
    background: rgba(0, 0, 0, 0.5);
    color: #fff;
}
.splide__slide:hover {
    opacity: 1;
}
  </style>
<script>
  document.querySelectorAll('.splide figure').forEach(el => 
    el.classList.add('splide__slide'));
  
  document.addEventListener( 'DOMContentLoaded', function() {
    var splide = new Splide( '.splide' 
    , {
        type       : 'loop',
        perPage    : 1,
        perMove    : 1,
        pagination : false,
        arrows     : false,
        pauseOnHover: false,
        pauseOnFocus: false,
        arrows: true,
        gap: '3em',
        heightRatio: 1,

        breakpoints: {
            600: {
                perPage: 1,
                perMove: 1,
                height: '60vh'
            }
        }
    } );
    splide.mount();
  } );
</script>

One final important trick. Because these snippets are wrapping the images in a couple extra divs, you will want to set the visibility on both html cards to web only. That causes email readers to get a column of images. (Alternately, if you have a LOT of images, maybe you don't want to do that, and instead the images will disappear, and then you could use a CTA card to nudge email readers to come see the images online.) Click the HTML card, and choose the visibility icon:

Then set the visibility to off for the email options.

I am hoping that one day we'll get visibility choices for ActivityPub too, since the needed behavior there is more like email than web, and right now it gets rendered like web, but minus the javascript and styles that make web actually work well for anything more complicated/interesting.

Host your images somewhere else

The final option for groups of images in Ghost is to host them somewhere else, and to embed in Ghost. (Expect all the usual issues with embeds - they're great on web, but not email or ActivityPub.)

Here's a post I wrote about using Flickr for images and galleries:

How to embed a Flikr photo in Ghost
Want to use Flickr images in Ghost? This tutorial will show you how, no coding needed.

While I haven't done a detailed write-up for any other photo-sharing platform, the process will be pretty similar: Get an embed code, and put it in an embed card. Don't expect it to work except on web.


My wish-list for Ghost

  • Native carousels (perhaps as an alternate layout for the gallery?)
  • Make alt text easy to set on any image type, not just images and galleries
  • Visibility settings specific to ActivityPub.

That's all for today. Wishing you a very happy October!

Hey, before you go... If your finances allow you to keep this tea-drinking ghost and the freelancer behind her supplied with our hot beverage of choice, we'd both appreciate it!