Text areas
tier 2 — classes
The same .form-input, on a <textarea>. rows sets the
starting height and the class does the rest; the one thing worth deciding is which way the reader
may drag it.
The text area
Label, control, hint, exactly as a single-line field.
Recorded against your name and shown to the warehouse.
<div style="max-width:460px">
<div class="form-field">
<label class="form-label" for="ta-reason">Reason for the override</label>
<textarea class="form-input" id="ta-reason" rows="3"
placeholder="Why are you overriding the reservation?"></textarea>
<p class="form-hint">Recorded against your name and shown to the warehouse.</p>
</div>
</div>
Locking the resize
Vertical is the default, not a class. The browser ships
resize: both, and a text area dragged wider than its column breaks the row it is
in and every row below it — taller never breaks anything.
.form-input--resize-none and --resize-both are the two departures.
<div class="sedna-col" style="max-width:460px; gap:16px">
<div class="form-field">
<label class="form-label" for="rs-default">Default — vertical only</label>
<textarea class="form-input" id="rs-default" rows="2">Drag the corner: it grows taller, never wider.</textarea>
</div>
<div class="form-field">
<label class="form-label" for="rs-none">Locked</label>
<textarea class="form-input form-input--resize-none" id="rs-none" rows="2">No grip at all. For a cell or a toolbar where the height is the layout's decision.</textarea>
</div>
<div class="form-field">
<label class="form-label" for="rs-both">Both axes</label>
<textarea class="form-input form-input--resize-both" id="rs-both" rows="2">Free in both directions — only where nothing sits beside it.</textarea>
</div>
</div>
Inside a two-up grid
Why the default is the safe axis, with something beside it to break.
<div class="sedna-grid sedna-grid--sm sedna-grid--fit" style="max-width:620px">
<div class="form-field">
<label class="form-label" for="ig-order">Order</label>
<input class="form-input" id="ig-order" type="text" value="ORD-4182" />
</div>
<div class="form-field">
<label class="form-label" for="ig-customer">Customer</label>
<input class="form-input" id="ig-customer" type="text" value="Priya Nair" />
</div>
<div class="form-field sedna-span-full">
<label class="form-label" for="ig-note">Note</label>
<textarea class="form-input" id="ig-note" rows="3">Drag this corner. It cannot leave its column, so the two fields above stay where they are.</textarea>
</div>
</div>
With a character budget
maxlength stops the typing. The count itself is the app's to render — there
is no class for it, because where the number comes from is the app's state.
57 of 280 characters. maxlength stops the typing; the count is the app's to keep.
<div style="max-width:460px">
<div class="form-field">
<label class="form-label" for="ct-msg">Message to the customer</label>
<textarea class="form-input" id="ct-msg" rows="3" maxlength="280"
aria-describedby="ct-msg-hint">Your order is held until Tuesday while we wait on stock.</textarea>
<p class="form-hint" id="ct-msg-hint">57 of 280 characters. <code>maxlength</code> stops the typing; the count is the app's to keep.</p>
</div>
</div>
Rejected
aria-invalid and .form-error reach a text area unchanged — see
validation for the rule.
An override is recorded against your name, so it needs a reason.
<div style="max-width:460px">
<div class="form-field">
<label class="form-label form-label--required" for="iv-reason">Reason</label>
<textarea class="form-input" id="iv-reason" rows="3" required
aria-invalid="true" aria-describedby="iv-reason-err"></textarea>
<p class="form-error" id="iv-reason-err">
<i class="ri-error-warning-line"></i>
<span>An override is recorded against your name, so it needs a reason.</span>
</p>
</div>
</div>
Three sizes
The tier moves the type; rows moves the height. They are independent, so a small
text area can still be six rows tall.
<div class="sedna-col" style="max-width:460px; gap:16px">
<textarea class="form-input form-input-sm" rows="2" aria-label="Small text area">Small — 12px, for a note beside a small button.</textarea>
<textarea class="form-input" rows="2" aria-label="Default text area">Default — 13px, the same tier as an input.</textarea>
<textarea class="form-input form-input-lg" rows="2" aria-label="Large text area">Large — 14px. The tier moves the type; rows moves the height.</textarea>
</div>