目次
Next.jsブログでzenn-markdown-htmlを使っていて、ダークモードでテーブル(表)が見づらい問題を解決したので備忘録を残します。
zenn-markdown-htmlのダークモード問題
Next.jsとnext-themesでダークモード切り替えを実装していましたが、zenn-markdown-htmlで変換したmarkdown内のテーブルがダークモードでも白背景のままで、非常に見づらい状態でした。
コードブロックの背景は元々ダークブルーだったので問題なかったのですが、表だけが白く浮いてしまっていました。
zenn-markdown-htmlのダークモード対応
2025年5月にzenn-markdown-htmlがv0.1.160でダークモードに対応しました。
data-theme属性を使ってテーマを切り替えることができるようになっています。
この機能を使うことで、markdownコンテンツ内の表などがダークモードに適切に対応できるようになりました。
zennがダークモード対応してるので見てみたらzenn-markdown-htmlもダークモード使えそうなので自分のブログも修正。
— Clameyes (@clameyes39) August 3, 2025
今までダークモードで表だけ明るすぎたので助かる。
実装手順
パッケージのアップデート
まず、zenn関連パッケージを最新版にアップデートします。
npm update zenn-markdown-html zenn-content-css zenn-embed-elements
バージョン0.1.160以降が必要です。確認するには以下のコマンドを実行します。
npm list zenn-markdown-html zenn-content-css zenn-embed-elements
markdownコンテンツにdata-theme属性を追加
markdownコンテンツを表示している部分で、zncクラスがついた要素にdata-theme属性を追加します。
// 基本的な実装例
const { theme } = useTheme()
// markdownコンテンツを表示する部分
<div className="znc" data-theme={theme === 'dark' ? 'dark-blue' : 'light'}>
<div dangerouslySetInnerHTML={{ __html: markdownContent }} />
</div>
next-themesを使っている場合のハイドレーションエラー対策も含めた実装は下記の通りです。
import { useTheme } from 'next-themes'
import { useEffect, useState } from 'react'
const MarkdownRenderer = ({ content }: { content: string }) => {
const { theme } = useTheme()
const [mounted, setMounted] = useState(false)
useEffect(() => {
setMounted(true)
}, [])
if (!mounted) {
return <div className="znc" dangerouslySetInnerHTML={{ __html: content }} />
}
return (
<div className="znc" data-theme={theme === 'dark' ? 'dark-blue' : 'light'}>
<div dangerouslySetInnerHTML={{ __html: content }} />
</div>
)
}
コード解説
data-theme属性
zenn-content-cssは以下のテーマをサポートしています:
light: ライトモード(デフォルト)dark-blue: ダークモード
zncクラスが付いた要素にdata-theme属性を設定することで、その配下のコンテンツのテーマが切り替わります。
next-themesとの連携
useThemeフックでnext-themesの現在のテーマを取得し、それに応じてdata-themeを切り替えています。
ハイドレーションエラー対策
const [mounted, setMounted] = useState(false)
useEffect(() => {
setMounted(true)
}, [])
if (!mounted) {
return null
}
この部分はSSRとクライアントサイドでのテーマの不一致によるハイドレーションエラーを防ぐための処理です。
これでmarkdownコンテンツもダークモードに対応し、テーブルが暗い背景と境界線で適切に表示されるようになりました。
