Header Card Images Displaying Side-by-Side Instead of as Background

Hey everyone, I’m having an issue where header card images are displaying alongside the text content in a split layout instead of as background images. The cards have the correct structure with a <picture> element as a direct child of the .kg-header-card, but Ghost’s CSS seems to be forcing a flex layout that puts the image and content side by side.

The Problem

When I inspect the rendered HTML, header cards look like this:

<div class="kg-card kg-header-card kg-v2 kg-width-full">
    <picture>
        <img src="https://example.com/image.jpg" class="kg-header-card-image">
    </picture>
    <div class="kg-header-card-content">
        <h2 class="kg-header-card-heading">My Heading</h2>
        <h3 class="kg-header-card-subheading">My Subheading</h3>
        <a href="#" class="kg-header-card-button">Button Text</a>
    </div>
</div>

The structure looks correct (picture is a direct child of the card, not inside the content div), but the rendered result shows the image and text side by side in a split layout, rather than the image as a background behind the text.

What I’ve Tried

  1. Removed kg-layout-split class - This class was present and I removed it, but the side-by-side layout persists.

  2. Tried data-kg-background-image attribute - Switched to using Ghost’s native background image attribute, removed the picture element. Result: Full width card but no background image at all.

  3. Added CSS to override flex layout - Tried forcing display: block and flex-direction: unset with !important:

.kg-header-card {
    display: block !important;
    flex-direction: unset !important;
}

Still showing side by side.

  1. Wrapped in container div - Following the approach from spectralwebservices, wrapped cards in a container div and targeted with CSS. No change.

  2. Positioned picture absolutely - Tried making the picture element position: absolute with z-index: 0 and content at z-index: 1. Ghost’s flex layout still overrides it.

What I’m Seeing in the Inspector

When I inspect the rendered page:

  • The card has display: flex applied (from cards.muin.css)
  • The picture element and content div are flex children, causing the side-by-side layout
  • Even with !important flags, I can’t seem to override Ghost’s flex layout
  • The kg-layout-split class is removed, but the split behavior persists

Questions

  1. Is there a specific class or attribute that tells Ghost to render header cards with background images vs split layout? The docs mention kg-style-image - does that need to be present?

  2. How does Ghost’s default CSS determine whether to show an image as background vs side-by-side? Is it based on the presence of data-kg-background-image, or something else?

  3. Are there theme-specific CSS rules I should be aware of? I’m using a custom theme - could it be overriding the default header card behavior?

  4. Has anyone successfully overridden Ghost’s flex layout for header cards to force background image display? What CSS specificity was needed?

The structure matches what I see in the Ghost docs, but the rendering doesn’t. Any insights would be super helpful!

Thanks,

Nic

If it’s public, can you link the site?

I’d expect the image (within the picture element) to be set to display: absolute. I wonder if you/your theme has some styles that are accidentally overriding that behavior. Click on the img element and see what styles it has, and where they’re from?

Firstly, thanks for your website; it’s been an amazing resource for me over the past 2 years.

Here’s a preview link, not sure if that will work: DECEMBER 2025 ● ISSUE #27 - FREE EDITION

Looks to me as if the img element is display: block. Looks like it’s getting it from reset.css dunno what that is.

1 Like

@Cathy_Sarisky Just circling back here, any thoughts?

I looked at a couple of your cards, and they all appear to have the kg-layout-split class applied, which would be consistent with the card actually being in split format. What do you see when you open the card in the editor – I’m wondering if this is user error? A screenshot showing the header card with its settings window (little white popup where you can upload an image and change layout) would be useful here, I think.

Thanks for checking, that helped me narrow it down. When I open the editor it shows up as split and I can manually set it back to wide. I’m programmatically generating HTML and sending it to Ghost via the Admin API, and even after ensuring the HTML matches a working example, Ghost still shows the cards as split in the editor.

I’ve verified the HTML we’re sending:

  • No kg-layout-split class present

  • Has kg-width-full and kg-content-wide classes

  • Picture element is a direct child of the card (not inside content div)

  • Structure matches exported HTML from a working card

Example of what we’re sending:

I’m guessing what’s happening is that this HTML is sent via the API, Ghost converts it to Mobiledoc, and the editor shows split layout. I suspect the HTML-to-Mobiledoc conversion isn’t inferring the layout correctly.

How does Ghost store layout information (split vs full/wide) in Mobiledoc JSON? Is it in the card payload or inferred from HTML structure? Is there a way to explicitly specify the layout, or must it be inferred?

Thanks for your help!

I can confirm this behavior. Using the exported HTML for cards, both a wide and a split card were rendered as split cards using the Admin API, with HTML as the source.

One option would be to pass Lexical to the API instead. (Yeah, I don’t love that either.)

Otherwise, it looks like there’s a bug here, and you might want to file it over on Github.

I think the problem is here:

Thanks for your help Cathy!

Filed the bug here: Header card HTML parser incorrectly defaults to split layout when image is present · Issue #1656 · TryGhost/Koenig · GitHub