Advanced

Code injection

Restyle any part of Meridian by pasting a few lines of CSS into Ghost's Code injection box. Every major section and component has a stable, named handle, so your tweaks keep working after theme updates.

Want to nudge a colour, hide a section, or tighten some spacing without forking the theme? Meridian gives every major part of the page a stable handle you can target with a few lines of CSS. You paste that CSS once into Ghost's Code Injection and it sticks, even when you update the theme.

No theme editing required

Everything on this page is done through Ghost Admin → Settings → Code injection. You don't edit theme files, and you don't rebuild anything. Code Injection survives theme updates, which is exactly why it's the safe place for custom CSS. (Editing the theme files directly is not safe: your changes are erased the next time you upload a new meridian.zip.)

The naming convention

Meridian labels its building blocks with a small, predictable set of HTML attributes — a naming convention you can reason about. Once you know the four words below, you can usually guess the hook for something instead of looking it up:

  • data-region marks a big structural area, like the site header, the article body, or the homepage hero. There's usually one of each per page.
  • data-component marks a reusable unit that can appear many times, like a post card, a story link in a rail, or the pagination bar.
  • data-variant tells apart flavours of the same component — for example a post card rendered as the big hero versus a compact dense list item.
  • data-part marks a piece inside a component or region — the title, kicker, excerpt, meta (byline/date), image, or read-time. These names are the same everywhere, so the headline of any story preview is [data-part="title"], whether it's an <h1> or a <p>. A few parts live outside story previews: rank (the position number in numbered rails), logo (the brand logo image), and wordmark (the text site title shown when there's no logo).
AttributeMeansHow manyExample values
data-regiona structural area~one per pagesite-header, post-body, most-read-rail, lead-story, comments
data-componenta repeating unitmanypost-card, story-link, story-card, pagination, newsletter-cta
data-varianta flavour of its hostpairedhero, dense, compact, editorial, next
data-parta piece inside the hostmanytitle, kicker, excerpt, meta, image, read-time, rank, logo, wordmark

You compose these by nesting — region, then component (with its variant), then part — and you can scope the whole thing to one page type with a Ghost body class (shown in the next section).

To target any of them, use an attribute selector in CSS:

<style>
  /* A structural region */
  [data-region="post-body"] { font-size: 1.05rem; }

  /* Every post card on the site */
  [data-component="post-card"] { /* ... */ }

  /* Only the hero-style post card */
  [data-component="post-card"][data-variant="hero"] { /* ... */ }

  /* The headline inside any post card, whatever element it uses */
  [data-component="post-card"] [data-part="title"] { /* ... */ }
</style>

What not to target

