外部iframe(はてなブログカード)のダークモードに対応する

公開日:
目次

サイトにダークモードを実装したものの、はてなブログのリンクカードなど外部iframeが白いままで浮いてしまう問題を、CSSフィルターを使って解決したので備忘録を残します。

外部iframeがダークモードに対応しない

ブログサイトでダークモード対応を実装しましたが、はてなブログのリンクカードのiframeだけが白背景のまま残ってしまいました。

はてなブログのリンクカードは以下のようなiframeで表示されており、hatenablog-parts.comという外部ドメインのため、直接CSSでスタイリングすることができません。

<iframe 
  class="hatenablogcard" 
  style="width:100%;height:155px;max-width:680px;" 
  src="https://hatenablog-parts.com/embed?url=https://example.com" 
  width="300" 
  height="150" 
  frameborder="0" 
  scrolling="no">
</iframe>

Same-Origin Policy(同一オリジンポリシー)

外部ドメインのiframe内のコンテンツは、セキュリティ上の理由でJavaScriptやCSSから直接操作することができません。

これにより、通常のCSS手法では外部サービスのダークモード対応ができません。

CSSフィルターによる色反転

CSSのfilterプロパティを使用することで、iframe全体の色を反転させることでダークモード風の見た目を実現します。

基本的な実装

/* ダークモード時に外部iframeを反転 */
[data-theme="dark"] .external-iframe,
.dark .external-iframe {
  filter: invert(1) hue-rotate(180deg) brightness(0.9) contrast(0.9);
  border-radius: 8px;
}

はてなブログカードの場合

/* はてなブログリンクカードのダークモード対応 */
[data-theme="dark"] .hatenablogcard,
.dark .hatenablogcard {
  filter: invert(1) hue-rotate(180deg) brightness(0.9) contrast(0.9) !important;
  border-radius: 8px !important;
}

このCSSを適用することで、はてなブログのリンクカードがダークモードに対応し、白背景が黒背景に変わります。

その他の外部iframeでも同様の方法でダークモード対応が可能です。

フィルターの詳細解説

各プロパティの役割

プロパティ 効果
invert(1) 100%反転 白→黒、黒→白に色を反転
hue-rotate(180deg) 180度回転 色相を調整してより自然な色に
brightness(0.9) 90%の明度 少し暗くしてダークモード感を演出
contrast(0.9) 90%のコントラスト コントラストを下げて目に優しく

パラメータの調整例

用途に応じてパラメータを調整できます:

/* より暗いダークモード */
filter: invert(1) hue-rotate(180deg) brightness(0.8) contrast(0.8);

/* コントラスト重視 */
filter: invert(1) hue-rotate(180deg) brightness(0.9) contrast(1.1);

/* 色味を変えたい場合 */
filter: invert(1) hue-rotate(200deg) brightness(0.9) contrast(0.9);

外部iframeのダークモード対応はfilterプロパティを使用することで実現できます。

完璧ではありませんが、ユーザビリティを大幅に改善できる実用的な解決策です。

参考