0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

家計簿アプリにダークモードを実装してCSSを共通化した【改修記録⑦】

0
Posted at

はじめに

今回は2つの改修を同時に行いました。

  1. ダークモード対応(ブラウザ設定連動+手動切り替え)
  2. style.cssへの共通化(各ページのCSSを1ファイルに集約)

【シンプル家計簿】https://kakeibo-khaki.vercel.app/


ダークモードの実装

3段階の優先順位

手動設定(localStorage)> ブラウザ設定 > デフォルト(ライト)

CSSの構成

/* ① ライトモード(デフォルト) */
:root{
  --color-text-primary:#222;
  --color-background-primary:#fff;
  /* ... */
}

/* ② ブラウザ設定に自動連動 */
@media(prefers-color-scheme:dark){
  :root{
    --color-text-primary:#e8eaf6;
    --color-background-primary:#1a1d27;
    /* ... */
  }
}

/* ③ 手動ダークモード(classで上書き) */
html.dark{
  --color-text-primary:#e8eaf6;
  --color-background-primary:#1a1d27;
  /* ... */
}

/* ④ 手動ライトモード(ブラウザがダークでも強制ライト) */
html.light{
  --color-text-primary:#222;
  --color-background-primary:#fff;
  /* ... */
}

CSSの優先順位は「後に書いたものが勝つ」ので、html.darkhtml.light@mediaより後に書かれていることで手動設定が優先されます。

JavaScriptのテーマ切り替え処理

function applyTheme(theme){
  const html=document.documentElement;
  const btn=document.getElementById('theme-btn');
  html.classList.remove('dark','light');
  if(theme==='dark'){ html.classList.add('dark'); btn.textContent='☀️'; }
  else if(theme==='light'){ html.classList.add('light'); btn.textContent='🌙'; }
  else{
    // autoの場合はブラウザ設定に応じてボタンアイコンだけ変える
    btn.textContent = window.matchMedia('(prefers-color-scheme:dark)').matches ? '☀️' : '🌙';
  }
}

function toggleTheme(){
  // 現在ダークかどうかを判定
  const isDark = document.documentElement.classList.contains('dark') ||
    (!document.documentElement.classList.contains('light') &&
      window.matchMedia('(prefers-color-scheme:dark)').matches);
  const next = isDark ? 'light' : 'dark';
  localStorage.setItem('theme', next);
  applyTheme(next);
}

// 起動時に適用
applyTheme(localStorage.getItem('theme') || 'auto');

円グラフのダークモード対応

ドーナツグラフの中央の穴は白で塗りつぶしていましたが、ダークモード時に背景色と合わなくなります。CSS変数から背景色を取得して対応しました。

// CSS変数の値をJavaScriptから取得
const bgColor = getComputedStyle(document.documentElement)
  .getPropertyValue('--color-background-primary').trim();

// 中央の穴をCSS変数の背景色で塗る
ctx.beginPath();
ctx.arc(cx, cy, innerR, 0, 2*Math.PI);
ctx.fillStyle = bgColor || '#ffffff';
ctx.fill();

style.cssへの共通化

変更前の問題

index.html    → <style>300行のCSS</style>
about.html    → <style>200行のCSS</style>
howto.html    → <style>200行のCSS</style>
privacy.html  → <style>200行のCSS</style>
fixedcost.html→ <style>200行のCSS</style>
category.html → <style>200行のCSS</style>

同じCSSが6ファイルに重複していた状態でした。

変更後

style.css     → 共通CSS(1ファイルで管理)

index.html    → <link rel="stylesheet" href="style.css">
about.html    → <link rel="stylesheet" href="style.css">
howto.html    → <link rel="stylesheet" href="style.css">
privacy.html  → <link rel="stylesheet" href="style.css">
fixedcost.html→ <link rel="stylesheet" href="style.css">
category.html → <link rel="stylesheet" href="style.css">

メリット:

  • デザインを変えるときはstyle.cssだけ修正すればOK
  • 各HTMLファイルがスッキリした
  • ダークモードのCSS変数も1箇所で管理できる

まとめ

変更箇所 内容
style.css 新規作成・全ページ共通CSSを集約
全HTMLファイル <style>タグを<link>タグに変更
ダークモード ブラウザ連動+手動切り替え対応
円グラフ CSS変数から背景色を取得してダーク対応

これでこのアプリの改修は一旦終了しますが、ご要望などございましたらコメントしていただければ対応していきたいと考えています!
この記事を読んでいただいてありがとうございました。
また別のアプリの考案をしていきます。

★開発したアプリ
【シンプル家計簿】https://kakeibo-khaki.vercel.app/

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?