fix(core): expose multi-theme keys on <code> for themed backgrounds - #274
fix(core): expose multi-theme keys on <code> for themed backgrounds#274pablofdezr wants to merge 2 commits into
Conversation
With multiple themes, Shiki emits the theme keys (`--shiki-light-bg`,
`--shiki-dark-bg`, ...) as inline styles on the `<pre>` element only.
rehype-pretty-code's documented CSS targets `<code>`:
code[data-theme*=' '] { background-color: var(--shiki-light-bg); }
That worked only because the custom properties inherit from `<pre>` down
to `<code>`, so the background variables were never actually present on
`<code>` as the docs (and the container itself) imply. This mirrors the
`<pre>` theme-key style onto `<code>` when multiple themes are active and
`keepBackground` is on, letting the container's own background be styled
per theme without relying on inheritance.
Single-theme output is untouched (its `<pre>` style paints real colors,
which we must not duplicate onto `<code>`), and `keepBackground: false`
still strips the keys from both elements.
Closes rehype-pretty#222
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
🦋 Changeset detectedLatest commit: 8f5bb60 The changes in this PR will be included in the next version bump. This PR includes changesets to release 1 package
Not sure what this means? Click here to learn what changesets are. Click here if you're a maintainer who wants to add another changeset to this PR |
commit: |
PR reviewA transformer-style leak can unexpectedly change Bugs (1)1. 🔴 Copying the complete pre style leaks unrelated declarationsLocation: code.properties.style = code.properties.style
? `${pre.properties.style};${code.properties.style}`
: `${pre.properties.style};`;The change intends to expose Shiki’s theme variables, but it copies every declaration added to Failure scenario: A transformer adds Fix: Copy only the relevant Docs (1)1. 🟠 Add a patch changesetLocation: // Shiki emits the dual-theme keys ... as inline styles on <pre> only.This changes published Failure scenario: The fix merges successfully but is absent from the next release because Changesets sees no package change. Fix: Add a changeset declaring VerdictRequest changes - the broad style copy can regress public transformer configurations. 🤖 Review generated with Codex |
Copying the whole <pre> style moved every declaration on it, including styling owned by user transformers: a transformer adding `padding:123px` to <pre> also changed <code>'s layout under a multi-theme config. Filter the copy down to the `--shiki-*` custom properties, which is all the themed-background selector needs. Adds a transformer regression test asserting the padding stays on <pre> while the theme variables still reach <code>. Existing snapshots are unchanged: Shiki writes nothing but those custom properties on <pre> in these fixtures. Also adds the patch changeset.
PR reviewThe transformer-leak fix from the previous round is correct, but the premise underneath it does not hold: Shiki already writes the Simplifications (2)1. 🔴 The mirrored declarations change nothing —
|
|
Addressed the review. The copy is now filtered down to the Added the transformer regression test: a transformer puts Existing snapshots are unchanged — Shiki writes nothing but those custom properties on Patch changeset added. Ready for another look. |
|
Before this year these would've been merged already 😅. But now models keep finding issues that the back-and-forth takes forever. PR reviewThis introduces a merge-blocking CSS-cascade regression. Default rendering remains unchanged, but consumers can no longer override the documented multi-theme variables using ordinary CSS. Bugs (1)1. 🔴 Mirrored theme variables block consumer overridesLocation: const themeProperties = getShikiCustomProperties(pre.properties.style);
if (themeProperties.length > 0) {
const declarations = `${themeProperties.join(';')};`;
code.properties.style = code.properties.style
? `${declarations}${code.properties.style}`
: declarations;
}On Failure scenario: A consumer applies Fix: Remove the mirroring block and its helper/output changes. The variables already resolve through inheritance; emitting them inline necessarily changes their override precedence. VerdictRequest changes - the inline declarations break the public multi-theme customization contract. 🤖 Review generated with Codex |
|
You're right on both counts, and I checked each before conceding rather than taking the review's word for it. On <pre style="--shiki-dark:#e1e4e8;--shiki-light:#24292e;--shiki-dark-bg:#24292e;--shiki-light-bg:#fff">
<code data-theme="github-dark github-light" style="display: grid;">
And the cascade point is the more serious half. Mirroring the variables into Closing this. #222 looks stale for the same reason: the variables it asks for are on Sorry for the rounds this one took to get to a clear answer. |
Summary
Closes #222.
When multiple themes are configured, Shiki emits the theme keys
(
--shiki-light-bg,--shiki-dark-bg, …) as inline styles on the<pre>element only. However, the documented way to theme a codeblock's background targets
<code>:Today that selector resolves only because CSS custom properties
inherit from
<pre>down to<code>— the background variables arenever actually present on
<code>, even though the docs (and thecontainer itself, via
data-theme) imply they are. As #222 notes, thekeys are only really set on the
<span>s and, since a later change, on<pre>.This PR mirrors the
<pre>theme-key style onto<code>when multiplethemes are active and
keepBackgroundis on, so the container's ownbackground can be styled per theme without relying on inheritance.
Behavior
<code>stylekeepBackground: true)--shiki-*+--shiki-*-bgkeys ✅keepBackground: false<pre>and<code><pre>paints realbackground-color/color, so we deliberately do not duplicate it onto<code>The
themeNames.length > 1guard aligns exactly with the documentedcode[data-theme*=' ']selector, which only matches whendata-themecontains a space (i.e. two or more themes).
Diff
Tests
codeBackgroundMultipleTheme.mdasserting the<code>element carries the theme keys.showLineNumbersStartAtMultipleThemesnapshot(only the
<code>style line changed).38/38); single-theme snapshots are untouched,confirming no double-paint regression.
typecheckandbiome checkboth pass.