Site cover image

📖Ast-Rock Blog

Notion + astro なブログ

🌙astro-notion-blog にダークモードを導入する

Image in a image block

astro-notion-blog は Notion のページ(データベース)をブログとして公開できるツールです。

Astroというフレームワークで書かれているためページの表示が早く、ユーザーの好きなようにカスタマイズできるのがメリットです。

この記事では astro-notion-blog にダークモードを導入する手順を紹介します。

インストールしたばかりの astro-notion-blog を想定しているため、すでにカスタマイズをしている場合は表示が崩れる場合があるので調整が必要です。

astro-notion-blog + ダークモード

👉

Github

動作デモ

ダークモードトグルは タイトル下の ナビゲーション内に表示されます。クリック、タッチごとにダークモードとライトモードの切り替えが可能です。初回訪問時はブラウザの設定が優先されます。

また、ブラウザのローカルストレージにモードを保存しているためページを遷移してもダークモードが保持されます。

Darkmode.astro を作成

src/components/ディレクトリに Darkmode.astroというファイルを新しく作成します。

下記のコードを丸ごとDarkmode.astro として保存しましょう。

こちらからも Darkmode.astroのコードを参照できます。

---
---

<div class="mode-wrap">
  <input type="checkbox" id="mode-toggle" tabindex="0" />
  <label for="mode-toggle"><span></span></label>
</div>

<style is:global>
/* --------------------
layout.astro
-------------------- */
:root.darkmode {
  --bg: #191919;
  --fg: #d5d5d5;
  --accents-1: #864C1D;
  --accents-2: #f26000;
  --accents-3: #a5a5a5;;
}
.darkmode .header h1 {
  color: var(--fg);
}

.darkmode aside {
  background: #202020;
  color: var(--fg);
}

.darkmode a:hover {
  background: #333 !important;
}

/* --------------------
pages/index.astro
-------------------- */
.darkmode .read-more-link a {
  color: var(--fg);
}
/* --------------------
posts/[slug].astro
-------------------- */
.darkmode .content h1 {
  color: var(--fg);
}

/* --------------------
NoContents.astro
-------------------- */
.darkmode .no-contents {
  color: var(--accents-3);
}

/* --------------------
Pagination.astro
-------------------- */
.darkmode .pagination a{
  background: #333;
}
.darkmode .pagination a:hover:not(.inactive) {
  background: #555;
}
.darkmode .pagination a.inactive {
  color: #f7f7f7;
  background: #444;
}
/* --------------------
Bookmark.astro
-------------------- */
.darkmode .bookmark {
  background: #202020;
}

/* --------------------
BulletedListItems.astro
-------------------- */
.darkmode li {
  color: var(--fg);
}

/* --------------------
Callout.astro
-------------------- */
.darkmode .callout.gray-background {
  background: #252525 !important;
}

/* --------------------
Code.astro
-------------------- */
.darkmode .code pre {
  background: #272727 !important;
}
.darkmode .code pre code {
  color: var(--fg);
  background: #272727 !important;
}
.darkmode code {
  background: #2F2F2D;
}

.darkmode .code > div {
  background: #272727;
}

.darkmode .code button.copy {
  background-color: rgba(227,226,224,0.2);
}

/* --------------------
Caption.astro
-------------------- */
.darkmode .caption {
  background: var(--bg) !important;
}

/* --------------------
Paragraph.astro
-------------------- */
.darkmode p {
  color: var(--fg);
}

/* --------------------
SyncedBlock.astro
-------------------- */
.darkmode .callout.blue-background {
  background: #1D282E !important;
}

/* --------------------
Table.astro
-------------------- */
.darkmode table {
  color: var(--fg);
}
.darkmode table th {
  background: #272727;
  border-color: #272727;
}
.darkmode table td {
  border-color: #272727;
}

/* --------------------
TableOfContents.astro
-------------------- */
.darkmode .table-of-contents > a {
  color: #9B9B9B;
}
.darkmode .table-of-contents > a:hover {
  background: rgba(241, 241, 239, 0.1) !important;
}

/* --------------------
ToDo.astro
-------------------- */
.darkmode .to-do {
  color: var(--fg);
}

/* --------------------
PostRelativeLink.astro
-------------------- */
.darkmode div.post-relative-link > div > a.colored  {
  background: rgba(227,226,224,0.1);
}

