Chrome拡張機能のpopup画面を作る:HTML・CSS・JavaScriptで小さな操作画面を整える
前回の記事では、manifest.json、popup.html、popup.js の最小構成で、Chrome拡張機能をまず動かすところまで確認しました。
今回は、そのpopup画面をもう少し実用的な形に整えます。
Chrome拡張機能のpopupは、ツールバーの拡張機能アイコンを押したときに表示される小さな画面です。設定を切り替えたり、現在の状態を見せたり、処理を実行するボタンを置いたりできます。
popupは特別な画面に見えますが、基本はHTML、CSS、JavaScriptで作れます。通常のWebページと同じように、HTMLで構造を作り、CSSで見た目を整え、JavaScriptで操作に反応させます。
この記事では、初心者でも追いやすいように、外部API通信やタブ操作は扱いません。まずは「押せる」「状態が変わる」「見た目が整っている」popupを作ります。

popup画面の役割
popup画面は、Chrome拡張機能の入口になることが多い画面です。
たとえば、次のような用途に向いています。
- 機能を実行するボタンを置く
- 現在の状態を表示する
- ON/OFFの設定を切り替える
- 保存済みの情報を簡単に確認する
- 詳細画面や設定画面へのリンクを置く
一方で、popupは大きなアプリ画面ではありません。
ツールバーから一時的に開く小さな画面なので、長い入力フォームや複雑な一覧表示を詰め込みすぎると使いにくくなります。
popupでは、よく使う操作を少数に絞るのが基本です。
今回作るpopupの完成イメージ
今回は、次のようなpopupを作ります。
- タイトルを表示する
- 説明文を表示する
- 現在の状態を表示する
- ボタンを押すと状態文が変わる
完成後の動きはシンプルです。
最初は「待機中」と表示します。ボタンを押すと「処理を実行しました」に変わります。
実際の業務ツールでは、このボタンに「ページ情報を取得する」「コメントを保存する」「設定を反映する」といった処理をつなげられます。ただし、この記事ではpopup画面そのものに集中するため、まずは状態表示だけを変えます。
ファイル構成
今回のフォルダ構成は次の通りです。
popup-sample-extension/
├─ manifest.json
├─ popup.html
├─ popup.css
└─ popup.js前回の最小構成では、CSSを popup.html の中に直接書いていました。
今回は、見た目の調整を分かりやすくするために popup.css を分けます。
役割は次の通りです。
| ファイル | 役割 |
|---|---|
manifest.json | 拡張機能の基本設定を書く |
popup.html | popup画面のHTML構造を書く |
popup.css | popup画面の見た目を整える |
popup.js | ボタン操作や状態表示の処理を書く |
manifest.json が popup.html を指定し、popup.html から popup.css と popup.js を読み込む関係です。

manifest.json で popup.html を指定する
まず、manifest.json を作ります。
{
"manifest_version": 3,
"name": "Popup Sample Extension",
"version": "1.0.0",
"description": "popup画面の作り方を確認するサンプル拡張機能です。",
"action": {
"default_popup": "popup.html"
}
}popup画面を指定しているのは、次の部分です。
"action": {
"default_popup": "popup.html"
}action.default_popup に指定したHTMLファイルが、拡張機能アイコンを押したときに開きます。chrome.action API(公式)の詳細や action キーの役割はManifest V3の記事でも解説しています。
今回のpopupは、Chrome APIを使わずに画面内の表示だけを変えるため、permissions は書きません。
権限は、必要になったときだけ追加します。最初から広い権限を入れないことは、Chrome拡張機能を安全に作るうえで大切です。
popup.html で画面の構造を作る
次に、popup.html を作ります。
<!doctype html>
<html lang="ja">
<head>
<meta charset="UTF-8">
<title>Popup Sample</title>
<link rel="stylesheet" href="popup.css">
</head>
<body>
<main class="popup">
<p class="label">Chrome Extension</p>
<h1>Popup Sample</h1>
<p class="description">
ボタンを押すと、popup内の状態表示が変わります。
</p>
<section class="status-box" aria-live="polite">
<span class="status-label">現在の状態</span>
<strong id="status-text">待機中</strong>
</section>
<button id="run-button" type="button">
処理を実行する
</button>
</main>
<script src="popup.js"></script>
</body>
</html>HTMLでは、画面に必要な要素だけを置いています。
id="status-text" は、JavaScriptから状態表示を書き換えるために使います。
id="run-button" は、ボタンが押されたことをJavaScriptで受け取るために使います。
aria-live="polite" は、状態表示が変わったことを支援技術に伝えやすくするための指定です。小さなpopupでも、状態が変わる場所には入れておくと親切です。
popup.css で見た目を整える
次に、popup.css を作ります。
body {
width: 320px;
margin: 0;
color: #1f2937;
background: #f8fafc;
font-family: system-ui, sans-serif;
}
.popup {
padding: 18px;
}
.label {
margin: 0 0 6px;
color: #2563eb;
font-size: 12px;
font-weight: 700;
}
h1 {
margin: 0 0 10px;
font-size: 20px;
line-height: 1.3;
}
.description {
margin: 0 0 16px;
color: #4b5563;
font-size: 13px;
line-height: 1.6;
}
.status-box {
margin-bottom: 14px;
padding: 12px;
border: 1px solid #dbeafe;
border-radius: 8px;
background: #eff6ff;
}
.status-label {
display: block;
margin-bottom: 4px;
color: #1d4ed8;
font-size: 12px;
}
#status-text {
font-size: 15px;
}
button {
width: 100%;
border: 0;
border-radius: 8px;
padding: 10px 12px;
color: #ffffff;
background: #2563eb;
font-weight: 700;
cursor: pointer;
}
button:hover {
background: #1d4ed8;
}popupでは、横幅を指定しておくと表示が安定します。
ここでは body に width: 320px; を指定しています。Chrome拡張機能のpopupは、通常のWebページのように画面いっぱいに広がるものではありません。小さなパネルとして使いやすい幅にしておきます。
また、ボタンは幅いっぱいにしています。popupでは細かい操作よりも、迷わず押せる大きさのほうが使いやすくなります。
popup.js でボタン操作と状態表示を作る
最後に、popup.js を作ります。
const statusText = document.getElementById("status-text");
const runButton = document.getElementById("run-button");
runButton.addEventListener("click", () => {
statusText.textContent = "処理を実行しました";
});処理はとても短いです。
まず、document.getElementById() でHTMLの要素を取得します。
次に、addEventListener("click", ...) でボタンが押されたときの処理を書きます。
ボタンが押されたら、statusText.textContent を書き換えます。
これで、popup内の表示が「待機中」から「処理を実行しました」に変わります。

