[Astro] Markdownのコードハイライトを Shiki でライト/ダーク両対応にする
Tech技術ブログだとコードブロックの見た目は地味に大事です。Astro は Shiki を標準で内蔵していて、設定だけで Markdown のコードハイライトが効きます。さらに、ライトモードとダークモードで配色を切り替えることもできるので、その設定をまとめます。
デュアルテーマを指定する
astro.config.mjs の markdown.shikiConfig.themes に、light / dark それぞれのテーマを指定します。追加パッケージは不要(Shiki は Astro 同梱)。
// astro.config.mjs
import { defineConfig } from 'astro/config';
export default defineConfig({
markdown: {
shikiConfig: {
themes: {
light: 'github-light',
dark: 'github-dark',
},
},
},
});
theme(単数)ではなく themes(複数) で light/dark を渡すのがデュアルテーマのキモです。
CSS でダーク配色を有効化する
デュアルテーマにすると、Shiki は各トークンにライト用の色 + --shiki-dark というCSS変数を一緒に出力します。デフォルトのままだとライト配色しか効かないので、ダーク時に --shiki-dark を使うよう CSS を1つ足します。
/* src/styles/global.css */
@media (prefers-color-scheme: dark) {
.astro-code,
.astro-code span {
color: var(--shiki-dark) !important;
background-color: var(--shiki-dark-bg) !important;
}
}
Shiki が出力するコードブロックは .astro-code というクラスを持っています。ダークモード時にこのクラス(と中の span)の色を --shiki-dark / --shiki-dark-bg に差し替えることで、配色が切り替わります。
ここでは OS 設定に追従する
prefers-color-schemeで切り替えていますが、クラス(.darkなど)で手動トグルしたい場合は、メディアクエリの代わりにそのクラスをセレクタに使えば OK です。
ついでに見た目を整える
.astro-code に角丸やパディングを足しておくと、prose の中でも馴染みます。
.astro-code {
border-radius: 0.5rem;
padding: 1.25rem;
font-size: 0.875rem;
line-height: 1.7;
}
確認
適当な Markdown にコードブロックを書いて、OS のダークモードを切り替えてみます。
```js
const hello = 'world';
console.log(hello);
```
ライト時は github-light、ダーク時は github-dark の配色に切り替われば成功です。設定2か所(config の themes と CSS の --shiki-dark)だけで両対応になるので、コストの割に効果が大きいカスタマイズでした。
Astro, Shiki, Markdown