Textarea
Multi-line text input with auto-resize and character count.
Default
Plain <textarea class="textarea"> — fixed rows, manual
resize handle left to the browser default. No JS involved.
<label class="sc-field">
<span class="sc-field-label">Message</span>
<textarea class="textarea sc-textarea" rows="4" placeholder="Write your message…"></textarea>
</label>
Auto-resize
Grows with its content instead of scrolling internally. The height
reset-then-measure happens on every keystroke via a plain Alpine
x-on:input expression — short enough that it doesn't need
a named function in the JS file.
<textarea
class="textarea sc-textarea sc-textarea--auto"
rows="2"
x-data
x-on:input="$el.style.height = 'auto'; $el.style.height = $el.scrollHeight + 'px'"
></textarea>
Character / word count
A live counter below the field, with a max length and a colour change as the limit approaches — handled entirely with Alpine state, no DaisyUI equivalent needed.
/ characters
<div x-data="{ value: '', max: 160 }">
<textarea class="textarea sc-textarea" :class="{ 'textarea-error': value.length > max }"
x-model="value" :maxlength="max"></textarea>
<p class="sc-textarea-counter"><span x-text="value.length"></span> / <span x-text="max"></span></p>
</div>
Floating label
Label sits inside the field until focused or filled, then floats above
the border. Pure CSS via Tailwind's peer/peer-focus
variants — DaisyUI's floating-label class targets single-line inputs only.
Min / max rows (clamped auto-resize)
Same auto-resize behaviour, clamped between 3 and 8 visible rows via
min-height / max-height — beyond the max it scrolls
internally instead of pushing the rest of the page down.
States
Default, disabled, error, and empty.
Default
Disabled
Error
Minimum 10 characters required.
Empty