フォームで入力された数値を掛け算して合計を表示したり、スライダーの現在値をその場に映したり。こうした「計算結果」や「操作の結果」を表すために HTML には <output> という専用の要素が用意されています。<span> や <div> でも見た目は作れますが、<output> を使うと意味が明確になり、スクリーンリーダーが値の変化を読み上げてくれるという利点もあります。この記事では基本の書き方から for 属性、スライダーとの組み合わせ、JavaScript からの更新、アクセシビリティ上の挙動まで順を追って解説します。
目次
div ではなく output を使う理由
計算結果を画面に出すだけなら、<div> や <span> の中身を書き換えても実現できます。それでも <output> が用意されているのは、この要素が「ユーザーの操作や計算の結果を表す」という意味を持っているからです。
意味づけ(セマンティクス)がはっきりすると、機械にとって読みやすいマークアップになります。特に大きいのが支援技術との相性です。<output> は初期状態で role="status" を持ち、ライブリージョン(aria-live="polite" 相当)として扱われます。つまり中身が変わると、スクリーンリーダーが操作を邪魔しないタイミングで新しい値を読み上げてくれます。<div> で同じことをするには自分で aria-live を付ける必要がありますが、<output> なら最初からその役割を備えているわけです。
基本の書き方
<output> は開始タグと終了タグを持つ通常の要素で、間に結果として表示したいテキストを書きます。次のように置くだけで使えます。
<output>0</output>
これだけでは <span> と変わらないように見えますが、JavaScript から値を差し込む先として使ったり、次に説明する for 属性で入力欄との関係を示したりすることで真価を発揮します。なお中身の読み書きには、後述するとおり value プロパティと textContent のどちらも使えます。
for・name・form の3つの属性
<output> には結果としての性格を補足するための属性がいくつかあります。よく使う3つを整理します。
| 属性 | 役割 |
|---|---|
for | この結果がどの入力要素と関係しているかを、対象の id を空白区切りで並べて示す(例: for="price qty") |
name | フォーム部品としての名前。同じフォーム内から form.elements や要素名で参照するときに使う |
form | 要素が <form> の外側にある場合に、所属させたいフォームの id を指定して結びつける |
for 属性は見た目には影響せず、あくまで「この出力はこれらの入力から算出されたものだ」という関連付けを表す情報です。<label> の for が1つの id を指すのと違い、<output> の for は複数の id を空白で区切って並べられる点に注意してください。
スライダーと組み合わせて自動計算する
もっとも手軽な使い方が、<form> の oninput 属性と組み合わせる方法です。oninput はフォーム内のいずれかの入力が変わるたびに実行されるので、そこで結果を計算して <output> に代入すれば、JavaScript ファイルを別に用意しなくても自動計算が動きます。
まずは2つのスライダー(type="range")の値を足し合わせ、その合計を <output> に表示する例です。スライダーを動かすと、合計がリアルタイムに書き換わります。
<form oninput="sum.value = Number(a.value) + Number(b.value)">
<p>
<label>数量A:<input type="range" name="a" id="a" min="0" max="100" value="30"></label>
</p>
<p>
<label>数量B:<input type="range" name="b" id="b" min="0" max="100" value="20"></label>
</p>
<p class="result">
合計:<output name="sum" for="a b">50</output>
</p>
</form>
body {
font-family: sans-serif;
padding: 16px;
}
input[type="range"] {
width: 220px;
vertical-align: middle;
}
.result {
font-size: 1.4rem;
font-weight: bold;
}
.result output {
color: #e8590c;
}
ポイントは sum.value = ... の部分です。name="sum" を付けた <output> は、フォーム内では sum という名前でそのまま参照でき、value プロパティに代入すると表示が更新されます。a.value や b.value は文字列で返るため、Number() で数値に変換してから足している点にも注目してください。文字列のまま + を使うと連結されてしまいます。
次は数量入力の実務でよくある「単価 × 個数」の計算です。type="number" の入力を2つ用意し、掛け算した合計金額を <output> に表示します。
<form oninput="total.value = Number(price.value) * Number(qty.value)">
<p>
<label>単価
<input type="number" name="price" id="price" value="500" min="0">
</label>
円
</p>
<p>
<label>個数
<input type="number" name="qty" id="qty" value="3" min="0">
</label>
個
</p>
<p class="result">
合計:<output name="total" for="price qty">1500</output> 円
</p>
</form>
body {
font-family: sans-serif;
padding: 16px;
}
input[type="number"] {
width: 80px;
padding: 4px 6px;
}
.result {
font-size: 1.2rem;
font-weight: bold;
}
.result output {
color: #007bff;
}
ここでも for="price qty" のように、関係する入力の id を空白区切りで指定しています。この記述は計算を動かすためではなく、あくまで意味づけのためのものですが、書いておくと後からコードを読む人にも支援技術にも関係性が伝わります。
JavaScript から値を書き換える
属性の oninput ではなく、外部の JavaScript から <output> を操作したい場面も多いはずです。要素を取得したあと、値を差し込む方法は大きく2つあります。
const output = document.querySelector('#total');
// 方法1: value プロパティに代入する(output 要素固有のプロパティ)
output.value = 1500;
// 方法2: textContent で中身のテキストを書き換える
output.textContent = '1500';
どちらも画面上の表示は更新されます。value は <output> が持つ専用のプロパティで、代入すると内部のテキストが差し替わります。textContent は要素共通のプロパティで、こちらでも同じように書き換えられます。表示だけを目的にするなら、意味が明快な value を使うのがおすすめです。
なお value に数値を渡しても、内部では文字列として扱われます。読み取り側でも output.value は必ず文字列で返ってくるため、再計算に使う場合は Number() などで変換してから扱ってください。
読み上げが二重になる・意図せず読まれるとき
<output> はライブリージョンとして働くため、便利な反面ちょっとした注意点もあります。
入力のたびに読み上げられて煩わしい
<output> の中身が変わるたびにスクリーンリーダーは新しい値を読み上げます。スライダーのように連続して値が変わる入力と組み合わせると、そのたびに読み上げが走ります。aria-live="polite" 相当なので操作を中断するほどではありませんが、頻繁な更新が邪魔になる場合は、更新の頻度を抑えるか、途中経過ではなく確定した結果だけを <output> に反映する設計を検討してください。
合計が文字列として連結されてしまう
「50 + 20」が「70」ではなく「5020」になるのは、入力値が文字列のまま + で結合された典型的なミスです。<input> の value は数値入力でも文字列で返るため、足し算をするときは Number(a.value) + Number(b.value) のように数値へ変換します。掛け算や引き算では文字列が自動的に数値化されるため気づきにくいですが、足し算だけは明示的な変換が欠かせません。
フォームの外にある output が更新できない
oninput を使った sum.value = ... のような短い書き方は、<output> が同じ <form> の中にあることが前提です。レイアウトの都合でフォームの外に置く場合は、<output> に form 属性で所属先フォームの id を指定するか、JavaScript で document.querySelector() から要素を取得して直接操作するようにしてください。
まとめ
<output> は、計算や操作の「結果」を表すための専用要素です。<div> でも見た目は再現できますが、<output> なら意味が明確になり、role=”status” のライブリージョンとして値の変化が読み上げられる利点があります。for 属性は関係する入力の id を空白区切りで並べて関連を示し、name でフォーム内から参照でき、form 属性で外側からフォームに結びつけられます。<form> の oninput と組み合わせれば JavaScript ファイルなしで自動計算が作れ、外部スクリプトからは value か textContent で表示を更新できます。足し算の際に Number() で数値へ変換することだけ忘れないようにすれば、フォームの結果表示がぐっと書きやすくなります。