A .field is the container. The
<label> after the control is the floating
label. An icon names its side with prefix or
suffix and is aria-hidden.
<small> is supporting text. The default is
the M3 filled field; add outlined for the outlined
variant.
Tokens follow the
M3 text field spec.
Height is 56dp. Filled is a surface-variant well with
4dp top corners and a 1dp / 2dp bottom indicator. Outlined is a
1dp / 2dp outline at 4dp. The label is
body-large at rest and body-small floated.
Input text is body-large / on-surface.
Icons are 24dp, 12dp from the edge.
Add placeholder=" " (one space) so the label floats
with CSS only. A missing placeholder, or any other string, keeps
the label floated. Importing the bundle runs
Forms.Init(); it validates .validate
fields on change and starts textareas and file paths.
Character Counter is not in AutoInit().
<div class="field">
<input id="first_name" type="text" placeholder=" " aria-describedby="first_name_help">
<label for="first_name">First name</label>
<small id="first_name_help">Supporting text</small>
</div>
<div class="field outlined">
<input id="last_name" type="text" placeholder=" ">
<label for="last_name">Last name</label>
</div>
<div class="field">
<span class="material-symbols prefix" aria-hidden="true">place</span>
<span class="material-symbols suffix" aria-hidden="true">gps_fixed</span>
<input id="loc" type="text" placeholder=" ">
<label for="loc">Location</label>
</div>
Put invalid or aria-invalid="true" on the
input for the error state. Do not put error on the
wrapper — that class is a color utility and fills the field.
.supporting-text and .prefix /
.suffix remain as aliases.
Input types
email, password, and the other native
text-like types are styled the same way. validate
uses HTML5 constraint validation on change and
toggles invalid on the input. There is no green
valid style.
<div class="field">
<input id="email" type="email" class="validate" placeholder=" " aria-describedby="email_help">
<label for="email">Email</label>
<small id="email_help" data-error="Enter a valid email">Supporting text</small>
</div>
validate also honors data-length: the
field is marked invalid when the value is longer than
that number. Prefer maxlength when you want the
browser to cap input.
Inline
Add inline to sit the field in a line of text.
This is an inline input field:
<span class="field inline">
<input id="email_inline" type="email" class="validate" placeholder=" ">
<label for="email_inline">Email</label>
</span>
Textarea
Use textarea.expressive-textarea inside
.field. That class name is Expressive’s; there is no
.materialize-textarea. Textareas grow with their
content. Forms.Init() starts every
.expressive-textarea on DOMContentLoaded.
<div class="field">
<textarea id="textarea1" class="expressive-textarea" placeholder=" "></textarea>
<label for="textarea1">Textarea</label>
</div>
If you add a textarea after load, initialize it yourself:
Expressive.Forms.InitTextarea(document.querySelector('#textarea1'));
Setting .value in script does not resize the field.
Call textareaAutoResize afterwards.
File input
A .file-field.field pairs a button with a path field.
Forms.Init() copies the chosen file name into
input.file-path.
<div class="file-field field">
<label class="button">
File
<input type="file">
</label>
<div class="file-path-wrapper">
<input class="file-path" type="text" placeholder=" " readonly aria-label="Selected file">
</div>
</div>
Add multiple to allow more than one file.
Character counter
Character Counter is not in AutoInit(). It reads
maxlength (not data-length) and writes
current/max into a .character-counter
span. Overflow adds invalid on the field.
Expressive.CharacterCounter.init(
document.querySelectorAll('#input_text, #textarea2')
);