Basic Input
A labelled text input with helper text wired to it via aria-describedby.
6 個のフレームワーク初級
A character counter that warns near the limit and announces only when it matters.
<!--
Two things worth stealing here:
1. aria-live="polite" on the counter, NOT on every keystroke. A live region
that fires per character is a machine gun. It only speaks inside the last
20 characters - the point where the number stops being trivia and starts
being a warning.
2. The counter is inside aria-describedby, so a screen reader user is told the
limit exists when they ENTER the field, not when they hit it.
-->
<div class="count-field">
<label class="count-field__label" for="count-field-bio">Short bio</label>
<textarea
class="count-field__input"
id="count-field-bio"
name="bio"
rows="4"
maxlength="180"
placeholder="Tell us what you work on."
aria-describedby="count-field-bio-count"
></textarea>
<p class="count-field__count" id="count-field-bio-count" aria-live="polite">
<span class="count-field__used">0</span> of 180 characters used
</p>
</div>
<script>
document.querySelectorAll('.count-field').forEach(function (root) {
var input = root.querySelector('.count-field__input');
var readout = root.querySelector('.count-field__count');
var used = root.querySelector('.count-field__used');
var max = Number(input.getAttribute('maxlength'));
var WARN_AT = 20;
function sync() {
var length = input.value.length;
used.textContent = String(length);
var remaining = max - length;
root.classList.toggle('count-field--warn', remaining <= WARN_AT);
// Silent until the number matters, then polite. Never assertive: this is
// information, not an interruption.
readout.setAttribute('aria-live', remaining <= WARN_AT ? 'polite' : 'off');
}
input.addEventListener('input', sync);
sync();
});
</script>| Prop | 型 | デフォルト | 説明 |
|---|---|---|---|
label必須 | string | - | 読み込み中に読み上げられるアクセシブルなラベル。 |
value必須 | string | - | 指標の現在値。フォーマット済みの文字列を渡します。 |
count | number | - | バッジに表示される数値。99 を超えると「99+」と表示されます。 |
disabled | boolean | false | 操作を無効にし、コントロールを淡色表示にします。 |
Two things worth stealing. First, `aria-live` is `off` until the last 20 characters and only then becomes `polite` - a live region that fires on every keystroke is a machine gun, and this is information, never an interruption, so never `assertive`. Second, the counter sits inside `aria-describedby`, so a screen reader user is told the limit exists when they *enter* the field rather than discovering it by hitting it. The warning changes colour *and* weight, because colour alone is no signal for a red-blind user. `tabular-nums` stops the readout jittering as digits change. The amber inverts in dark mode - `amber-700` is 2.6:1 on `gray-900` and would vanish.