Input
Form element that allows users to input and edit text or data into a website page.
| Class name | Type | |
|---|---|---|
.prs-input |
Component | For <input> or <label> |
.prs-input-ghost |
Modifier | Remove border |
.prs-input_focus |
State | Manually apply visual focus |
.prs-input_invalid |
State | Manually apply visual invalid |
.prs-input_disabled |
State | Manually apply visual disabled |
-
<label><input type="text" class="prs-input" placeholder="Placeholder" aria-label="Text" /></label> -
<label><textarea class="prs-input" placeholder="Placeholder" aria-label="Textarea"></textarea></label> -
<label> <select class="prs-input" aria-label="Select"> <option selected disabled>Choose:</option> <option>1</option> <option>2</option> <option>3</option> </select> </label> -
<label class="prs-form-control"> <div class="prs-label"> <span class="prs-label-text">Upload image</span> </div> <input type="file" class="prs-input" accept="image/*" /> </label> -
Container
The markup is strict.
.prs-label-textmust be a direct child of.prs-input.<label class="prs-form-control"> <div class-"prs-label"> <span class="prs-label-text">Email:</span> </div> <span class="prs-input"> <input type="text" size="8" placeholder="user" /> <span class="prs-label-text">@</span> <input type="text" size="12" placeholder="domain.ext" /> </span> </label> <label class="prs-form-control"> <div class-"prs-label"> <span class="prs-label-text">Price:</span> </div> <span class="prs-input"> <span class="prs-label-text">$</span> <input type="number" min="0" max="999" step="1" pattern="[0-9]{1,3}" oninput="if(parseInt(this.value)>999){ this.value = 999; return false; }" placeholder="123" /> <span class="prs-label-text">.00</span> </span> </label> <label class="prs-form-control"> <div class-"prs-label"> <span class="prs-label-text">Select:</span> </div> <span class="prs-input"> <span class="prs-label-text"> <!-- use <svg>, <iconify-icon>, or .icon --> <svg xmlns="http://www.w3.org/2000/svg" width="1em" height="1em" fill="currentColor" role="img" aria-label="Some label"> <use href="/_assets/prs-icons.svg#nav-level-down" /> </svg> </span> <select> <option selected disabled>Choose:</option> <option>1</option> <option>2</option> <option>3</option> </select> </span> </label> -
Ghost
Borderless variant.
<div class="w-96 max-w-xs space-y-5 [&>:where(label:not(.prs-form-control))]:(w-full block)"> <!-- <- this is just for demo purposes --> <label><input type="text" class="prs-input prs-input-ghost" placeholder="Text" aria-label="Text" /></label> <label><textarea class="prs-input prs-input-ghost" placeholder="Textarea" aria-label="Textarea"></textarea></label> <label><select class="prs-input prs-input-ghost" aria-label="Select"><option selected disabled>Select</option></select></label> <label><input type="file" class="prs-input prs-input-ghost" aria-label="File" /></label> </div> -
<div class="w-96 max-w-xs space-y-5 [&>:where(label:not(.prs-form-control))]:(w-full block)"> <!-- <- this is just for demo purposes --> <label><input type="email" class="prs-input" placeholder="Email" aria-label="Email" /></label> <label><input type="password" class="prs-input" placeholder="Password" aria-label="Password" /></label> <label><input type="search" class="prs-input" placeholder="Search" aria-label="Search" /></label> <label><input type="number" class="prs-input" placeholder="Number" aria-label="Number" /></label> <label><input type="tel" class="prs-input" placeholder="Phone number" aria-label="Phone number" /></label> <div class="grid-(& cols-5) gap-5"> <label><input type="color" class="prs-input" placeholder="Color" aria-label="Color" value="#383838" /></label> <label><input type="color" class="prs-input" placeholder="Color" aria-label="Color" value="#0600B4" /></label> <label><input type="color" class="prs-input" placeholder="Color" aria-label="Color" value="#E3B153" /></label> <label><input type="color" class="prs-input" placeholder="Color" aria-label="Color" value="#00F0A8" /></label> <label><input type="color" class="prs-input" placeholder="Color" aria-label="Color" value="#E0205D" /></label> </div> <label><input type="url" class="prs-input" placeholder="URL" aria-label="URL" /></label> <label><input type="date" class="prs-input" aria-label="Date" onfocus="this.showPicker()" /></label> <label><input type="datetime-local" class="prs-input" aria-label="Date and time" onfocus="this.showPicker()" /></label> <label><input type="month" class="prs-input" aria-label="Month and year" onfocus="this.showPicker()" /></label> <label><input type="week" class="prs-input" aria-label="Week of the year" onfocus="this.showPicker()" /></label> </div> -
<label><input type="text" class="prs-input prs-input_focus" placeholder="Placeholder" aria-label="Text" /></label> -
Invalid
.prs-label-erroris hidden by default unless the.form-controltag contains an invalid input. Pure CSS.<div class="w-96 max-w-xs space-y-5 [&>:where(label:not(.prs-form-control))]:(w-full block)"> <!-- <- this is just for demo purposes --> <!-- native html validation - remove text then click outside --> <label class="prs-form-control"> <span class="prs-label-text"><strong>Native:</strong> remove text then click outside</span> <input type="text" class="prs-input" placeholder="Placeholder" aria-label="Text" value="Value" onfocus="this.select()" required /> <span class="prs-label-text prs-label-error">Error message</span> </label> <!-- manually handle validation: - toggle .prs-input_invalid on <input/textarea/select> - your error message will still automatically show/hide --> <label class="prs-form-control"> <span class="prs-label-text"><strong>Forced:</strong> with class</span> <input type="text" class="prs-input prs-input_invalid" placeholder="Placeholder" aria-label="Text" onInput={handleInput} /> <span class="prs-label-text prs-label-error">Error message</span> </label> </div> -
<div class="w-96 max-w-xs space-y-5 [&>:where(label:not(.prs-form-control))]:(w-full block)"> <!-- <- this is just for demo purposes --> <label><input type="text" class="prs-input" aria-label="Text" disabled /></label> <label><input type="text" class="prs-input" placeholder="Placeholder" aria-label="Text" disabled /></label> <label><input type="text" class="prs-input" value="Value" placeholder="Placeholder" aria-label="Text" disabled /></label> <label><input type="file" class="prs-input" aria-label="File" disabled /></label> </div>
CSS
Full Library
Component Only
.prs-input {
appearance: none;
padding: 0.1875rem 1rem;
border: 1px solid var(--prs-c-gray);
width: 100%;
min-height: 2rem;
background: var(--prs-c-white);
color: var(--prs-c-gray-900);
text-align: left;
font-weight: var(--prs-fw-ui-md);
font-size: var(--prs-fz-ui-md);
line-height: var(--prs-fl-ui-md);
flex-shrink: 1;
display: block;
border-radius: var(--prs-radius-input);
transition-property: var(--prs-transition-property);
transition-timing-function: var(--prs-transition-timing);
transition-duration: var(--prs-transition-duration);
}
/* number */
.prs-input:where([type="number"]) {
padding-right: 0.1875rem;
}
/* color */
.prs-input:where([type="color"]) {
padding: 0 0.1875rem;
}
/* when used as a container */
.prs-input:where(:not(input)) {
display: flex;
align-items: center;
gap: 1rem;
}
.prs-input :where(input, select, textarea) {
appearance: none;
flex-grow: 1;
}
.prs-input :where(input, select, textarea):last-child,
.prs-input :where(input[type="number"]) {
margin-inline-end: -1rem;
}
.prs-input > .prs-label-text {
padding: 0;
color: var(--prs-c-gray-600);
line-height: normal;
white-space: nowrap;
flex-shrink: 0;
display: flex;
align-items: center;
justify-content: center;
user-select: none;
}
.prs-input > .prs-label-text:not(:first-child,:last-child) {
padding-inline: 1rem;
border-inline: 1px solid var(--prs-c-gray-300);
}
.prs-input > .prs-label-text + .prs-label-text:not(:first-child,:last-child) {
padding-inline: 0 1rem;
border-inline-start: 0 none;
}
.prs-input > .prs-label-text:first-child {
padding-inline-end: 1rem;
border-inline-end: 1px solid var(--prs-c-gray-300);
}
.prs-input > .prs-label-text:last-child {
padding-inline-start: 1rem;
border-inline-start: 1px solid var(--prs-c-gray-300);
}
.prs-input .prs-label-text svg,.prs-input .prs-label-text .icon,.prs-input .prs-label-text iconify-icon {
font-size: 1rem;
}
/* ghost */
.prs-input-ghost {
border-color: transparent;
background-color: transparent;
}
/* textarea */
.prs-input:where(textarea) {
resize: vertical;
}
/* select */
.prs-input:where(select),.prs-input :where(select) {
padding-right: 2rem;
background-image: linear-gradient(45deg,transparent 50%,currentColor 50%),linear-gradient(135deg,currentColor 50%,transparent 50%);
background-size: 4px 4px, 4px 4px;
background-position: calc(100% - 20px) calc(1px + 50%), calc(100% - 16.1px) calc(1px + 50%);
background-repeat: no-repeat;
cursor: pointer;
user-select: none;
}
/* file */
.prs-input:where([type="file"]) {
padding: 0;
padding-right: 1rem;
}
.prs-input::file-selector-button {
appearance: none;
padding: .25rem 1rem;
border-width: var(--prs-border-btn);
border-style: solid;
border-color: transparent;
font-size: 1rem;
font-style: normal;
line-height: 1.375rem;
background-color: var(--prs-c-primary);
color: var(--prs-c-white);
text-align: center;
display: inline-flex;
flex-wrap: wrap;
align-items: center;
justify-content: center;
flex-shrink: 0;
cursor: pointer;
user-select: none;
border-radius: inherit;
transition-property: var(--prs-transition-property);
transition-timing-function: var(--prs-transition-timing);
transition-duration: var(--prs-transition-duration);
}
.prs-input:hover::file-selector-button {
background-color: var(--prs-c-primary-600);
}
/* placeholder */
.prs-input::placeholder,.prs-input ::placeholder {
color: var(--prs-c-gray-600);
font-style: italic;
}
/* focus */
.prs-input:focus,.prs-input:where(:not([type="range"])):focus-within,.prs-input_focus:where(:not([type="range"])) {
outline: 2px solid var(--prs-c-primary);
outline-offset: 1px;
}
.prs-input :focus {
outline: 0 none;
}
/* invalid */
.prs-input:user-invalid,.prs-input:has(:user-invalid),.prs-input_invalid {
border-color: var(--prs-c-danger);
background-color: var(--prs-c-danger-100);
}
/* disabled */
.prs-input:disabled,.prs-input_disabled {
border-color: var(--prs-c-gray);
color: var(--prs-c-gray-600);
background-color: var(--prs-c-gray-200);
cursor: not-allowed;
}
.prs-input:disabled::placeholder,.prs-input_disabled::placeholder {
color: var(--prs-c-gray-400);
}
.prs-input:where([type="range"]):disabled {
--filler: var(--prs-c-gray-400);
background-color: transparent;
cursor: not-allowed;
}
.prs-input:disabled::file-selector-button,
.prs-input_disabled::file-selector-button {
background-color: var(--prs-c-gray-400);
color: white;
cursor: not-allowed;
}
Coming soon...