/* --------------------
notion-color.css
-------------------- */
.darkmode .tag.default {
  background: #373737 !important;
  color: #f7f7f7;
}
.darkmode .tag.gray,
.darkmode .gray-background {
  background: #5a5a5a !important;
  color: #f7f7f7;
}
.darkmode .tag.brown,
.darkmode .brown-background {
  background: #603b2c !important;
  color: #f7f7f7;
}
.darkmode .tag.orange,
.darkmode .orange-background {
  background: #864C1D !important;
  color: #f7f7f7;
}
.darkmode .tag.yellow,
.darkmode .yellow-background {
  background: #8a632a !important;
  color: #f7f7f7;
}
.darkmode .tag.green,
.darkmode .green-background {
  background: #2c5940 !important;
  color: #f7f7f7;
}
.darkmode .tag.blue,
.darkmode .blue-background {
  background: #28456c !important;
  color: #f7f7f7;
}
.darkmode .tag.purple,
.darkmode .purple-background {
  background: #493064 !important;
  color: #f7f7f7;
}
.darkmode .tag.pink,
.darkmode .pink-background {
  background: #613047 !important;
  color: #f7f7f7;
}
.darkmode .tag.red,
.darkmode .red-background {
  background: #6f3630 !important;
  color: #f7f7f7;
}

/* --------------------
ダークモードトグル
-------------------- */
.mode-wrap {
  display:flex;
  margin-block-end: 1rem;
}

.mode-wrap #mode-toggle {
  display: none;
}

.mode-wrap #mode-toggle + label {
  display: -webkit-inline-flex;
  display: -ms-inline-flexbox;
  display : inline-flex;
  align-items: center;
  font-size: 1rem;
  height: 1.6em;
  width: 2.4em;
  -webkit-box-sizing: border-box;
  box-sizing: border-box;
  border-radius: calc(2em / 2);
  background: #fff;
  -webkit-transition: 0.2s;  transition: 0.2s;
  border: 2px solid var(--accents-1);
  overflow: hidden;
  cursor: pointer;
  -webkit-tap-highlight-color: rgba(0,0,0,0);
}

.mode-wrap #mode-toggle + label span {
  background: var(--accents-1);
  border-radius: 50%;
  height: 1.8em;
  width: 1.8em;
  -webkit-transform: translateX(-0.125em) scale(0.65);
  transform: translateX(-0.125em) scale(0.65);
  -webkit-transition: 0.2s;
  transition: 0.2s;
  cursor: pointer;
}

.mode-wrap #mode-toggle:checked + label {
  border-color: var(--bg);
  background: var(--accents-1);
}

.mode-wrap #mode-toggle:checked + label span {
  background: var(--bg);
  -webkit-transform: translateX(calc(100% - 1.25em)) scale(0.65);
  transform: translateX(calc(100% - 1.25em)) scale(0.65);
}

.darkmode .mode-wrap #mode-toggle + label {
  border-color: var(--accents-1);
}
</style>

<script is:inline>
/* --------------------
ダークモード切り替え
-------------------- */
// OS設定を反映
const osDark = window.matchMedia("(prefers-color-scheme: dark)");
// トグル処理
const modeToggle = document.getElementById("mode-toggle");
function darkModeOn() {
  document.documentElement.classList.add("darkmode");
  modeToggle.checked = true;
}

function darkModeOff() {
  document.documentElement.classList.remove("darkmode");
  modeToggle.checked = false;
}

const listener = (event) => {
  if (event.matches) {
    darkModeOn();
  } else {
    darkModeOff();
  }
};

osDark.addEventListener("change", listener);
listener(osDark);

modeToggle.addEventListener("change", () => {
  if (modeToggle.checked) {
    darkModeOn();
    style = "dark";
  } else {
    darkModeOff();
    style = "light";
  }
  localStorage.setItem("mode", style);
});
// モード設定をロード
if (localStorage.getItem("mode") === "dark") {
  darkModeOn();
} else if (localStorage.getItem("mode") === "light") {
  darkModeOff();
}
</script>

参考にしたサイト

Layout.asrto を編集

src/layout/Layout.astroを編集

ダークモードのコンポーネントを読み込む

挿入場所は import GoogleAnalytics from …の下あたり

import Darkmode from '../components/Darkmode.astro'

ダークモード切り替えのトグルボタンを好きな位置に入れる。

サイドバーに入れたい場合は、<aside></aside>内に <Darkmode /> を挿入する。

<aside>
  <Darkmode />
  <slot name="aside" />
</aside>

カスタマイズ

ダークモードカラーはNotion風の配色にしていますが、好きなように変更することができます。

好みの色に変更したい場合は Darkmode.astroの該当箇所を調整してください。

基本的な文字色は--fg、背景色は --bgを修正することで変更できます。

オレンジ色のアクセントカラーを変更するには --accents-1を修正するとサイトのイメージカラーに合うトグルの色になります。リンクの色も —accents-1 です。

文章(段落:p)の色は .darkmode p {}の部分です。

配色バランスが難しいですが、頑張ってやってみてください。