Chromeで動作確認する
ファイルを作ったら、Chromeで読み込みます。
手順は前回と同じです。
- Chromeで
chrome://extensionsを開く - デベロッパーモードをオンにする
- 「パッケージ化されていない拡張機能を読み込む」を押す
popup-sample-extensionフォルダを選ぶ- ツールバーの拡張機能アイコンからpopupを開く
popupが開いたら、「処理を実行する」ボタンを押します。
状態表示が「処理を実行しました」に変われば成功です。
ファイルを変更したのに画面が変わらない場合は、拡張機能管理画面で対象の拡張機能を再読み込みします。popupは開き直すだけでは古い内容が残ることがあります。
popup作成時の注意点
popupはHTML、CSS、JavaScriptで作れますが、通常のWebページと少し違う注意点があります。
画面を大きくしすぎない
popupは一時的に開く小さな画面です。
横幅や高さを大きくしすぎると、ブラウザ上で扱いにくくなります。
設定項目が多い場合は、popupにすべてを詰め込むのではなく、設定ページや管理画面に分けることを考えます。
インラインJavaScriptを書かない
Chrome拡張機能では、セキュリティ上の理由から、インラインJavaScriptを避けるのが基本です。
たとえば、HTMLに次のような書き方をするのは避けます。
<button onclick="runTask()">実行</button>代わりに、この記事のように popup.js を読み込み、JavaScript側で addEventListener() を使います。
runButton.addEventListener("click", () => {
statusText.textContent = "処理を実行しました";
});HTMLは構造、CSSは見た目、JavaScriptは動き、と分けておくと、エラーも追いやすくなります。
必要な権限だけを追加する
今回のサンプルは、popup内の表示を書き換えるだけです。
そのため、permissions は不要です。
現在開いているタブの情報を取得したり、Webページの中身を操作したり、データを保存したりする場合は、目的に応じて権限やAPIが必要になります。
権限については、後続の記事で扱います。まずは、権限なしで作れる範囲を理解しておくと、あとで必要な権限を判断しやすくなります。
外部通信は失敗する前提で考える
今回の記事では外部通信を扱いません。
ただし、実際の拡張機能では、APIから情報を取得したり、サーバーへ送信したりすることがあります。
その場合は、通信が失敗することを前提に、エラーメッセージや再試行の方針を考える必要があります。
popupは小さな画面なので、失敗したときに何も表示しないと、ユーザーは何が起きたのか分かりません。
今回のpopupで分かること
今回作ったpopupは小さなサンプルですが、Chrome拡張機能の画面作りの基本が入っています。
action.default_popupでpopup画面を指定するpopup.htmlで画面構造を作るpopup.cssで見た目を整えるpopup.jsでボタン操作に反応する- 権限が不要な処理から始める
この形をベースにすれば、ボタンを増やしたり、設定項目を追加したり、保存処理につなげたりできます。
ただし、popupだけでできることには限りがあります。
開いているWebページの内容を読んだり、ページ上にボタンを追加したりするには、content script が必要になります。
まとめ
この記事では、Chrome拡張機能のpopup画面を、HTML、CSS、JavaScriptに分けて作りました。
popupは、拡張機能の利用者が最初に触れることの多い画面です。小さな画面だからこそ、役割を絞り、見やすく、押しやすく作ることが大切です。
今回のサンプルでは、特別な権限を使わず、popup内のボタン操作と状態表示だけを扱いました。
次回は、content script を使って、開いているWebページ側に処理を追加する方法を扱います。popupが「操作画面」だとすれば、content script は「ページの中で動く処理」です。この2つを理解すると、Chrome拡張機能で作れるものの幅が一気に広がります。




Your Message