Text input
A text input is a user interface component that allows users to enter or edit textual data. It provides a visual and interactive affordance for text entry while supporting labels, placeholders, icons, helper messages, and validation feedback.
On this page
You can find here the OUDS Text Input design guidelines.
Overview
Use a .text-input wrapper to create a textual form field with OUDS styles, then wrap a pair of <input class="text-input-field"> and <label> elements in .text-input-container. Note that the <label> must come before the <input>.
A placeholder attribute is required on each <input> as our CSS-only floating label implementation relies on the :placeholder-shown pseudo-element to detect when the input is empty.
If the placeholder text is empty, it is not visible: only the <label> is shown to users.
To be compliant with the WCAG 1.3.5: Identify Input Purpose criteria, for each input field collecting information about the user, add the appropriate value to the autocomplete attribute (sufficient technique H98).
<div class="text-input">
<div class="text-input-container">
<label for="exampleTextInputWithEmptyPlaceholder">Email address</label>
<input type="email" autocomplete="email" class="text-input-field" id="exampleTextInputWithEmptyPlaceholder" placeholder="">
</div>
</div> If the placeholder text is supplied, <label> will automatically adjust to its floated position.
<div class="text-input">
<div class="text-input-container">
<label for="exampleTextInputWithPlaceholder">Email address</label>
<input type="email" class="text-input-field" id="exampleTextInputWithPlaceholder" placeholder="name@example.com">
</div>
</div> When there’s a value already defined, <label>s will automatically adjust to their floated position.
<div class="text-input">
<div class="text-input-container">
<label for="exampleTextInputWithValue">Input with value</label>
<input type="email" class="text-input-field" id="exampleTextInputWithValue" placeholder="name@example.com" value="test@example.com">
</div>
</div> Variants
Outlined
Add .text-input-container-outlined for a minimalist input with a transparent background and a visible stroke outlining the field. This style may be interesting for contexts other than form pages:
- When inputs need to feel lightweight and unobtrusive
- In a header (search field)
- In a selection/filtering feature in a product catalog
<div class="text-input">
<div class="text-input-container text-input-container-outlined">
<label for="exampleTextInputOutlined">Firstname</label>
<input type="text" class="text-input-field" id="exampleTextInputOutlined" placeholder="">
</div>
</div> Rounded
Add .text-input-container-rounded for a finish with rounded corners.
<div class="text-input mb-md">
<div class="text-input-container text-input-container-rounded">
<label for="exampleTextInputRounded">Firstname</label>
<input type="text" class="text-input-field" id="exampleTextInputRounded" placeholder="">
</div>
</div>
<div class="text-input">
<div class="text-input-container text-input-container-rounded text-input-container-outlined">
<label for="exampleTextInputRoundedAlt">Firstname</label>
<input type="text" class="text-input-field" id="exampleTextInputRoundedAlt" placeholder="">
</div>
</div> Leading icon
Add an icon to help indicate the purpose of the input by placing an <svg> or <img> element inside the .text-input-container. The icon is automatically positioned at the left side of the input field.
The recommended way to use icons is to fill an SVG sprite file, and use currentColor for styling. If really necessary, for example when you have a lot of icons, you can use an icon font. Find out more about using icons.
<div class="text-input mb-md">
<div class="text-input-container">
<svg aria-hidden="true">
<use xlink:href="/orange/docs/0.5/assets/img/ouds-web-sprite.svg#heart-empty"/>
</svg>
<label for="exampleTextInputEmptyWithIcon">Label</label>
<input type="email" class="text-input-field" id="exampleTextInputEmptyWithIcon" placeholder="">
</div>
</div>
<div class="text-input mb-md">
<div class="text-input-container">
<svg aria-hidden="true">
<use xlink:href="/orange/docs/0.5/assets/img/ouds-web-sprite.svg#heart-empty"/>
</svg>
<label for="exampleTextInputPlaceholderWithIcon">Label</label>
<input type="email" class="text-input-field" id="exampleTextInputPlaceholderWithIcon" placeholder="placeholder">
</div>
</div>
<div class="text-input mb-md">
<div class="text-input-container text-input-container-outlined">
<svg aria-hidden="true">
<use xlink:href="/orange/docs/0.5/assets/img/ouds-web-sprite.svg#heart-empty"/>
</svg>
<label for="exampleTextInputAltEmptyWithIcon">Label</label>
<input type="email" class="text-input-field" id="exampleTextInputAltEmptyWithIcon" placeholder="">
</div>
</div>
<div class="text-input">
<div class="text-input-container text-input-container-outlined">
<svg aria-hidden="true">
<use xlink:href="/orange/docs/0.5/assets/img/ouds-web-sprite.svg#heart-empty"/>
</svg>
<label for="exampleTextInputAltValueWithIcon">Label</label>
<input type="email" class="text-input-field" id="exampleTextInputAltValueWithIcon" placeholder="placeholder" value="Input">
</div>
</div> Trailing action
Trailing actions can be added to the right side of the input field by placing a minimal icon only button (.btn, .btn-minimal and .btn-icon) inside the .text-input-container. It can be used to provide actions related to the field: clear input, toggle password visibility, open a date picker, etc.
<div class="text-input">
<div class="text-input-container">
<label for="exampleTextInputEmptyWithAction">Label</label>
<input type="email" class="text-input-field" id="exampleTextInputEmptyWithAction" placeholder="">
<button class="btn btn-minimal btn-icon">
<svg aria-hidden="true">
<use xlink:href="/orange/docs/0.5/assets/img/ouds-web-sprite.svg#heart-empty"/>
</svg>
<span class="visually-hidden">Add to favorites</span>
</button>
</div>
</div> Helper text
To display a helper text below inputs, add a .text-input-helper as a sibling of a .text-input-container.
Helper text should be explicitly associated with the text input it relates to using the aria-describedby attribute. This will ensure that assistive technologies—such as screen readers—will announce this helper text when the user focuses or enters the input.
<div class="text-input">
<div class="text-input-container">
<label for="inputTextPassword">Password</label>
<input type="password" id="inputTextPassword" class="text-input-field" aria-describedby="passwordTextHelpBlock" placeholder="">
</div>
<div id="passwordTextHelpBlock" class="text-input-helper">
Your password must be 8-20 characters long, contain letters and numbers, and must not contain spaces, special characters, or emoji.
</div>
</div> Helper link
If the helper text is not sufficient, it's possible to offer the user an additional help link. The helper link can also be displayed on its own without helper text.
To display a helper link below inputs, use a standard .link class as a sibling of a .text-input-container.
If a helper link is used in conjunction with a helper text, the aria-describedby attribute should refer to the helper text and the helper link should to be referenced by the aria-labelledby attribute.
<div class="text-input">
<div class="text-input-container">
<label for="inputTextWithHelperTextLink">Send your feedback</label>
<input type="text" id="inputTextWithHelperTextLink" aria-describedby="feedbackTextHelpBlock" aria-labelledby="feedbackTextHelpMore" class="text-input-field" placeholder="">
</div>
<div id="feedbackTextHelpBlock" class="text-input-helper">
Please describe your feedback in a few words.
</div>
<a href="#" id="feedbackTextHelpMore" class="link">
More information
</a>
</div>
<div class="text-input">
<div class="text-input-container mt-lg">
<label for="inputTextWithHelperLink">Send your feedback</label>
<input type="text" id="inputTextWithHelperLink" aria-describedby="feedbackTextHelpLink" class="text-input-field" placeholder="">
</div>
<a href="#" id="feedbackTextHelpLink" class="link">
More information
</a>
</div> Input prefix and suffix
A textual prefix or suffix can be added to an input by wrapping the <input> in a .input-container and adding data-bs-prefix and/or data-bs-suffix attributes to it.
For accessibility purpose the prefix and suffix should be explicitly mentioned in the helper text related to the input by the aria-describedby attribute. This will ensure that assistive technologies—such as screen readers—will announce these additional or already existing elements when the user focuses or enters the input.
<div class="text-input">
<div class="text-input-container">
<label for="inputTextWithPrefix">Enter you website URL</label>
<div class="input-container" data-bs-prefix="https://">
<input type="text" id="inputTextWithPrefix" aria-describedby="prefixTextHelpBlock" class="text-input-field" placeholder="">
</div>
</div>
<div id="prefixTextHelpBlock" class="text-input-helper">
Please fill in the complete URL without the protocol (e.g. www.example.com).
</div>
<div class="text-input-container mt-md">
<label for="inputTextWithSuffix">Price</label>
<div class="input-container" data-bs-suffix="€">
<input type="text" id="inputTextWithSuffix" aria-describedby="suffixTextHelpBlock" class="text-input-field" placeholder="">
</div>
</div>
<div id="suffixTextHelpBlock" class="text-input-helper">
Enter your price in Euro (€).
</div>
</div>
<div class="text-input">
<div class="text-input-container mt-md">
<label for="inputTextWithPrefixSuffix">Price</label>
<div class="input-container" data-bs-prefix="£" data-bs-suffix=".00">
<input type="text" id="inputTextWithPrefixSuffix" aria-describedby="prefixSuffixTextHelpBlock" class="text-input-field" placeholder="Enter amount">
</div>
</div>
<div id="prefixSuffixTextHelpBlock" class="text-input-helper">
Enter your price in Pounds (£) without decimals.
</div>
</div>
<div class="text-input">
<div class="text-input-container mt-md">
<svg aria-hidden="true">
<use xlink:href="/orange/docs/0.5/assets/img/ouds-web-sprite.svg#heart-empty"/>
</svg>
<label for="inputTextWithPrefixSuffixLeadingTrailing">Email</label>
<div class="input-container" data-bs-prefix="🖳" data-bs-suffix="@orange.com">
<input type="email" id="inputTextWithPrefixSuffixLeadingTrailing" aria-describedby="globalTextHelpBlock" class="text-input-field" placeholder="">
</div>
<button class="btn btn-minimal btn-icon">
<svg aria-hidden="true">
<use xlink:href="/orange/docs/0.5/assets/img/ouds-web-sprite.svg#heart-empty"/>
</svg>
<span class="visually-hidden">Add to favorites</span>
</button>
</div> <div id="globalTextHelpBlock" class="text-input-helper">
Enter your email address without the domain name (e.g. only your username before the @).
</div>
</div> States
Disabled
Add the disabled boolean attribute on an input to give it a grayed out appearance, remove pointer events, and prevent focusing.
<div class="text-input mb-md">
<div class="text-input-container">
<label for="exampleTextInputDisabledEmpty">Firstname</label>
<input type="text" class="text-input-field" id="exampleTextInputDisabledEmpty" placeholder="" disabled>
</div>
</div>
<div class="text-input mb-md">
<div class="text-input-container">
<label for="exampleTextInputDisabled">Lastname</label>
<input type="text" class="text-input-field" id="exampleTextInputDisabled" placeholder="" value="Doe" disabled>
</div>
</div>
<div class="text-input mb-md">
<div class="text-input-container text-input-container-outlined">
<label for="exampleTextInputOutlinedDisabledEmpty">Firstname</label>
<input type="text" class="text-input-field" id="exampleTextInputOutlinedDisabledEmpty" placeholder="" disabled>
</div>
</div>
<div class="text-input">
<div class="text-input-container text-input-container-outlined">
<label for="exampleTextInputOutlinedDisabled">Lastname</label>
<input type="text" class="text-input-field" id="exampleTextInputOutlinedDisabled" placeholder="" value="Doe" disabled>
</div>
</div> Readonly
Add the readonly boolean attribute on an input to prevent modification of the input’s value. readonly inputs can still be focused and selected, while disabled inputs cannot.
<div class="text-input mb-md">
<div class="text-input-container">
<label for="exampleTextInputReadonlyEmpty">Firstname</label>
<input type="text" class="text-input-field" id="exampleTextInputReadonlyEmpty" placeholder="" readonly>
</div>
</div>
<div class="text-input mb-md">
<div class="text-input-container">
<label for="exampleTextInputReadonly">Lastname</label>
<input type="text" class="text-input-field" id="exampleTextInputReadonly" placeholder="" value="Doe" readonly>
</div>
</div>
<div class="text-input mb-md">
<div class="text-input-container text-input-container-outlined">
<label for="exampleTextInputOutlinedReadonlyEmpty">Firstname</label>
<input type="text" class="text-input-field" id="exampleTextInputOutlinedReadonlyEmpty" placeholder="" readonly>
</div>
</div>
<div class="text-input">
<div class="text-input-container text-input-container-outlined">
<label for="exampleTextInputOutlinedReadonly">Lastname</label>
<input type="text" class="text-input-field" id="exampleTextInputOutlinedReadonly" placeholder="" value="Doe" readonly>
</div>
</div> Invalid
The invalid state is the equivalent of the ‘Error’ state that you can find in the design specification.
To display an invalid input, add .is-invalid to a .text-input-field within the .text-input-container. Please take a look at our Validation page to learn more.
For accessibility purpose, the invalid should be associated with a .text-input-error as a sibling of a .text-input-container and related to it with an aria-labelledby attribute when displayed. Note that the .text-input-error will replace the helper text, so it should be descriptive enough to convey the error.
<div class="text-input mb-md">
<div class="text-input-container">
<label for="exampleTextInputInvalidEmpty">Username</label>
<input type="text" class="text-input-field is-invalid" id="exampleTextInputInvalidEmpty" aria-describedby="usernameTextHelpBlock" aria-labelledby="usernameFeedback" placeholder="">
</div>
<div id="usernameTextHelpBlock" class="text-input-helper">
Please choose a username.
</div>
<div id="usernameFeedback" class="text-input-error">
Username is required.
</div>
</div>
<div class="text-input mb-md">
<div class="text-input-container">
<label for="exampleTextInputInvalid">Email</label>
<input type="text" class="text-input-field is-invalid" id="exampleTextInputInvalid" value="john.doe@example" aria-labelledby="emailFeedback" placeholder="">
<button class="btn btn-minimal btn-icon">
<svg aria-hidden="true">
<use xlink:href="/orange/docs/0.5/assets/img/ouds-web-sprite.svg#heart-empty"/>
</svg>
<span class="visually-hidden">Add to favorites</span>
</button>
</div>
<div id="emailFeedback" class="text-input-error">
Email is invalid.
</div>
</div>
<div class="text-input mb-md">
<div class="text-input-container text-input-container-outlined">
<svg aria-hidden="true">
<use xlink:href="/orange/docs/0.5/assets/img/ouds-web-sprite.svg#heart-empty"/>
</svg>
<label for="exampleTextInputOutlinedInvalidEmpty">Address</label>
<input type="text" class="text-input-field is-invalid" id="exampleTextInputOutlinedInvalidEmpty" aria-labelledby="addressFeedback" placeholder="">
</div>
<div id="addressFeedback" class="text-input-error">
Address is required.
</div>
</div>
<div class="text-input mb-md">
<div class="text-input-container text-input-container-outlined">
<label for="exampleTextInputOutlinedInvalid" class="form-label">City</label>
<input type="text" class="text-input-field is-invalid" id="exampleTextInputOutlinedInvalid" value="Doe" aria-labelledby="cityFeedback" placeholder="">
</div>
<div id="cityFeedback" class="text-input-error">
City is invalid.
</div>
</div>
<div class="text-input mb-md">
<div class="text-input-container text-input-container">
<svg aria-hidden="true">
<use xlink:href="/orange/docs/0.5/assets/img/ouds-web-sprite.svg#heart-empty"/>
</svg>
<label for="exampleTextInputInvalidWithPrefixSuffix">Price</label>
<div class="input-container" data-bs-prefix="£" data-bs-suffix=".00">
<input type="text" class="text-input-field is-invalid" id="exampleTextInputInvalidWithPrefixSuffix" value="-2.2XX" aria-labelledby="priceFeedback" placeholder="">
</div>
</div>
<div id="priceFeedback" class="text-input-error">
Price is not valid.
</div>
</div>
<div class="text-input">
<div class="text-input-container text-input-container">
<svg aria-hidden="true">
<use xlink:href="/orange/docs/0.5/assets/img/ouds-web-sprite.svg#heart-empty"/>
</svg>
<label for="exampleTextInputInvalidTrailingWithPrefixSuffix">Price</label>
<div class="input-container" data-bs-prefix="£" data-bs-suffix=".00">
<input type="text" class="text-input-field is-invalid" id="exampleTextInputInvalidTrailingWithPrefixSuffix" value="-2.2XX" aria-describedby="priceTextHelpBlock" aria-labelledby="invalidPrice" placeholder="">
</div>
<button class="btn btn-minimal btn-icon">
<svg aria-hidden="true">
<use xlink:href="/orange/docs/0.5/assets/img/ouds-web-sprite.svg#trash"/>
</svg>
<span class="visually-hidden">Delete</span>
</button>
</div>
<div id="priceTextHelpBlock" class="text-input-helper">
Please enter your price.
</div>
<div id="invalidPrice" class="text-input-error">
Price is not valid.
</div>
<a href="#" id="priceTextHelpLink" class="link">
More information
</a>
</div>
Bootstrap
$enable-bootstrap-compatibility: true
This part is enabled only when $enable-bootstrap-compatibility is set to true. Read more
about Bootstrap compatibility.
Example
Form controls are styled with a mix of Sass and CSS variables, allowing them to adapt to color modes and support any customization method.
<div class="mb-md">
<label for="exampleFormControlInput1" class="form-label">Email address</label>
<input type="email" class="form-control" id="exampleFormControlInput1" placeholder="name@example.com">
</div>
<div class="mb-md">
<label for="exampleFormControlTextarea1" class="form-label">Example textarea</label>
<textarea class="form-control" id="exampleFormControlTextarea1" rows="3"></textarea>
</div> Sizing
Set heights using classes like .form-control-lg and .form-control-sm.
<input class="form-control form-control-lg" type="text" placeholder=".form-control-lg" aria-label=".form-control-lg example">
<input class="form-control" type="text" placeholder="Default input" aria-label="default input example">
<input class="form-control form-control-sm" type="text" placeholder=".form-control-sm" aria-label=".form-control-sm example"> Form text
Block-level or inline-level form text can be created using .form-text.
Form text should be explicitly associated with the form control it relates to using the aria-describedby attribute. This will ensure that assistive technologies—such as screen readers—will announce this form text when the user focuses or enters the control.
Form text below inputs can be styled with .form-text. If a block-level element will be used, a top margin is added for easy spacing from the inputs above.
<label for="inputPassword5" class="form-label">Password</label>
<input type="password" id="inputPassword5" class="form-control" aria-describedby="passwordHelpBlock">
<div id="passwordHelpBlock" class="form-text">
Your password must be 8-20 characters long, contain letters and numbers, and must not contain spaces, special characters, or emoji.
</div> Inline text can use any typical inline HTML element (be it a <span>, <small>, or something else) with nothing more than the .form-text class.
<div class="row g-3 align-items-center">
<div class="col-auto">
<label for="inputPassword6" class="col-form-label">Password</label>
</div>
<div class="col-auto">
<input type="password" id="inputPassword6" class="form-control" aria-describedby="passwordHelpInline">
</div>
<div class="col-auto">
<span id="passwordHelpInline" class="form-text">
Must be 8-20 characters long.
</span>
</div>
</div> Disabled
Add the disabled boolean attribute on an input to give it a grayed out appearance, remove pointer events, and prevent focusing.
<input class="form-control" type="text" placeholder="Disabled input" aria-label="Disabled input example" disabled>
<input class="form-control" type="text" value="Disabled readonly input" aria-label="Disabled input example" disabled readonly> Readonly
Add the readonly boolean attribute on an input to prevent modification of the input’s value. readonly inputs can still be focused and selected, while disabled inputs cannot.
<input class="form-control" type="text" value="Readonly input here..." aria-label="readonly input example" readonly> Readonly plain text
If you want to have <input readonly> elements in your form styled as plain text, replace .form-control with .form-control-plaintext to remove the default form field styling and preserve the correct margin and padding.
<div class="mb-md row">
<label for="staticEmail" class="col-sm-2 col-form-label">Email</label>
<div class="col-sm-10">
<input type="text" readonly class="form-control-plaintext" id="staticEmail" value="email@example.com">
</div>
</div>
<div class="mb-md row">
<label for="inputPassword" class="col-sm-2 col-form-label">Password</label>
<div class="col-sm-10">
<input type="password" class="form-control" id="inputPassword">
</div>
</div> <form class="row g-3">
<div class="col-auto">
<label for="staticEmail2" class="visually-hidden">Email</label>
<input type="text" readonly class="form-control-plaintext" id="staticEmail2" value="email@example.com">
</div>
<div class="col-auto">
<label for="inputPassword2" class="visually-hidden">Password</label>
<input type="password" class="form-control" id="inputPassword2" placeholder="Password">
</div>
<div class="col-auto">
<button type="submit" class="btn btn-primary mb-md">Confirm identity</button>
</div>
</form> File input
<div class="mb-md">
<label for="formFile" class="form-label">Default file input example</label>
<input class="form-control" type="file" id="formFile">
</div>
<div class="mb-md">
<label for="formFileMultiple" class="form-label">Multiple files input example</label>
<input class="form-control" type="file" id="formFileMultiple" multiple>
</div>
<div class="mb-md">
<label for="formFileDisabled" class="form-label">Disabled file input example</label>
<input class="form-control" type="file" id="formFileDisabled" disabled>
</div>
<div class="mb-md">
<label for="formFileSm" class="form-label">Small file input example</label>
<input class="form-control form-control-sm" id="formFileSm" type="file">
</div>
<div>
<label for="formFileLg" class="form-label">Large file input example</label>
<input class="form-control form-control-lg" id="formFileLg" type="file">
</div> Color
Set the type="color" and add .form-control-color to the <input>. We use the modifier class to set fixed heights and override some inconsistencies between browsers.
<label for="exampleColorInput" class="form-label">Color picker</label>
<input type="color" class="form-control form-control-color" id="exampleColorInput" value="#563d7c" title="Choose your color"> Datalists
Datalists allow you to create a group of <option>s that can be accessed (and autocompleted) from within an <input>. These are similar to <select> elements, but come with more menu styling limitations and differences. While most browsers and operating systems include some support for <datalist> elements, their styling is inconsistent at best.
Learn more about support for datalist elements.
<label for="exampleDataList" class="form-label">Datalist example</label>
<input class="form-control" list="datalistOptions" id="exampleDataList" placeholder="Type to search...">
<datalist id="datalistOptions">
<option value="San Francisco">
<option value="New York">
<option value="Seattle">
<option value="Los Angeles">
<option value="Chicago">
</datalist>