Meridian uses other data-* attributes internally — they wire up JavaScript or belong to Ghost itself — and those are not part of this styling API. Only the four above (data-region, data-component, data-variant, data-part) are a promise. Leave the rest alone, because they can change or disappear in any update:

  • Theme machinery (drives Meridian's own scripts): data-breaking-ticker, data-ticker-*, data-footer-nav-*, data-post-toolbar, data-reading-progress, data-toc-mount, data-favicon-fallback, and the like.
  • Page state on <html>: data-color-scheme, data-palette, data-font-size. For dark-mode tweaks, use the .dark class instead (shown later).
  • Ghost & libraries (owned by Ghost, not the theme): data-portal, data-members-*, data-ghost-search, data-pswp-*.

A quick test: if the name reads like the four-word grammar — an area, a unit, a flavour, or a piece — it's fair game. If it reads like a wiring label (-toolbar, -mount, -track, portal), don't style against it.

Scope a change to one kind of page

Ghost adds a class to the <body> of every page that tells you what kind of page it is — home-template, post-template, page-template, tag-template, author-template, and error-template (plus paged on pages 2, 3, and so on). Combine that with a hook to scope a change to just one place:

<style>
  /* The hero headline, but only on the homepage */
  .home-template [data-component="post-card"][data-variant="hero"] h1 { /* ... */ }

  /* Pagination, but only on tag archives */
  .tag-template [data-component="pagination"] { /* ... */ }
</style>

Reach the elements inside a region

The hooks mark the containers. To style something inside one, add a selector after the hook. For the parts of a story preview, prefer the data-part hook over a bare element selector — the heading level varies between layouts, but the part name doesn't:

<style>
  [data-component="post-card"] [data-part="title"] { letter-spacing: -0.01em; }  /* card headlines */
  [data-component="post-card"] [data-part="image"] { border-radius: 4px; }       /* card images   */
  [data-component="post-card"] [data-part="meta"] time { font-style: italic; }   /* the date line */
</style>

Inside the article body, Meridian renders the content Ghost's editor produces, which already has its own stable classes. Target those directly under [data-region="post-body"]:

<style>
  [data-region="post-body"] .kg-image-card { /* images   */ }
  [data-region="post-body"] .kg-button-card { /* buttons  */ }
  [data-region="post-body"] blockquote { /* pull-quotes */ }
</style>

Targeting parts of a story

Every story preview — the linked headline blocks in feeds, rails, grids, carousels, and "more to read" lists — is built from the same handful of parts, each with a data-part hook:

PartHookWhat it is
Title[data-part="title"]the headline link
Kicker[data-part="kicker"]the small primary-tag label above the title
Excerpt[data-part="excerpt"]the short summary / dek
Meta[data-part="meta"]the byline and/or date line
Image[data-part="image"]the thumbnail <figure>
Read time[data-part="read-time"]the "5 min read" label inside the meta line

Because the names never change, you can restyle a part everywhere it appears with a single rule — no matter which heading level or element the layout happens to use:

<style>
  /* Every story headline on the site */
  [data-part="title"] { font-variation-settings: "wght" 620; }
</style>

…or scope it to one region. To recolour just the headlines in the homepage "More to read" rail, combine the region with the part:

<style>
  [data-region="most-read-rail"] [data-part="title"] {
    color: var(--color-accent);
  }
</style>

Not every preview has every part — a text-only rail row has no image or excerpt — but when a part is present, it always carries the same hook.

A few parts live outside story previews, for the same convenience: [data-part="rank"] is the position number in numbered rails (the "More to read" list, some section rows), while [data-part="logo"] (the brand logo image) and [data-part="wordmark"] (the text site title, when there's no logo) appear in the masthead, the Compact header, and the hamburger menu. The menu is its own region — [data-region="menu"] — so you can size each place's logo on its own (see the logo snippets below).

Hook reference

Every targetable part of Meridian, grouped by where it lives. Pair any of these with a body class above to scope it to one page type.

Site-wide chrome

Part of the pageSelector
Breaking-news ticker[data-component="breaking-ticker"]
Site header (both styles)[data-region="site-header"]
Editorial header only[data-region="site-header"][data-variant="editorial"]
Compact header only[data-region="site-header"][data-variant="compact"]
Masthead / nameplate[data-region="masthead"]
Brand logo image[data-part="logo"]
Site-title text (wordmark, no-logo sites)[data-part="wordmark"]
Hamburger menu (off-canvas)[data-region="menu"]
Primary sections nav[data-region="primary-nav"]
Sign in / Subscribe links[data-component="auth-links"]
Reading-progress bar[data-component="reading-progress"]
Footer[data-region="site-footer"]
Footer brand column[data-component="footer-brand"]
Footer link columns[data-region="footer-nav"]
Footer copyright row[data-region="footer-legal"]
Advertisement slot (any)[data-component="ad-slot"]
A specific ad position[data-component="ad-slot"][data-variant="leaderboard"] (also in-feed, billboard, in-article, post-footer)
Bold section divider (the heavy 3px rule between sections)[data-component="divider"][data-variant="section"]

Homepage

Part of the pageSelector
Front grid wrapper[data-region="home-grid"]
Lead story column[data-region="lead-story"]
Sub-leads under the lead[data-region="sub-leads"]
Secondary stories column[data-region="secondary-stories"]
Editor's note box[data-component="editors-note"]
"More to read" rail[data-region="most-read-rail"]
Editor's Picks carousel[data-component="editors-picks"]
A homepage section row[data-component="section-row"]
Carousel-style section row[data-component="section-row"][data-variant="carousel"]
Feature-rail section row[data-component="section-row"][data-variant="feature-rail"]
Tag-columns section row[data-component="section-row"][data-variant="tag-columns"]
Sections page (topic hubs)[data-region="sections-page"]
"From the archive" tail[data-region="archive-tail"]

Posts & pages

Part of the pageSelector
Whole article[data-region="post"]
Static page[data-region="page"]
Post header block[data-region="post-header"]
Byline + date line[data-region="post-meta"]
Feature image[data-region="feature-image"]
Feature-image caption (posts, pages & cards)[data-component="image-caption"]
Article body[data-region="post-body"]
Article action toolbar[data-component="article-toolbar"]
Reader-preferences panel[data-component="reader-panel"]
Sticky bar (after scroll)[data-component="sticky-bar"]
Table of contents[data-component="table-of-contents"]
Author card[data-region="author-card"]
A single author block[data-component="author"]
Comments section[data-region="comments"]
Previous / next links[data-component="post-navigation"]
Breadcrumb[data-component="breadcrumb"]
Static page header[data-region="page-header"]

Recommendation rails (below a post)

Part of the pageSelector
Latest articles[data-component="latest-articles"]
Related coverage[data-component="related-coverage"]
You may be interested in[data-component="you-may-like"]
From this writer[data-component="from-this-writer"]
Ghost recommendations[data-component="recommendations"]

Post cards

A post card is the linked story preview that appears in feeds, rails, and grids. Target all of them with [data-component="post-card"], or one style with a data-variant:

Card styleSelectorWhere it shows
Hero[data-component="post-card"][data-variant="hero"]Homepage lead story
Hero (split)[data-component="post-card"][data-variant="hero-split"]Top of archive pages
Feed[data-component="post-card"][data-variant="feed"]Default grid card
Horizontal[data-component="post-card"][data-variant="horizontal"]Wide image-left rows
Grid[data-component="post-card"][data-variant="grid"]Image-top cards in the homepage grid carousels (3- and 4-column)
Dense[data-component="post-card"][data-variant="dense"]Text-only rail items
Dense + thumb[data-component="post-card"][data-variant="dense-thumb"]Rail items with a thumbnail
Thumb row[data-component="post-card"][data-variant="thumb-row"]Recommendation grids

Other story previews & their parts

Not every story preview is a post card. Compact list rows and a few hand-built cards carry their own component hook, and every preview exposes the same parts:

HookSelectorWhere it shows
Story link[data-component="story-link"]compact text rows in rails, related coverage, recommendations, and the "more to read" rail
Story card[data-component="story-card"]hand-built cards like Editor's Picks and some homepage section rows
Previous / next link[data-component="post-nav-link"]the links below a post (data-variant="next" and data-variant="prev")
Story part[data-part="title"]the headline of any preview (also kicker, excerpt, meta, image, read-time)

Archives, members & CTAs

Part of the pageSelector
Archive header[data-region="archive-header"]
Desk filter chips[data-component="archive-filters"]
Author archive header[data-region="author-header"]
A post grid row[data-component="post-grid"] (variants two-up, three-up, four-up)
Pagination bar[data-component="pagination"]
Newsletter signup[data-component="newsletter-cta"]
Membership band[data-component="membership-cta"]
Member CTA (signed-out)[data-component="member-cta"][data-variant="signup"]
404 hero[data-region="error-hero"]
404 browse suggestions[data-region="error-browse"]

Common snippets

Paste any of these into Settings → Code injection → Site Header and click Save. They're grouped by what they change; click a snippet to expand it. Mix and match — keep the ones you want and delete the rest.

Check the settings first

Many look-and-feel choices are built into Meridian, so you don't need CSS for them: accent colour and heading/body fonts live in Ghost's Settings → Design & branding (see Brand), while default light/dark mode, background palette, header style, single-author bylines, the breaking-news ticker, and ads are theme settings (see Site-wide settings). Reach for Code injection only for tweaks the settings don't cover.

Brand & colours

Typography

To switch the heading or body typeface, use the font settings in Design & branding rather than CSS.

Header, logo & navigation

Hiding things

Layout & spacing

Dark mode

Mobile

Need something else? See the full handle reference above, or the Sections and Membership CTA guides for component context.

Targeting with JavaScript

The same handles work from JavaScript, which you can add in Settings → Code injection → Site Footer:

<script>
  document.querySelectorAll('[data-component="post-card"]').forEach((card) => {
    // do something with each card
  });
</script>

These handles are a promise

The data-region, data-component, data-variant, and data-part names on this page are a supported part of Meridian. We treat renaming or removing one as a breaking change, called out in the changelog — so the CSS you write today keeps working.

Troubleshooting

Find the handle for anything on the page

Not sure which hook to use? Right-click the thing you want to style and choose Inspect. In the panel that opens, look for the nearest tag with a data-region or data-component attribute — that's your selector.

My CSS isn't taking effect

Meridian's own styles are sometimes more specific than a plain selector. If your rule is being ignored, make the selector more specific (for example, lead with a page class like .post-template ...) or, as a last resort, add !important to the property. Also double-check you wrapped the CSS in <style> tags inside the Site Header box.

The snippet looks broken after pasting

Some editors silently turn straight quotes (") into "smart quotes" (" and "), which CSS doesn't understand. If a snippet stops working after you copied it from a document or chat, retype the quotes, or paste into a plain-text editor first so the quotes stay straight.

See also: Social Links for adding more social icons, and For developers if you'd rather fork the theme and edit the source.