data-count
Live character or word count for textareas with configurable limits. Color shifts at warning and error thresholds for visual feedback.
Overview
The data-count attribute adds a live counter below a textarea that updates as the user types. It supports both character counting (with maxlength) and word counting (with data-maxwords), with automatic color shifts at warning and error thresholds.
How It Works
Add data-count to any <textarea>. The init script:
- Creates an
<output>element withclass="textarea-counter" - Sets
aria-live="polite"andaria-atomic="true"on the counter for screen reader announcements - Places the counter after the textarea (inside
<form-field>if present, otherwise directly after) - Listens for
inputevents to update the count in real time - Calculates thresholds: warning at ≥80% of limit, error at ≥100%
- Sets
counter.dataset.stateto"","warning", or"error"for CSS styling - Sets
data-count-initto prevent double-binding
Attributes
| Attribute | Values | Description |
|---|---|---|
data-count |
"", "words" |
Enables the counter. Empty string (default) counts characters. "words" counts words. |
maxlength |
number | Standard HTML attribute. Used as the character limit. The counter displays current / max format. |
data-maxwords |
number | Word limit for word-count mode. The counter displays current / max format. |
data-count-init |
boolean | Set automatically to prevent double-binding. Do not set manually. |
Character Count
The default mode counts characters. Pair with maxlength to show a current / max display and enforce the limit.
Word Count
Set data-count="words" for word counting. Use data-maxwords to set a word limit. Words are split on whitespace.
Count Without Limit
Omit maxlength or data-maxwords to show a running count without enforcing a limit. No threshold states are applied.
Characters without limit
Words without limit
Display Format
The counter text adapts based on the configuration:
| Configuration | Display | Example |
|---|---|---|
Characters with maxlength |
current / max |
42 / 200 |
| Characters without limit | count character(s) |
42 characters |
Words with data-maxwords |
current / max |
12 / 50 |
| Words without limit | count word(s) |
12 words |
Threshold States
When a limit is set, the counter shifts color at configurable thresholds via data-state:
- Normal (
data-state="") — below 80% of the limit, uses muted text color - Warning (
data-state="warning") — at or above 80% of the limit, shifts to warning color - Error (
data-state="error") — at or above 100% of the limit, shifts to danger color with bold weight
Without a limit, no threshold states are applied and the counter stays in its default style.
Combined with data-grow
Use data-count alongside data-grow for a textarea that expands as the user types while showing the count.
Programmatic Access
The counter element is a standard DOM node. Query it to read the current state programmatically.
Styling
The counter is an <output> element styled via the .textarea-counter class. Threshold states are driven by data-state attribute selectors.
The warning state uses --color-warning and the error state uses --color-danger with increased font weight for emphasis.
Dynamic Elements
Textareas added to the DOM after page load are automatically enhanced via a MutationObserver. No manual initialization is needed.
Accessibility
- The counter uses
aria-live="polite"so screen readers announce count changes without interrupting the user aria-atomic="true"ensures the entire counter text is read, not just the changed portion- The
<output>element has implicit ARIA semantics for live regions - Threshold state changes (warning, error) are conveyed through the updated counter text
- The counter is placed after the textarea in DOM order, matching visual reading order
- Without JavaScript, the textarea works normally with no counter (progressive enhancement)