Bear Blog カスタマイズ
(2026.11 更新)
Bear Blogプラットフォームで配信中の当ブログに施したカスタマイズ等についてのノートです。自己言及的なブログについてのブログ、いわゆるメタ投稿が増えすぎないよう、ここに全てまとめることにしました。追加・変更がありしだい更新します。
こんな工夫をしてみたよというだけで、教育的・資料的な内容ではありません。どうせ大したことをしていません。もしコードを知りたければ、このブログをブラウザーの開発ツールで覗いてみてください(ものによってはミニファイされたソースも復元表示できる)。
前提
何ができるか・どうやるのか、基本的なカスタマイズ方法はBear Blog公式ドキュメントに網羅されています。ここでは重ねて解説しません。
Bear Blogのビジネスモデルはフリーミアムで、無料プランではできることが制限されます。ここでは制限なしの有料プランを前提とします。
カスタムCSS
書き換えではなく追加
うちのブログのテーマは、デフォルトテーマを少し変更しただけのお手軽なもの。ただ、実現方法をちょっぴり工夫しています。デフォルトテーマのCSSの後ろに、その定義を上書きするCSSを加える構成としているのです。
なぜそうしたか。まず、デフォルトテーマを基礎としたのは、それが最も無難だからです。レイアウトがシンプルなうえ、デフォルトゆえにBear Blogの機能と最もよく親和・調和するであろう安心感があります。
そして、デフォルトテーマのCSSを直接書き換えず、後ろに追加して上書きする形にしたのは、Bear Blogの将来の仕様変更に対応しやすくするためです。もし仕様が変更されたら、既製テーマの内容もそれに合わせて調整される可能性があるでしょう。そんなとき、「素の既製テーマ + 追加差分」との形でCSSがあらかじめ分離されていれば、更新が比較的ラクにできます。
アクセシビリティー
少なくとも監査ツールで判定できる範囲では、Bear Blogのデフォルトテーマのアクセシビリティーは悪くありません。ただし2026年11月現在、ひとつだけ監査に引っかかる項目がありました。テキストブロックつまり本文中のリンクのコントラストが足りないのです。ここで言うのは背景色と文字色とのコントラストではなく、通常文字列とリンク文字列とのコントラスト。つまりリンク部分を区別しやすく目立たせろというわけです。
監査では、配色よりもスタイルの違いで目立たせる解決策が推奨されています。そこでうちのブログでは、本文中のリンクに下線を引くことにしました。
印刷への配慮
元のテーマにはない、印刷(Printメディアクエリー)向けのスタイルを追加しました。印刷にはさまざまなテクニックがあるのですが、深追いせず主に次のことだけしています。
- 不要な要素を省く
- ボタン類は印刷では無意味
- 白地に黒のモノクロ配色にする
- 印刷物として何かと都合がよい
- 段組みにする
- より読みやすく、用紙を効率よく使える
- 基準フォントサイズ(1rem)を10.5ポイントにする
- 和文印刷の標準に合わせる
なお、印刷機能はPDF化のために使われることもあり、紙への特化には賛否両論あり得ます。しかしブログサイトに限っては、文章さえちゃんと読めればまず問題ないでしょう。
ユーザー設定メニュー
訪問者の選好に応え、またアクセシビリティーを向上するため、「設定」メニューを設けました。JavaScriptが有効なら追加され、無効なら何も変わらぬプログレッシブ・エンハンスメントです。
ひな形コード
汎用的な丁寧な作りではまったくありません。しかしきわめて単純で、HTML/CSSさえ理解していれば変更・拡張は容易だと思います。最低限の設定項目(テーマと文字サイズ)を備えたコードを以下に示します。使うにはHTMLのheadディレクティブに追加します。
<script>
/*! Settings.js by M.T. - 自己責任で自由に利用・改変してください */
'use strict';
{
// 名前・値をHTML属性とCSS変数に反映する関数
const setKeyValue = async (key, val) => {
document.documentElement.setAttribute('data-settings-' + key, val);
document.documentElement.style.setProperty('--settings-' + key, val);
}
// ローカルストレージからJSONを読み込み、HTML属性とCSS変数に反映(レンダリングに影響するため、なるべく早く実行する)
const Settings = JSON.parse(localStorage.getItem('Settings') || '{}');
for (let key in Settings) setKeyValue(key, Settings[key]);
window.addEventListener('DOMContentLoaded', async (e) => {
// DOMへ設定ダイアログ要素を追加
document.querySelector('footer').insertAdjacentHTML('afterend', `
<dialog id="Settings" closedby="any" aria-labelledby="Settings-Title">
<button id="Settings-Close" type="button">閉じる</button>
<section>
<h1 id="Settings-Title">設定</h1>
<ul>
<!-- 設定項目。項目を増やすには、<li>…</li>を複製してselectやinputのnameを変える -->
<li>
<label for="Settings-Theme">テーマ</label>
<select id="Settings-Theme" name="theme">
<option value="auto">自動</option>
<option value="light">ライト</option>
<option value="dark">ダーク</option>
</select>
</li>
<li>
<label for="Settings-FontSize">文字サイズ</label>
<input id="Settings-FontSize" name="fontsize" type="range" min="1.0" max="1.5" step="0.01" value="1.0"/>
</li>
</ul>
</section>
</dialog>`);
// 設定ダイアログ内のselect,input要素を走査
document.querySelectorAll('#Settings select, #Settings input').forEach(async (ele) => {
// JSONの内容を初期値に反映
{
const val = Settings[ele.name];
if (val !== undefined) {
if (ele.type !== 'checkbox') {
if (val !== null) ele.value = val;
} else {
ele.checked = (val !== null);
}
}
}
// 値変更イベントリスナー
ele.addEventListener('change', async (e) => {
const ele = e.target;
const val = (ele.type !== 'checkbox' || ele.checked)? ele.value : null;
// 名前・値をHTML属性とCSS変数に反映
setKeyValue(ele.name, val);
// 値をJSONとしてローカルストレージに保存
Settings[ele.name] = val;
localStorage.setItem('Settings', JSON.stringify(Settings));
});
});
// DOMのヘッダーナビゲーション内に「設定」ボタンを追加
document.querySelector('header nav > p').insertAdjacentHTML('beforeend', `<button id="Settings-Button" type="button">設定</button>`)
// 設定ボタンのクリックイベントリスナー
document.getElementById('Settings-Button').addEventListener('click', (e) => {
document.getElementById('Settings').showModal(); // 設定ダイアログを開く
});
// 閉じるボタンのクリックイベントリスナー
document.getElementById('Settings-Close').addEventListener('click', (e) => {
document.getElementById('Settings').close(); // 設定ダイアログを閉じる
});
});
}
</script>
コード中に、ダイアログのHTMLをDOMに追加している部分がありますね。このダイアログ内のselectまたはinputを操作すると、その要素のname属性・value属性の値の組が次のようにHTMLとCSSに反映される仕組みになっています。
- html要素に属性「
data-settings-[name属性値]="[value属性値]"」が設定される- 例:
<html data-settings-theme="light">
- 例:
- CSSに変数「
--settings-[name属性値]: "[value属性値]"」が設定される- 例:
--settings-theme: "light";
- 例:
あとは、これらの属性・変数に応じて変化するCSSを書けばいいだけです。たとえば次のように。
/* 設定を反映するためのCSS(デフォルトテーマCSSの「後ろ」に追加)*/
/* 文字サイズ */
:root {
--font-scale: calc(1em * var(--settings-fontsize, 1));
}
/* テーマ:ライト(指定) */
html[data-settings-theme="light"] { /* ちなみにhas疑似クラスを利用する手もある */
color-scheme: light;
--background-color: #fff;
--heading-color: #222;
--text-color: #444;
--link-color: #3273dc;
--visited-color: #8b6fcb;
--code-background-color: #f2f2f2;
--code-color: #222;
--blockquote-color: #222;
}
/* テーマ:ダーク(指定) */
html[data-settings-theme="dark"] {
color-scheme: dark;
--background-color: #01242e;
--heading-color: #eee;
--text-color: #ddd;
--link-color: #8cc2dd;
--visited-color: #8b6fcb;
--code-background-color: #000;
--code-color: #ddd;
--blockquote-color: #ccc;
}
設定ダイアログ自体に関するスタイルは示しません。お好みでCSSに加えてください。
なお現状、select・input要素のすべてのバリエーションに対応しているわけではありません。自分では使う予定がなく面倒なので試していませんが、複数選択や特定のtype属性ではうまく動かない恐れがあります。
現在の設定項目
- テーマ
- よくある配色選択。WCAG2.2のAAAに適合する高コントラストをどぎつく感じる人(わたし)のため、AAをギリギリ満たす「薄」や「グレー」も用意
- 本文フォント
- ゴシック体か明朝体かを選ぶことができる。個人的には後者を好むものの、Chromium系でかすれがちなため標準にしにくい
- 文字サイズ
- 文字の大きさを標準の1.0~1.5倍のあいだで調整できる。ちなみに「サイトに文字サイズ調整機能は不要」との神話は9割しか真実ではない
- カラム幅
- 行あたりの文字数を標準の0.75~1.25倍のあいだで調整できる
- 認知の支援
- 神経多様性や障害により、周囲の情報に気が散って集中しにくい・同じ行を気づかず繰り返し読んでしまう、といった人のための簡易的な支援機能
脱・いいね!
数字を消す
Bear Blogの投稿記事には、高評価つまりいわゆる「いいね!」ボタンが付いています。デフォルトではその評価数が表示され、人気の指標としてトレンド順のディスカバーフィードにも使われます。しかし、わたしを含めこうしたソーシャルメディア的な機能を敬遠したい人もいるでしょう。Bear Blogの開発者もそれは重々承知しており、これを書いているつい最近、仕様にテコが入りました。
高評価ボタンは従来どおり存在します。ただし、ディスカバーフィードに評価数が表示されなくなりました。そして、管理画面に「Hide upvotes」チェックボックスが追加されました。これを有効にすると、高評価ボタンに添えられていた評価数の表示も消えます。
さらに管理画面で「Collect analytics」を無効にすると、アクセス統計機能がまるごとなくなり、ブログ運営者にさえ投稿のアクセス数・評価数がわからなくなります。
押せないボタン
評価数が見えなくなれば通常十分でしょうが、押されることすら避けたい場合、HTMLのheadディレクティブにコンテンツセキュリティーポリシー(CSP)「<meta http-equiv="Content-Security-Policy" content="form-action 'none'; connect-src 'none'">」を加えてフォーム送信・非同期通信を遮るのが最も確実な方法です(雑な指定につき副作用に注意)。CSSやJavaScriptでボタンを隠す・削除する方法は併用するには結構ですが、知識のある人に回避されてしまう恐れがあります。
ボタンをなくす?
投稿がディスカバーフィードに載らなくても構わなければ、投稿のヘッダーに「discoverable: false」を指定すれば、高評価ボタンを元からなくすことができます。しかし、Geminiカプセルなる孤独な虚空を経てBear Blogにたどり着いた身としては、そうしてせっかくのコミュニティーに背を向けるつもりは今のところありません。
補足
技術的な詳細を補足します。2026年11月現在の情報です。
高評価したことをサーバーに受け付けてもらうには、「トークン」すなわちサーバーが発行する使い捨て認証キーが必要です。そのトークンは、ページを開いたときにバックグラウンドでJavaScriptがサーバーに要求しています。つまり、JavaScriptが有効でないと高評価ボタンは機能しません。
また蛇足ながら、正確を期すため記しておきます……。くだんのトークン取得の応答には、「評価数」も含まれています。第1節の方法で「数字を消」し、もはや不要なはずでも。したがって実は、開発ツールなどでこの応答の中身を見れば、設定に関係なく常に評価数を確認できてしまいます。
管理画面のスタイル
自ウェブサイト・GeminiカプセルからBear Blogに引っ越して良かったことのひとつは、投稿をウェブ上で作成・編集しすぐに配信できる手軽さ。CMSでは当たり前ですが、自前のツールや静的サイトジェネレーターを長年使っていると、そんなことがやけに新鮮でうれしいのです。
というわけで、投稿を管理画面上のエディター(ただのテキストエリア)で直に書くことがよくあります。ただ、やはり少々使いにくいところがある。幸い、Bear Blogの管理画面はCSS・JavaScriptを追加してカスタマイズできる仕組みになっています。そこで、次のCSSを適用しました。
/* 投稿エディターの調整 */
.editor-body, .editor-header, textarea {
font-size: .875rem; /* 文字の大きさ */
line-height: 1.5em; /* 行間 */
tab-size: 2; /* タブ幅 */
word-break: break-all; /* 単語の途中でも折り返す */
}
調整内容はコメントのとおり。要するに、デフォルトのままではテキストエリアを狭く感じたため、文字の大きさや行間をやや小さくしました。
「word-break: break-all」とは何か。文章が領域幅に沿って折り返される際、英語などの単語は途中で切れないように調整され、その結果行末に大きな空白が空くことがあります。特に厄介なのが、URLやコードなどのえらく長い文字列までもそうした単語とみなされてしまうこと。日本語でしか書かない場合、こんな挙動は煩わしいだけなので、単語をどこで切ってもいいよと指示しています。
Tips
妥当なフッター
これを書いている現在、footerディレクティブには不具合があります。そこに入る文字列や要素は自動的にp要素で囲まれるのですが、footerディレクティブ自体はspan要素のため、下の例のように構造が矛盾してしまうのです(HTML標準ではspanにpを含めてはいけない)。単純な誤りとはいえ影響範囲を考えると、開発者に報告したところでおいそれと直せるものか疑問です。
<span id="footer-directive">
<p>フッター文字列</p>
</span>
しかし、回避方法を見つけました。文字列の前にHTMLコメント「<!---->」を置くのです。するとなぜかp要素で囲まれず、生成されるHTML構造は次のようになります。
<span id="footer-directive">
<!---->フッター文字列
</span>
評価
テストと呼ぶほど厳格ではありませんが、CSSやJavaScriptが露骨に壊れていないか、アクセシビリティーやパフォーマンスを悪化させていないか、くらいを下記の手段で確認しています。
動作確認ブラウザー
原則として、シェアの大きなChromeとMobile Safari、そしてFirefoxで確認しています。さらにJavaScriptやCSSを無効にしたり、印刷を試してみたり。またBear Blogの対象外でしょうが、Lynxなどのテキストブラウザーで開いてみることもあります。
監査ツール
主に次の監査ツールを用いて一般的な問題点をざっと洗い出します。
- The W3C Markup Validation Service
- W3CのHTMLバリデーター
- PageSpeed Insights
- パフォーマンス・アクセシビリティー・ベストプラクティス・SEOの基本的な監査。実体である「Lighthouse」はChromeにも内蔵されている
- Website Carbon™ Calculator
- ウェブサイトの炭素排出量つまり消費エネルギーを推計。これをなるべく低く抑えるサステナブル・ウェブデザインを心がける
- Analyse your HTTP response headers
- HTTP応答ヘッダーによるサイトの安全性を判定
- Test for modern Internet Standards
- ウェブサーバー実装やドメイン設定の堅牢性を判定
最後の2つはBear BlogサーバーやCDNに関する監査で、われわれ利用者には改善しようがありません。それでも結果を知っておけば、プラットフォームの輪郭が明瞭になり、リスク見積もりの材料にもなるでしょう。