Web Programming

A simple practice button where pressing + makes the number go up, pressing − makes it go down, and if it goes below zero it turns red so it’s easy to notice.

カウントアップ・ダウンボタン

+ボタンを押すと数字が増えて、−ボタンを押すと数字が減り、もしマイナスになったら赤色でわかりやすく表示されるシンプルな練習用ボタンです。

学ぶこと:状態(数値)の保持テキスト更新
最小要件:/で数値が変化、0未満は赤表示

0

HTML

<div class="counter" role="group" aria-label="カウンター">
	<button id="decrement" type="button" aria-label="1 減らす">−</button>
	<!-- aria-live=\"polite\" で画面リーダーにも数値変化を伝える -->
	<span id="display" class="display" aria-live="polite">0</span>
	<button id="increment" type="button" aria-label="1 増やす">+</button>
</div>

CSS

.counter {
	display: inline-flex;
	align-items: center;
	gap: 1rem;
	border: 1px solid #ccc;
	border-radius: 8px;
	padding: 1rem;
}
.display {
	min-width: 4ch;           /* 2桁以上でも崩れにくい */
	text-align: right;
	font-variant-numeric: tabular-nums; /* 桁揃え */
	font-size: 2rem;
}
.negative { color: #c0392b; } /* 0未満は赤表示 */

button {
	font-size: 1.2rem;
	padding: .5rem .9rem;
	border-radius: 6px;
	border: 1px solid #aaa;
	background: #f5f5f5;
	cursor: pointer;
}
button:active { transform: translateY(1px); }

JavaScript

// 1) 状態(アプリの今の値)を用意する
let count = 0; // 初期値

// 2) 画面(DOM)から必要な要素を取得
const displayEl = document.getElementById('display');
const incBtn = document.getElementById('increment');
const decBtn = document.getElementById('decrement');

// 3) 状態 → 画面へ反映する関数(レンダー関数)
function render() {
	displayEl.textContent = count;                 // 数字を表示
	displayEl.classList.toggle('negative', count < 0); // 0未満なら赤
}

// 初期描画
render();

// 4) ボタンクリックで状態を更新 → 画面を再描画
incBtn.addEventListener('click', () => {
	count = count + 1; // 状態を更新
	render();          // 画面へ反映
});

decBtn.addEventListener('click', () => {
	count = count - 1; // 状態を更新
	render();          // 画面へ反映
});

// 学習ポイント:
// ・状態(count)は必ずrender()を通してDOMに反映する(見通しが良くなる)
// ・色の切替はclass付け替えに任せ、見た目の定義はCSSに分離する

コードの解説

このサンプルは「状態(count)という数字を1つだけ持ち、その数字を 画面に映すボタンで変えるという最小構成」です。 学ぶポイントは「状態を1か所で管理し、画面更新のやり方を1本にまとめる」ことです。

1. HTML(見た目の部品を置く)

<button id="decrement">−</button><button id="increment">+</button>
2つのボタンが「数を減らす/増やす」役目です。
<span id="display">0</span>
ここに現在の数を表示します。aria-live="polite" を付けると画面リーダーが変化を読み上げやすくなります。

全体を包む <div class="counter"> は、ボタンと表示を横並びに整える箱です(CSSで見た目を調整)。

2. CSS(見た目の調整)

.counter { display: inline-flex; gap: 1rem; ... }
ボタンと数字を横並び・等間隔にします。
.display { font-variant-numeric: tabular-nums; text-align: right; }
桁が揃い、右寄せで読みやすくなります。
.negative { color: #c0392b; }
数が0未満のときだけ付けるクラス。色の切替はCSSに任せ、JSは「付け外し」だけ担当します。

3. JavaScript(仕組みの心臓部)

状態を用意する
let count = 0; が「今の数字」の唯一の元データ(単一の真実)です。
表示用の関数を1本作る
render()count を画面へ映します。
具体的には displayEl.textContent = count; と、displayEl.classList.toggle('negative', count < 0); の2つだけ。 条件(0未満)を満たすときだけ negative クラスが付き、色が赤になります。
イベントで状態を変える
ボタンは count = count + 1; ボタンは count = count - 1; とし、必ず最後に render() を呼んで画面を最新状態にします。

4. 大事な考え方(設計のコツ)

「状態 → 画面」一方向に流す
画面(DOM)の数字を直接いじり回さず、count を変えて render() で映す、という順番を徹底すると大きくなっても迷子になりません。
見た目はCSSに、条件はJSに
JSは「いつ赤くするか」だけ決め、実際の色や太さなどはCSSに任せます(役割分担)。
「1箇所に集める」習慣
表示を変える処理を render() に一本化しておけば、UIを増やす(リセットボタンやキーボード操作)ときも最後に render() だけ呼べばOK になります。

5. ありがちなつまずき

文字列と数値の混同
count = count + 1 は数値の足し算ですが、DOMから文字列を読んで足すと「連結」になりやすいです。このサンプルでは状態をJS変数だけで管理しているので安全です。
render() を呼び忘れる
変数は増減しているのに画面が変わらない…というときは、render() の呼び出しを確認しましょう。
innerHTML の使いすぎ
文字列でごっそり入れ替えるより、textContentclassList.toggle() を使うと安全・明快です。

6. 発展アイデア

リセットボタン
count = 0; render(); を呼ぶだけで実装できます。
保存(永続化)
変更のたびに localStorage.setItem('count', String(count));
初期化時は count = Number(localStorage.getItem('count') ?? 0); で読み込み。
キーボード操作
ArrowUp で+、ArrowDown で− などを keydown イベントで追加可能。
下限/上限・ステップ幅
例:Math.max(min, Math.min(max, count + step)) の形で制御。
アクセシビリティ
ボタンに aria-label を付け、表示には aria-live を用意済み。フォーカス移動やキーボード操作も加えるとより親切です。

まとめると、「状態を決める → 画面に映す関数を1つにまとめる → 操作で状態を変えたら毎回その関数を呼ぶ」の3点が基本です。 この型を覚えると、もっと複雑なUIでもスムーズに組み立てられるようになります。