HTML
この記事では、フォームの入力値やJavaScriptで計算した結果を表示する<output>要素の役割と、入力欄との関係を初心者向けに説明します。
An element for dynamically displaying form inputs and calculation results on the page.
output 要素
<output> 要素は、フォームの入力値や JavaScript で算出した値をそのまま文書の一部として描画できる唯一のネイティブ HTML 要素です。DOM の差し替えによる再描画を行わずに「結果を表示する枠」を簡単に用意できるため、リアルタイムな値の変化をスムーズに見せられます。さらに、この要素は「ここは演算結果を示す場所です」というセマンティクス(意味づけ)をブラウザーや支援技術へ伝える役割を持ちます。同じ見た目を <div> や <span> でも実現できますが、こうした意味づけは得られません。
また、name 属性を付与すれば 他のフォーム部品と同様に送信データとして扱われ、form 属性を使えば フォームの外側に配置しても特定のフォームと関連付けられます。加えて、aria-live="polite" や role="status" と組み合わせることで、値が変化した際にスクリーンリーダーが自動的に更新内容を読み上げるようになり、アクセシビリティも向上します。
基本のマークアップ
HTML
<form oninput="total.value = Number(a.value) + Number(b.value)">
<label for="a">1つ目の数:</label>
<input type="number" id="a" name="a" value="1">
+
<label for="b">2つ目の数:</label>
<input type="number" id="b" name="b" value="2">
=
<output name="total" for="a b" role="status" aria-live="polite" aria-atomic="true"></output>
</form>
CSS
input[type="number"] {
width: 4em;
}
name属性- フォーム送信時に
sum=値がペイロードに含まれる。無指定なら送信されません。 for属性- 計算に関与する要素 ID を空白区切りで列挙し、論理的関連を明示。
form属性- 要素がフォーム外にあっても関連付けられる。
oninput により入力が変わるたび合計が即時反映されます。<output> 自体はフォーム部品ではないため、フォーカスを移してもキーボード入力は受け付けません。
属性・プロパティ詳細
for- 結果に影響を与える 入力要素の ID 群 を指定。
- JavaScript からは
output.htmlFor(DOMTokenList)として取得・操作可能。 name- 送信名 兼
form.elementsキー。 - 一意である必要はないが重複すると RadioNodeList になる点に注意。
form- フォーム外配置時に 関連フォームの
idを指定。Shadow DOM 内でも有効。 value/defaultValueプロパティvalueは 現在表示している値、defaultValueは リセット時に戻る既定値。formのreset()実行や<input type="reset">クリックでvalueがdefaultValueに戻る。
JavaScript での操作
双方向バインディング
JavaScript
const output = document.querySelector('output[name="total"]');
output.value = 42; // 表示も同期
console.log(output.value); // "42"
.value プロパティは 自動で textContent と同期 するため、innerText を直接書き換えるより可読性が高く、フォーム送信にも正しく反映されます。
イベント連動
JavaScript
const out = document.querySelector('#status');
navigator.onLine
? (out.value = 'オンライン')
: (out.value = 'オフライン');
window.addEventListener('online', () => (out.value = 'オンライン'));
window.addEventListener('offline', () => (out.value = 'オフライン'));
状態表示パネルとして使えば、視覚的な「LED 表示」のように扱えます。
Constraint Validation API
output.setCustomValidity('エラー')→checkValidity() で動的計算結果も検証対象に。
その他
MutationObserver で for 対象の変更に追従。
CustomEvent と併用して再利用可能な計算コンポーネント化。
CSS と視覚的ヒント
CSS
output {
display: inline-block;
min-width: 3rem;
padding: .25em .5em;
border: 1px solid #ccc;
border-radius: .25rem;
text-align: right;
font-variant-numeric: tabular-nums;
}
CSS で display: inline-block を指定すると、幅や余白を調整しやすくなります。font-variant-numeric: tabular-nums を使うと、数字が等幅フォントで揃い、計算結果が見やすくなります。
エラー時 :invalid { color: red; } で視覚フィードバック。
アクセシビリティ
HTML
<output id="total" aria-live="polite" role="status"></output>
- ARIA ロールは既定で
statusに近い - 支援技術は動的テキストとして読み上げる。必要に応じ
role="status" aria-live="polite"を明示すると確実。 - ラベル付け
<label for="total">合計</label>を併用するとスクリーンリーダー利用者に意味が伝わりやすい。
ブラウザーサポートと制約
モダンブラウザー全般でフルサポート(Firefox4+, Safari7+, Chrome10+, Edge79+, Mobile 含む)。IE は未対応。
Safari 旧版(≤6)では value 反映が遅延するバグがあったが、2023 年に修正済み。
送信仕様は URL エンコード フォーマットに準拠。type="hidden" の代用可。
上級者向け活用アイデア
- Web Components
<calc-sum>内部で<output>を使い、外部属性変更で Shadow DOM 内値を更新。- Service Worker + Streams
- 長時間処理結果をストリームで受け取り、途中経過を
<output>にパイプしてプログレスバーと同期。 - Reactive Framework との統合
-
- Vue 3
<output :value="total" />(v-model ではなく props 経由で一方向データフローを保つ)- React
<output ref={ref => ref && (ref.value = total)} />で uncontrolled 的に扱うとフォーム送信が容易。
- セキュリティ
- 外部入力を
output.innerHTMLに入れるのは XSS リスク。valueかtextContentを使う。Trusted Types を導入するとさらに安全。
よくある落とし穴
- innerText だけ書き換えて value を更新し忘れ
- → フォーム送信値が空になる。必ず
valueプロパティも変更。 - for 属性に存在しない ID
- → 仕様上は無視されるが支援技術連携が失われるため、DOM 操作で生成する場合は要注意。
まとめ
<output> は「ただ表示するだけ」の要素に見えて、フォーム送信・バリデーション・アクセシビリティといった フォーム API の恩恵をフルに受けられる稀有な結果表示要素 です。
基本構文を押さえつつ、JavaScript で value を制御し、for や name を活用すれば、インタラクティブでセマンティックかつアクセシブルな UI を手軽に構築できます。