The <FormControl>
component renders a form control with Bootstrap styling. The <FormGroup>
component wraps a form control with proper spacing, along with support for a label, help text, and validation state. To ensure accessibility, set controlId
on <FormGroup>
, and use <FormLabel>
for the label.
< Form >
< Form.Group className = " mb-3 " controlId = " formBasicEmail " >
< Form.Label > Email address </ Form.Label >
< Form.Control type = " email " placeholder = " Enter email " />
< Form.Text className = " text-muted " >
We'll never share your email with anyone else .
</ Form.Text >
</ Form.Group >
< Form.Group className = " mb-3 " controlId = " formBasicPassword " >
< Form.Label > Password </ Form.Label >
< Form.Control type = " password " placeholder = " Password " />
</ Form.Group >
< Form.Group className = " mb-3 " controlId = " formBasicCheckbox " >
< Form.Check type = " checkbox " label = " Check me out " />
</ Form.Group >
< Button variant = " primary " type = " submit " >
Submit
</ Button >
</ Form >
The <FormControl>
component directly renders the <input>
or other specified component. If you need to access the value of an uncontrolled <FormControl>
, attach a ref
to it as you would with an uncontrolled input, then call ReactDOM.findDOMNode(ref)
to get the DOM node. You can then interact with that node as you would with any other uncontrolled input.
If your application contains a large number of form groups, we recommend building a higher-level component encapsulating a complete field group that renders the label, the control, and any other necessary components. We don't provide this out-of-the-box, because the composition of those field groups is too specific to an individual application to admit a good one-size-fits-all solution.
For textual form controlsโlike input
s and textarea
sโuse the FormControl
component. FormControl adds some additional styles for general appearance, focus state, sizing, and more.
<Form>
<Form.Group className="mb-3" controlId="exampleForm.ControlInput1">
<Form.Label>Email address</Form.Label>
<Form.Control type="email" placeholder="name@example.com" />
</Form.Group>
<Form.Group className="mb-3" controlId="exampleForm.ControlTextarea1">
<Form.Label>Example textarea</Form.Label>
<Form.Control as="textarea" rows={3} />
</Form.Group>
</Form> < Form >
< Form.Group className = " mb-3 " controlId = " exampleForm.ControlInput1 " >
< Form.Label > Email address </ Form.Label >
< Form.Control type = " email " placeholder = " name@example.com " />
</ Form.Group >
< Form.Group className = " mb-3 " controlId = " exampleForm.ControlTextarea1 " >
< Form.Label > Example textarea </ Form.Label >
< Form.Control as = " textarea " rows = { 3 } />
</ Form.Group >
</ Form >
Use size
on <FormControl>
and <FormLabel>
to change the size of inputs and labels respectively.
<>
<Form.Control size="lg" type="text" placeholder="Large text" />
<br />
<Form.Control type="text" placeholder="Normal text" />
<br />
<Form.Control size="sm" type="text" placeholder="Small text" />
</> < >
< Form.Control size = " lg " type = " text " placeholder = " Large text " />
< br />
< Form.Control type = " text " placeholder = " Normal text " />
< br />
< Form.Control size = " sm " type = " text " placeholder = " Small text " />
</ >
Add the readOnly
prop on an input to prevent modification of the input's value. Read-only inputs appear lighter (just like disabled inputs), but retain the standard cursor.
<Form.Control type="text" placeholder="Readonly input here..." readOnly /> < Form.Control type = " text " placeholder = " Readonly input here... " readOnly />
Readonly plain text# If you want to have readonly elements in your form styled as plain text, use the plaintext
prop on FormControls to remove the default form field styling and preserve the correct margin and padding.
<Form>
<Form.Group as={Row} className="mb-3" controlId="formPlaintextEmail">
<Form.Label column sm="2">
Email
</Form.Label>
<Col sm="10">
<Form.Control plaintext readOnly defaultValue="email@example.com" />
</Col>
</Form.Group>
<Form.Group as={Row} className="mb-3" controlId="formPlaintextPassword">
<Form.Label column sm="2">
Password
</Form.Label>
<Col sm="10">
<Form.Control type="password" placeholder="Password" />
</Col>
</Form.Group>
</Form> < Form >
< Form.Group as = { Row } className = " mb-3 " controlId = " formPlaintextEmail " >
< Form.Label column sm = " 2 " >
Email
</ Form.Label >
< Col sm = " 10 " >
< Form.Control plaintext readOnly defaultValue = " email@example.com " />
</ Col >
</ Form.Group >
< Form.Group as = { Row } className = " mb-3 " controlId = " formPlaintextPassword " >
< Form.Label column sm = " 2 " >
Password
</ Form.Label >
< Col sm = " 10 " >
< Form.Control type = " password " placeholder = " Password " />
</ Col >
</ Form.Group >
</ Form >
<>
<Form.Group controlId="formFile" className="mb-3">
<Form.Label>Default file input example</Form.Label>
<Form.Control type="file" />
</Form.Group>
<Form.Group controlId="formFileMultiple" className="mb-3">
<Form.Label>Multiple files input example</Form.Label>
<Form.Control type="file" multiple />
</Form.Group>
<Form.Group controlId="formFileDisabled" className="mb-3">
<Form.Label>Disabled file input example</Form.Label>
<Form.Control type="file" disabled />
</Form.Group>
<Form.Group controlId="formFileSm" className="mb-3">
<Form.Label>Small file input example</Form.Label>
<Form.Control type="file" size="sm" />
</Form.Group>
<Form.Group controlId="formFileLg" className="mb-3">
<Form.Label>Large file input example</Form.Label>
<Form.Control type="file" size="lg" />
</Form.Group>
</> < >
< Form.Group controlId = " formFile " className = " mb-3 " >
< Form.Label > Default file input example </ Form.Label >
< Form.Control type = " file " />
</ Form.Group >
< Form.Group controlId = " formFileMultiple " className = " mb-3 " >
< Form.Label > Multiple files input example </ Form.Label >
< Form.Control type = " file " multiple />
</ Form.Group >
< Form.Group controlId = " formFileDisabled " className = " mb-3 " >
< Form.Label > Disabled file input example </ Form.Label >
< Form.Control type = " file " disabled />
</ Form.Group >
< Form.Group controlId = " formFileSm " className = " mb-3 " >
< Form.Label > Small file input example </ Form.Label >
< Form.Control type = " file " size = " sm " />
</ Form.Group >
< Form.Group controlId = " formFileLg " className = " mb-3 " >
< Form.Label > Large file input example </ Form.Label >
< Form.Control type = " file " size = " lg " />
</ Form.Group >
</ >
<>
<Form.Label htmlFor="exampleColorInput">Color picker</Form.Label>
<Form.Control
type="color"
id="exampleColorInput"
defaultValue="#563d7c"
title="Choose your color"
/>
</> < >
< Form.Label htmlFor = " exampleColorInput " > Color picker </ Form.Label >
< Form.Control
type = " color "
id = " exampleColorInput "
defaultValue = " #563d7c "
title = " Choose your color "
/>
</ >
For the non-textual checkbox and radio controls, FormCheck
provides a single component for both types that adds some additional styling and improved layout.
By default, any number of checkboxes and radios that are immediate sibling will be vertically stacked and appropriately spaced with FormCheck.
<Form>
{['checkbox', 'radio'].map((type) => (
<div key={`default-${type}`} className="mb-3">
<Form.Check
type={type}
id={`default-${type}`}
label={`default ${type}`}
/>
<Form.Check
disabled
type={type}
label={`disabled ${type}`}
id={`disabled-default-${type}`}
/>
</div>
))}
</Form> < Form >
{ [ 'checkbox' , 'radio' ] . map ( ( type ) => (
< div key = { ` default- ${ type } ` } className = " mb-3 " >
< Form.Check
type = { type }
id = { ` default- ${ type } ` }
label = { ` default ${ type } ` }
/>
< Form.Check
disabled
type = { type }
label = { ` disabled ${ type } ` }
id = { ` disabled-default- ${ type } ` }
/>
</ div >
) ) }
</ Form >
Group checkboxes or radios on the same horizontal row by adding the inline
prop.
<Form>
{['checkbox', 'radio'].map((type) => (
<div key={`inline-${type}`} className="mb-3">
<Form.Check
inline
label="1"
name="group1"
type={type}
id={`inline-${type}-1`}
/>
<Form.Check
inline
label="2"
name="group1"
type={type}
id={`inline-${type}-2`}
/>
<Form.Check
inline
disabled
label="3 (disabled)"
type={type}
id={`inline-${type}-3`}
/>
</div>
))}
</Form> < Form >
{ [ 'checkbox' , 'radio' ] . map ( ( type ) => (
< div key = { ` inline- ${ type } ` } className = " mb-3 " >
< Form.Check
inline
label = " 1 "
name = " group1 "
type = { type }
id = { ` inline- ${ type } -1 ` }
/>
< Form.Check
inline
label = " 2 "
name = " group1 "
type = { type }
id = { ` inline- ${ type } -2 ` }
/>
< Form.Check
inline
disabled
label = " 3 (disabled) "
type = { type }
id = { ` inline- ${ type } -3 ` }
/>
</ div >
) ) }
</ Form >
When you render a FormCheck without a label (no children
) some additional styling is applied to keep the inputs from collapsing. Remember to add an aria-label
when omitting labels!
<>
<Form.Check aria-label="option 1" />
<Form.Check type="radio" aria-label="radio 1" />
</> < >
< Form.Check aria-label = " option 1 " />
< Form.Check type = " radio " aria-label = " radio 1 " />
</ >
When you need tighter control, or want to customize how the FormCheck
component renders, it may better to use it's constituent parts directly.
By provided children
to the FormCheck
you can forgo the default rendering and handle it yourself. (You can still provide an id
to the FormCheck
or FormGroup
and have it propagate to the label and input).
<Form>
{['checkbox', 'radio'].map((type) => (
<div key={type} className="mb-3">
<Form.Check type={type} id={`check-api-${type}`}>
<Form.Check.Input type={type} isValid />
<Form.Check.Label>{`Custom api ${type}`}</Form.Check.Label>
<Form.Control.Feedback type="valid">You did it!</Form.Control.Feedback>
</Form.Check>
</div>
))}
</Form> < Form >
{ [ 'checkbox' , 'radio' ] . map ( ( type ) => (
< div key = { type } className = " mb-3 " >
< Form.Check type = { type } id = { ` check-api- ${ type } ` } >
< Form.Check.Input type = { type } isValid />
< Form.Check.Label > { ` Custom api ${ type } ` } </ Form.Check.Label >
< Form.Control.Feedback type = " valid " > You did it ! </ Form.Control.Feedback >
</ Form.Check >
</ div >
) ) }
</ Form >
Create custom <input type="range">
controls with<FormRange>
. The track (the background) and thumb (the value) are both styled to appear the same across browsers. As only Firefox supports โfillingโ their track from the left or right of the thumb as a means to visually indicate progress, we do not currently support it.<>
<Form.Label>Range</Form.Label>
<Form.Range />
</> < >
< Form.Label > Range </ Form.Label >
< Form.Range />
</ >
Open this select menu One Two Three
<Form.Select aria-label="Default select example">
<option>Open this select menu</option>
<option value="1">One</option>
<option value="2">Two</option>
<option value="3">Three</option>
</Form.Select> < Form.Select aria-label = " Default select example " >
< option > Open this select menu </ option >
< option value = " 1 " > One </ option >
< option value = " 2 " > Two </ option >
< option value = " 3 " > Three </ option >
</ Form.Select >
You may also choose from small and large custom selects to match our similarly sized text inputs.
Large select Default select Small select
<>
<Form.Select size="lg">
<option>Large select</option>
</Form.Select>
<br />
<Form.Select>
<option>Default select</option>
</Form.Select>
<br />
<Form.Select size="sm">
<option>Small select</option>
</Form.Select>
</> < >
< Form.Select size = " lg " >
< option > Large select </ option >
</ Form.Select >
< br />
< Form.Select >
< option > Default select </ option >
</ Form.Select >
< br />
< Form.Select size = " sm " >
< option > Small select </ option >
</ Form.Select >
</ >
Wrap a <Form.Control>
element in <FloatingLabel>
to enable floating labels with Bootstrapโs textual form fields. A placeholder
is required on each <Form.Control>
as our method of CSS-only floating labels uses the :placeholder-shown
pseudo-element.
<>
<FloatingLabel
controlId="floatingInput"
label="Email address"
className="mb-3"
>
<Form.Control type="email" placeholder="name@example.com" />
</FloatingLabel>
<FloatingLabel controlId="floatingPassword" label="Password">
<Form.Control type="password" placeholder="Password" />
</FloatingLabel>
</> < >
< FloatingLabel
controlId = " floatingInput "
label = " Email address "
className = " mb-3 "
>
< Form.Control type = " email " placeholder = " name@example.com " />
</ FloatingLabel >
< FloatingLabel controlId = " floatingPassword " label = " Password " >
< Form.Control type = " password " placeholder = " Password " />
</ FloatingLabel >
</ >
Textareas# By default, <textarea>
s will be the same height as <input>
s. To set a custom height on your <textarea>
, do not use the rows
attribute. Instead, set an explicit height
(either inline or via custom CSS).
<>
<FloatingLabel controlId="floatingTextarea" label="Comments" className="mb-3">
<Form.Control as="textarea" placeholder="Leave a comment here" />
</FloatingLabel>
<FloatingLabel controlId="floatingTextarea2" label="Comments">
<Form.Control
as="textarea"
placeholder="Leave a comment here"
style={{ height: '100px' }}
/>
</FloatingLabel>
</> < >
< FloatingLabel controlId = " floatingTextarea " label = " Comments " className = " mb-3 " >
< Form.Control as = " textarea " placeholder = " Leave a comment here " />
</ FloatingLabel >
< FloatingLabel controlId = " floatingTextarea2 " label = " Comments " >
< Form.Control
as = " textarea "
placeholder = " Leave a comment here "
style = { { height : '100px' } }
/>
</ FloatingLabel >
</ >
Other than <Form.Control>
, floating labels are only available on <Form.Select>
s. They work in the same way, but unlike <input>
s, theyโll always show the <label>
in its floated state.
Open this select menu One Two Three Works with selects
<FloatingLabel controlId="floatingSelect" label="Works with selects">
<Form.Select aria-label="Floating label select example">
<option>Open this select menu</option>
<option value="1">One</option>
<option value="2">Two</option>
<option value="3">Three</option>
</Form.Select>
</FloatingLabel> < FloatingLabel controlId = " floatingSelect " label = " Works with selects " >
< Form.Select aria-label = " Floating label select example " >
< option > Open this select menu </ option >
< option value = " 1 " > One </ option >
< option value = " 2 " > Two </ option >
< option value = " 3 " > Three </ option >
</ Form.Select >
</ FloatingLabel >
When working with the Bootstrap grid system, be sure to place form elements within column classes.
Open this select menu One Two Three Works with selects
<Row className="g-2">
<Col md>
<FloatingLabel controlId="floatingInputGrid" label="Email address">
<Form.Control type="email" placeholder="name@example.com" />
</FloatingLabel>
</Col>
<Col md>
<FloatingLabel controlId="floatingSelectGrid" label="Works with selects">
<Form.Select aria-label="Floating label select example">
<option>Open this select menu</option>
<option value="1">One</option>
<option value="2">Two</option>
<option value="3">Three</option>
</Form.Select>
</FloatingLabel>
</Col>
</Row> < Row className = " g-2 " >
< Col md >
< FloatingLabel controlId = " floatingInputGrid " label = " Email address " >
< Form.Control type = " email " placeholder = " name@example.com " />
</ FloatingLabel >
</ Col >
< Col md >
< FloatingLabel controlId = " floatingSelectGrid " label = " Works with selects " >
< Form.Select aria-label = " Floating label select example " >
< option > Open this select menu </ option >
< option value = " 1 " > One </ option >
< option value = " 2 " > Two </ option >
< option value = " 3 " > Three </ option >
</ Form.Select >
</ FloatingLabel >
</ Col >
</ Row >
If you need greater control over the rendering, use the <FormFloating>
component to wrap your input and label. Also note that the <Form.Control>
must come first so we can utilize a sibling selector (e.g., ~).
<>
<Form.Floating className="mb-3">
<Form.Control
id="floatingInputCustom"
type="email"
placeholder="name@example.com"
/>
<label htmlFor="floatingInputCustom">Email address</label>
</Form.Floating>
<Form.Floating>
<Form.Control
id="floatingPasswordCustom"
type="password"
placeholder="Password"
/>
<label htmlFor="floatingPasswordCustom">Password</label>
</Form.Floating>
</> < >
< Form.Floating className = " mb-3 " >
< Form.Control
id = " floatingInputCustom "
type = " email "
placeholder = " name@example.com "
/>
< label htmlFor = " floatingInputCustom " > Email address </ label >
</ Form.Floating >
< Form.Floating >
< Form.Control
id = " floatingPasswordCustom "
type = " password "
placeholder = " Password "
/>
< label htmlFor = " floatingPasswordCustom " > Password </ label >
</ Form.Floating >
</ >
FormControl and FormCheck both apply display: block
with width: 100%
to controls, which means they stack vertically by default. Additional components and props can be used to vary this layout on a per-form basis.
The FormGroup
component is the easiest way to add some structure to forms. It provides a flexible container for grouping of labels, controls, optional help text, and form validation messaging. By default it only applies margin-bottom. Use it with fieldset
s, div
s, or nearly any other element.
You also add the controlId
prop to accessibly wire the nested label and input together via the id
.
<Form>
<Form.Group className="mb-3" controlId="formGroupEmail">
<Form.Label>Email address</Form.Label>
<Form.Control type="email" placeholder="Enter email" />
</Form.Group>
<Form.Group className="mb-3" controlId="formGroupPassword">
<Form.Label>Password</Form.Label>
<Form.Control type="password" placeholder="Password" />
</Form.Group>
</Form> < Form >
< Form.Group className = " mb-3 " controlId = " formGroupEmail " >
< Form.Label > Email address </ Form.Label >
< Form.Control type = " email " placeholder = " Enter email " />
</ Form.Group >
< Form.Group className = " mb-3 " controlId = " formGroupPassword " >
< Form.Label > Password </ Form.Label >
< Form.Control type = " password " placeholder = " Password " />
</ Form.Group >
</ Form >
More complex forms can be built using the grid components. Use these for form layouts that require multiple columns, varied widths, and additional alignment options.
<Form>
<Row>
<Col>
<Form.Control placeholder="First name" />
</Col>
<Col>
<Form.Control placeholder="Last name" />
</Col>
</Row>
</Form> < Form >
< Row >
< Col >
< Form.Control placeholder = " First name " />
</ Col >
< Col >
< Form.Control placeholder = " Last name " />
</ Col >
</ Row >
</ Form >
More complex layouts can also be created with the grid system.
<Form>
<Row className="mb-3">
<Form.Group as={Col} controlId="formGridEmail">
<Form.Label>Email</Form.Label>
<Form.Control type="email" placeholder="Enter email" />
</Form.Group>
<Form.Group as={Col} controlId="formGridPassword">
<Form.Label>Password</Form.Label>
<Form.Control type="password" placeholder="Password" />
</Form.Group>
</Row>
<Form.Group className="mb-3" controlId="formGridAddress1">
<Form.Label>Address</Form.Label>
<Form.Control placeholder="1234 Main St" />
</Form.Group>
<Form.Group className="mb-3" controlId="formGridAddress2">
<Form.Label>Address 2</Form.Label>
<Form.Control placeholder="Apartment, studio, or floor" />
</Form.Group>
<Row className="mb-3">
<Form.Group as={Col} controlId="formGridCity">
<Form.Label>City</Form.Label>
<Form.Control />
</Form.Group>
<Form.Group as={Col} controlId="formGridState">
<Form.Label>State</Form.Label>
<Form.Select defaultValue="Choose...">
<option>Choose...</option>
<option>...</option>
</Form.Select>
</Form.Group>
<Form.Group as={Col} controlId="formGridZip">
<Form.Label>Zip</Form.Label>
<Form.Control />
</Form.Group>
</Row>
<Form.Group className="mb-3" id="formGridCheckbox">
<Form.Check type="checkbox" label="Check me out" />
</Form.Group>
<Button variant="primary" type="submit">
Submit
</Button>
</Form> < Form >
< Row className = " mb-3 " >
< Form.Group as = { Col } controlId = " formGridEmail " >
< Form.Label > Email </ Form.Label >
< Form.Control type = " email " placeholder = " Enter email " />
</ Form.Group >
< Form.Group as = { Col } controlId = " formGridPassword " >
< Form.Label > Password </ Form.Label >
< Form.Control type = " password " placeholder = " Password " />
</ Form.Group >
</ Row >
< Form.Group className = " mb-3 " controlId = " formGridAddress1 " >
< Form.Label > Address </ Form.Label >
< Form.Control placeholder = " 1234 Main St " />
</ Form.Group >
< Form.Group className = " mb-3 " controlId = " formGridAddress2 " >
< Form.Label > Address 2 </ Form.Label >
< Form.Control placeholder = " Apartment, studio, or floor " />
</ Form.Group >
< Row className = " mb-3 " >
< Form.Group as = { Col } controlId = " formGridCity " >
< Form.Label > City </ Form.Label >
< Form.Control />
</ Form.Group >
< Form.Group as = { Col } controlId = " formGridState " >
< Form.Label > State </ Form.Label >
< Form.Select defaultValue = " Choose... " >
< option > Choose ... </ option >
< option > ... </ option >
</ Form.Select >
</ Form.Group >
< Form.Group as = { Col } controlId = " formGridZip " >
< Form.Label > Zip </ Form.Label >
< Form.Control />
</ Form.Group >
</ Row >
< Form.Group className = " mb-3 " id = " formGridCheckbox " >
< Form.Check type = " checkbox " label = " Check me out " />
</ Form.Group >
< Button variant = " primary " type = " submit " >
Submit
</ Button >
</ Form >
<Form>
<Form.Group as={Row} className="mb-3" controlId="formHorizontalEmail">
<Form.Label column sm={2}>
Email
</Form.Label>
<Col sm={10}>
<Form.Control type="email" placeholder="Email" />
</Col>
</Form.Group>
<Form.Group as={Row} className="mb-3" controlId="formHorizontalPassword">
<Form.Label column sm={2}>
Password
</Form.Label>
<Col sm={10}>
<Form.Control type="password" placeholder="Password" />
</Col>
</Form.Group>
<fieldset>
<Form.Group as={Row} className="mb-3">
<Form.Label as="legend" column sm={2}>
Radios
</Form.Label>
<Col sm={10}>
<Form.Check
type="radio"
label="first radio"
name="formHorizontalRadios"
id="formHorizontalRadios1"
/>
<Form.Check
type="radio"
label="second radio"
name="formHorizontalRadios"
id="formHorizontalRadios2"
/>
<Form.Check
type="radio"
label="third radio"
name="formHorizontalRadios"
id="formHorizontalRadios3"
/>
</Col>
</Form.Group>
</fieldset>
<Form.Group as={Row} className="mb-3" controlId="formHorizontalCheck">
<Col sm={{ span: 10, offset: 2 }}>
<Form.Check label="Remember me" />
</Col>
</Form.Group>
<Form.Group as={Row} className="mb-3">
<Col sm={{ span: 10, offset: 2 }}>
<Button type="submit">Sign in</Button>
</Col>
</Form.Group>
</Form> < Form >
< Form.Group as = { Row } className = " mb-3 " controlId = " formHorizontalEmail " >
< Form.Label column sm = { 2 } >
Email
</ Form.Label >
< Col sm = { 10 } >
< Form.Control type = " email " placeholder = " Email " />
</ Col >
</ Form.Group >
< Form.Group as = { Row } className = " mb-3 " controlId = " formHorizontalPassword " >
< Form.Label column sm = { 2 } >
Password
</ Form.Label >
< Col sm = { 10 } >
< Form.Control type = " password " placeholder = " Password " />
</ Col >
</ Form.Group >
< fieldset >
< Form.Group as = { Row } className = " mb-3 " >
< Form.Label as = " legend " column sm = { 2 } >
Radios
</ Form.Label >
< Col sm = { 10 } >
< Form.Check
type = " radio "
label = " first radio "
name = " formHorizontalRadios "
id = " formHorizontalRadios1 "
/>
< Form.Check
type = " radio "
label = " second radio "
name = " formHorizontalRadios "
id = " formHorizontalRadios2 "
/>
< Form.Check
type = " radio "
label = " third radio "
name = " formHorizontalRadios "
id = " formHorizontalRadios3 "
/>
</ Col >
</ Form.Group >
</ fieldset >
< Form.Group as = { Row } className = " mb-3 " controlId = " formHorizontalCheck " >
< Col sm = { { span : 10 , offset : 2 } } >
< Form.Check label = " Remember me " />
</ Col >
</ Form.Group >
< Form.Group as = { Row } className = " mb-3 " >
< Col sm = { { span : 10 , offset : 2 } } >
< Button type = " submit " > Sign in </ Button >
</ Col >
</ Form.Group >
</ Form >
You can size the <FormLabel>
using the column prop as shown.
<>
<Row>
<Form.Label column="lg" lg={2}>
Large Text
</Form.Label>
<Col>
<Form.Control size="lg" type="text" placeholder="Large text" />
</Col>
</Row>
<br />
<Row>
<Form.Label column lg={2}>
Normal Text
</Form.Label>
<Col>
<Form.Control type="text" placeholder="Normal text" />
</Col>
</Row>
<br />
<Row>
<Form.Label column="sm" lg={2}>
Small Text
</Form.Label>
<Col>
<Form.Control size="sm" type="text" placeholder="Small text" />
</Col>
</Row>
</> < >
< Row >
< Form.Label column = " lg " lg = { 2 } >
Large Text
</ Form.Label >
< Col >
< Form.Control size = " lg " type = " text " placeholder = " Large text " />
</ Col >
</ Row >
< br />
< Row >
< Form.Label column lg = { 2 } >
Normal Text
</ Form.Label >
< Col >
< Form.Control type = " text " placeholder = " Normal text " />
</ Col >
</ Row >
< br />
< Row >
< Form.Label column = " sm " lg = { 2 } >
Small Text
</ Form.Label >
< Col >
< Form.Control size = " sm " type = " text " placeholder = " Small text " />
</ Col >
</ Row >
</ >
As shown in the previous examples, our grid system allows you to place any number of <Col>
s within a <Row>
. They'll split the available width equally between them. You may also pick a subset of your columns to take up more or less space, while the remaining <Col>
s equally split the rest, with specific column classes like <Col xs={7}>
.
<Form>
<Row>
<Col xs={7}>
<Form.Control placeholder="City" />
</Col>
<Col>
<Form.Control placeholder="State" />
</Col>
<Col>
<Form.Control placeholder="Zip" />
</Col>
</Row>
</Form> < Form >
< Row >
< Col xs = { 7 } >
< Form.Control placeholder = " City " />
</ Col >
< Col >
< Form.Control placeholder = " State " />
</ Col >
< Col >
< Form.Control placeholder = " Zip " />
</ Col >
</ Row >
</ Form >
The example below uses a flexbox utility to vertically center the contents and changes <Col>
to <Col xs="auto">
so that your columns only take up as much space as needed. Put another way, the column sizes itself based on on the contents.
<Form>
<Row className="align-items-center">
<Col xs="auto">
<Form.Label htmlFor="inlineFormInput" visuallyHidden>
Name
</Form.Label>
<Form.Control
className="mb-2"
id="inlineFormInput"
placeholder="Jane Doe"
/>
</Col>
<Col xs="auto">
<Form.Label htmlFor="inlineFormInputGroup" visuallyHidden>
Username
</Form.Label>
<InputGroup className="mb-2">
<InputGroup.Text>@</InputGroup.Text>
<FormControl id="inlineFormInputGroup" placeholder="Username" />
</InputGroup>
</Col>
<Col xs="auto">
<Form.Check
type="checkbox"
id="autoSizingCheck"
className="mb-2"
label="Remember me"
/>
</Col>
<Col xs="auto">
<Button type="submit" className="mb-2">
Submit
</Button>
</Col>
</Row>
</Form> < Form >
< Row className = " align-items-center " >
< Col xs = " auto " >
< Form.Label htmlFor = " inlineFormInput " visuallyHidden >
Name
</ Form.Label >
< Form.Control
className = " mb-2 "
id = " inlineFormInput "
placeholder = " Jane Doe "
/>
</ Col >
< Col xs = " auto " >
< Form.Label htmlFor = " inlineFormInputGroup " visuallyHidden >
Username
</ Form.Label >
< InputGroup className = " mb-2 " >
< InputGroup.Text > @ </ InputGroup.Text >
< FormControl id = " inlineFormInputGroup " placeholder = " Username " />
</ InputGroup >
</ Col >
< Col xs = " auto " >
< Form.Check
type = " checkbox "
id = " autoSizingCheck "
className = " mb-2 "
label = " Remember me "
/>
</ Col >
< Col xs = " auto " >
< Button type = " submit " className = " mb-2 " >
Submit
</ Button >
</ Col >
</ Row >
</ Form >
You can then remix that once again with size-specific column classes.
<Form>
<Row className="align-items-center">
<Col sm={3} className="my-1">
<Form.Label htmlFor="inlineFormInputName" visuallyHidden>
Name
</Form.Label>
<Form.Control id="inlineFormInputName" placeholder="Jane Doe" />
</Col>
<Col sm={3} className="my-1">
<Form.Label htmlFor="inlineFormInputGroupUsername" visuallyHidden>
Username
</Form.Label>
<InputGroup>
<InputGroup.Text>@</InputGroup.Text>
<FormControl id="inlineFormInputGroupUsername" placeholder="Username" />
</InputGroup>
</Col>
<Col xs="auto" className="my-1">
<Form.Check type="checkbox" id="autoSizingCheck2" label="Remember me" />
</Col>
<Col xs="auto" className="my-1">
<Button type="submit">Submit</Button>
</Col>
</Row>
</Form> < Form >
< Row className = " align-items-center " >
< Col sm = { 3 } className = " my-1 " >
< Form.Label htmlFor = " inlineFormInputName " visuallyHidden >
Name
</ Form.Label >
< Form.Control id = " inlineFormInputName " placeholder = " Jane Doe " />
</ Col >
< Col sm = { 3 } className = " my-1 " >
< Form.Label htmlFor = " inlineFormInputGroupUsername " visuallyHidden >
Username
</ Form.Label >
< InputGroup >
< InputGroup.Text > @ </ InputGroup.Text >
< FormControl id = " inlineFormInputGroupUsername " placeholder = " Username " />
</ InputGroup >
</ Col >
< Col xs = " auto " className = " my-1 " >
< Form.Check type = " checkbox " id = " autoSizingCheck2 " label = " Remember me " />
</ Col >
< Col xs = " auto " className = " my-1 " >
< Button type = " submit " > Submit </ Button >
</ Col >
</ Row >
</ Form >
And of course custom form controls are supported.
Preference Choose... One Two Three
Submit
<Form>
<Row className="align-items-center">
<Col xs="auto" className="my-1">
<Form.Label
className="me-sm-2"
htmlFor="inlineFormCustomSelect"
visuallyHidden
>
Preference
</Form.Label>
<Form.Select className="me-sm-2" id="inlineFormCustomSelect">
<option value="0">Choose...</option>
<option value="1">One</option>
<option value="2">Two</option>
<option value="3">Three</option>
</Form.Select>
</Col>
<Col xs="auto" className="my-1">
<Form.Check
type="checkbox"
id="customControlAutosizing"
label="Remember my preference"
/>
</Col>
<Col xs="auto" className="my-1">
<Button type="submit">Submit</Button>
</Col>
</Row>
</Form> < Form >
< Row className = " align-items-center " >
< Col xs = " auto " className = " my-1 " >
< Form.Label
className = " me-sm-2 "
htmlFor = " inlineFormCustomSelect "
visuallyHidden
>
Preference
</ Form.Label >
< Form.Select className = " me-sm-2 " id = " inlineFormCustomSelect " >
< option value = " 0 " > Choose ... </ option >
< option value = " 1 " > One </ option >
< option value = " 2 " > Two </ option >
< option value = " 3 " > Three </ option >
</ Form.Select >
</ Col >
< Col xs = " auto " className = " my-1 " >
< Form.Check
type = " checkbox "
id = " customControlAutosizing "
label = " Remember my preference "
/>
</ Col >
< Col xs = " auto " className = " my-1 " >
< Button type = " submit " > Submit </ Button >
</ Col >
</ Row >
</ Form >
Help text# Block-level help text in forms can be created using <Form.Text>
. Inline help text can be flexibly implemented using any inline HTML element and utility classes like.text-muted
.
Associating help text with form controls Help 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 help text when the user focuses or enters the control.Help text below inputs can be styled with <Form.Text>
. This component includes display: block
and adds some top margin for easy spacing from the inputs above.
<>
<Form.Label htmlFor="inputPassword5">Password</Form.Label>
<Form.Control
type="password"
id="inputPassword5"
aria-describedby="passwordHelpBlock"
/>
<Form.Text id="passwordHelpBlock" muted>
Your password must be 8-20 characters long, contain letters and numbers, and
must not contain spaces, special characters, or emoji.
</Form.Text>
</> < >
< Form.Label htmlFor = " inputPassword5 " > Password </ Form.Label >
< Form.Control
type = " password "
id = " inputPassword5 "
aria-describedby = " passwordHelpBlock "
/>
< Form.Text id = " passwordHelpBlock " muted >
Your password must be 8 - 20 characters long , contain letters and numbers , and
must not contain spaces , special characters , or emoji .
</ Form.Text >
</ >
Add the disabled
boolean attribute on an input to prevent user interactions and make it appear lighter.
<>
<Form.Group className="mb-3">
<Form.Label>Disabled input</Form.Label>
<Form.Control placeholder="Disabled input" disabled />
</Form.Group>
<Form.Group className="mb-3">
<Form.Label>Disabled select menu</Form.Label>
<Form.Select disabled>
<option>Disabled select</option>
</Form.Select>
</Form.Group>
<Form.Group className="mb-3">
<Form.Check type="checkbox" label="Can't check this" disabled />
</Form.Group>
</> < >
< Form.Group className = " mb-3 " >
< Form.Label > Disabled input </ Form.Label >
< Form.Control placeholder = " Disabled input " disabled />
</ Form.Group >
< Form.Group className = " mb-3 " >
< Form.Label > Disabled select menu </ Form.Label >
< Form.Select disabled >
< option > Disabled select </ option >
</ Form.Select >
</ Form.Group >
< Form.Group className = " mb-3 " >
< Form.Check type = " checkbox " label = " Can't check this " disabled />
</ Form.Group >
</ >
Add the disabled
attribute to a <fieldset>
to disable all the controls within.
<Form>
<fieldset disabled>
<Form.Group className="mb-3">
<Form.Label htmlFor="disabledTextInput">Disabled input</Form.Label>
<Form.Control id="disabledTextInput" placeholder="Disabled input" />
</Form.Group>
<Form.Group className="mb-3">
<Form.Label htmlFor="disabledSelect">Disabled select menu</Form.Label>
<Form.Select id="disabledSelect">
<option>Disabled select</option>
</Form.Select>
</Form.Group>
<Form.Group className="mb-3">
<Form.Check
type="checkbox"
id="disabledFieldsetCheck"
label="Can't check this"
/>
</Form.Group>
<Button type="submit">Submit</Button>
</fieldset>
</Form> < Form >
< fieldset disabled >
< Form.Group className = " mb-3 " >
< Form.Label htmlFor = " disabledTextInput " > Disabled input </ Form.Label >
< Form.Control id = " disabledTextInput " placeholder = " Disabled input " />
</ Form.Group >
< Form.Group className = " mb-3 " >
< Form.Label htmlFor = " disabledSelect " > Disabled select menu </ Form.Label >
< Form.Select id = " disabledSelect " >
< option > Disabled select </ option >
</ Form.Select >
</ Form.Group >
< Form.Group className = " mb-3 " >
< Form.Check
type = " checkbox "
id = " disabledFieldsetCheck "
label = " Can't check this "
/>
</ Form.Group >
< Button type = " submit " > Submit </ Button >
</ fieldset >
</ Form >
Caveat with anchors By default, browsers will treat all native form controls (
<input>
,
<select>
and
<button>
elements) inside a
<fieldset disabled>
as disabled, preventing both keyboard and mouse interactions on them. However, if your form also includes
<a ... class="btn btn-*">
elements, these will only be given a style of
pointer-events: none
. As noted in the section about
disabled state for buttons (and specifically in the sub-section for anchor elements), this CSS property is not yet standardized and isnโt fully supported in Internet Explorer 10, and wonโt prevent keyboard users from being able to focus or activate these links. So to be safe, use custom JavaScript to disable such links.
Cross-browser compatibility While Bootstrap will apply these styles in all browsers, Internet Explorer 11 and below donโt fully support the disabled
attribute on a <fieldset>
. Use custom JavaScript to disable the fieldset in these browsers.Provide valuable, actionable feedback to your users with form validation feedback.
For native HTML form validationโavailable in all our supported browsers , the :valid
and :invalid
pseudo selectors are used to apply validation styles as well as display feedback messages.
Bootstrap scopes the :valid
and :invalid
styles to parent .was-validated
class, usually applied to the <Form>
(you can use the validated
prop as a shortcut). Otherwise, any required field without a value shows up as invalid on page load. This way, you may choose when to activate them (typically after form submission is attempted).
Watch out! Browsers provide their own validation UI by default on form
s. You can disable the default UI by adding the HTML noValidate
attribute to your <Form>
or <form>
element.
function FormExample() {
const [validated, setValidated] = useState(false);
const handleSubmit = (event) => {
const form = event.currentTarget;
if (form.checkValidity() === false) {
event.preventDefault();
event.stopPropagation();
}
setValidated(true);
};
return (
<Form noValidate validated={validated} onSubmit={handleSubmit}>
<Row className="mb-3">
<Form.Group as={Col} md="4" controlId="validationCustom01">
<Form.Label>First name</Form.Label>
<Form.Control
required
type="text"
placeholder="First name"
defaultValue="Mark"
/>
<Form.Control.Feedback>Looks good!</Form.Control.Feedback>
</Form.Group>
<Form.Group as={Col} md="4" controlId="validationCustom02">
<Form.Label>Last name</Form.Label>
<Form.Control
required
type="text"
placeholder="Last name"
defaultValue="Otto"
/>
<Form.Control.Feedback>Looks good!</Form.Control.Feedback>
</Form.Group>
<Form.Group as={Col} md="4" controlId="validationCustomUsername">
<Form.Label>Username</Form.Label>
<InputGroup hasValidation>
<InputGroup.Text id="inputGroupPrepend">@</InputGroup.Text>
<Form.Control
type="text"
placeholder="Username"
aria-describedby="inputGroupPrepend"
required
/>
<Form.Control.Feedback type="invalid">
Please choose a username.
</Form.Control.Feedback>
</InputGroup>
</Form.Group>
</Row>
<Row className="mb-3">
<Form.Group as={Col} md="6" controlId="validationCustom03">
<Form.Label>City</Form.Label>
<Form.Control type="text" placeholder="City" required />
<Form.Control.Feedback type="invalid">
Please provide a valid city.
</Form.Control.Feedback>
</Form.Group>
<Form.Group as={Col} md="3" controlId="validationCustom04">
<Form.Label>State</Form.Label>
<Form.Control type="text" placeholder="State" required />
<Form.Control.Feedback type="invalid">
Please provide a valid state.
</Form.Control.Feedback>
</Form.Group>
<Form.Group as={Col} md="3" controlId="validationCustom05">
<Form.Label>Zip</Form.Label>
<Form.Control type="text" placeholder="Zip" required />
<Form.Control.Feedback type="invalid">
Please provide a valid zip.
</Form.Control.Feedback>
</Form.Group>
</Row>
<Form.Group className="mb-3">
<Form.Check
required
label="Agree to terms and conditions"
feedback="You must agree before submitting."
/>
</Form.Group>
<Button type="submit">Submit form</Button>
</Form>
);
}
render(<FormExample />); function FormExample ( ) {
const [ validated , setValidated ] = useState ( false ) ;
const handleSubmit = ( event ) => {
const form = event . currentTarget ;
if ( form . checkValidity ( ) === false ) {
event . preventDefault ( ) ;
event . stopPropagation ( ) ;
}
setValidated ( true ) ;
} ;
return (
< Form noValidate validated = { validated } onSubmit = { handleSubmit } >
< Row className = " mb-3 " >
< Form.Group as = { Col } md = " 4 " controlId = " validationCustom01 " >
< Form.Label > First name </ Form.Label >
< Form.Control
required
type = " text "
placeholder = " First name "
defaultValue = " Mark "
/>
< Form.Control.Feedback > Looks good ! </ Form.Control.Feedback >
</ Form.Group >
< Form.Group as = { Col } md = " 4 " controlId = " validationCustom02 " >
< Form.Label > Last name </ Form.Label >
< Form.Control
required
type = " text "
placeholder = " Last name "
defaultValue = " Otto "
/>
< Form.Control.Feedback > Looks good ! </ Form.Control.Feedback >
</ Form.Group >
< Form.Group as = { Col } md = " 4 " controlId = " validationCustomUsername " >
< Form.Label > Username </ Form.Label >
< InputGroup hasValidation >
< InputGroup.Text id = " inputGroupPrepend " > @ </ InputGroup.Text >
< Form.Control
type = " text "
placeholder = " Username "
aria-describedby = " inputGroupPrepend "
required
/>
< Form.Control.Feedback type = " invalid " >
Please choose a username .
</ Form.Control.Feedback >
</ InputGroup >
</ Form.Group >
</ Row >
< Row className = " mb-3 " >
< Form.Group as = { Col } md = " 6 " controlId = " validationCustom03 " >
< Form.Label > City </ Form.Label >
< Form.Control type = " text " placeholder = " City " required />
< Form.Control.Feedback type = " invalid " >
Please provide a valid city .
</ Form.Control.Feedback >
</ Form.Group >
< Form.Group as = { Col } md = " 3 " controlId = " validationCustom04 " >
< Form.Label > State </ Form.Label >
< Form.Control type = " text " placeholder = " State " required />
< Form.Control.Feedback type = " invalid " >
Please provide a valid state .
</ Form.Control.Feedback >
</ Form.Group >
< Form.Group as = { Col } md = " 3 " controlId = " validationCustom05 " >
< Form.Label > Zip </ Form.Label >
< Form.Control type = " text " placeholder = " Zip " required />
< Form.Control.Feedback type = " invalid " >
Please provide a valid zip .
</ Form.Control.Feedback >
</ Form.Group >
</ Row >
< Form.Group className = " mb-3 " >
< Form.Check
required
label = " Agree to terms and conditions "
feedback = " You must agree before submitting. "
/>
</ Form.Group >
< Button type = " submit " > Submit form </ Button >
</ Form >
) ;
}
render ( < FormExample /> ) ;
It's often beneficial (especially in React) to handle form validation via a library like Formik, or react-formal. In those cases, isValid
and isInvalid
props can be added to form controls to manually apply validation styles. Below is a quick example integrating with Formik .
const { Formik } = formik;
const schema = yup.object().shape({
firstName: yup.string().required(),
lastName: yup.string().required(),
username: yup.string().required(),
city: yup.string().required(),
state: yup.string().required(),
zip: yup.string().required(),
terms: yup.bool().required().oneOf([true], 'Terms must be accepted'),
});
function FormExample() {
return (
<Formik
validationSchema={schema}
onSubmit={console.log}
initialValues={{
firstName: 'Mark',
lastName: 'Otto',
username: '',
city: '',
state: '',
zip: '',
terms: false,
}}
>
{({
handleSubmit,
handleChange,
handleBlur,
values,
touched,
isValid,
errors,
}) => (
<Form noValidate onSubmit={handleSubmit}>
<Row className="mb-3">
<Form.Group as={Col} md="4" controlId="validationFormik01">
<Form.Label>First name</Form.Label>
<Form.Control
type="text"
name="firstName"
value={values.firstName}
onChange={handleChange}
isValid={touched.firstName && !errors.firstName}
/>
<Form.Control.Feedback>Looks good!</Form.Control.Feedback>
</Form.Group>
<Form.Group as={Col} md="4" controlId="validationFormik02">
<Form.Label>Last name</Form.Label>
<Form.Control
type="text"
name="lastName"
value={values.lastName}
onChange={handleChange}
isValid={touched.lastName && !errors.lastName}
/>
<Form.Control.Feedback>Looks good!</Form.Control.Feedback>
</Form.Group>
<Form.Group as={Col} md="4" controlId="validationFormikUsername">
<Form.Label>Username</Form.Label>
<InputGroup hasValidation>
<InputGroup.Text id="inputGroupPrepend">@</InputGroup.Text>
<Form.Control
type="text"
placeholder="Username"
aria-describedby="inputGroupPrepend"
name="username"
value={values.username}
onChange={handleChange}
isInvalid={!!errors.username}
/>
<Form.Control.Feedback type="invalid">
{errors.username}
</Form.Control.Feedback>
</InputGroup>
</Form.Group>
</Row>
<Row className="mb-3">
<Form.Group as={Col} md="6" controlId="validationFormik03">
<Form.Label>City</Form.Label>
<Form.Control
type="text"
placeholder="City"
name="city"
value={values.city}
onChange={handleChange}
isInvalid={!!errors.city}
/>
<Form.Control.Feedback type="invalid">
{errors.city}
</Form.Control.Feedback>
</Form.Group>
<Form.Group as={Col} md="3" controlId="validationFormik04">
<Form.Label>State</Form.Label>
<Form.Control
type="text"
placeholder="State"
name="state"
value={values.state}
onChange={handleChange}
isInvalid={!!errors.state}
/>
<Form.Control.Feedback type="invalid">
{errors.state}
</Form.Control.Feedback>
</Form.Group>
<Form.Group as={Col} md="3" controlId="validationFormik05">
<Form.Label>Zip</Form.Label>
<Form.Control
type="text"
placeholder="Zip"
name="zip"
value={values.zip}
onChange={handleChange}
isInvalid={!!errors.zip}
/>
<Form.Control.Feedback type="invalid">
{errors.zip}
</Form.Control.Feedback>
</Form.Group>
</Row>
<Form.Group className="mb-3">
<Form.Check
required
name="terms"
label="Agree to terms and conditions"
onChange={handleChange}
isInvalid={!!errors.terms}
feedback={errors.terms}
id="validationFormik0"
/>
</Form.Group>
<Button type="submit">Submit form</Button>
</Form>
)}
</Formik>
);
}
render(<FormExample />); const { Formik } = formik ;
const schema = yup . object ( ) . shape ( {
firstName : yup . string ( ) . required ( ) ,
lastName : yup . string ( ) . required ( ) ,
username : yup . string ( ) . required ( ) ,
city : yup . string ( ) . required ( ) ,
state : yup . string ( ) . required ( ) ,
zip : yup . string ( ) . required ( ) ,
terms : yup . bool ( ) . required ( ) . oneOf ( [ true ] , 'Terms must be accepted' ) ,
} ) ;
function FormExample ( ) {
return (
< Formik
validationSchema = { schema }
onSubmit = { console . log }
initialValues = { {
firstName : 'Mark' ,
lastName : 'Otto' ,
username : '' ,
city : '' ,
state : '' ,
zip : '' ,
terms : false ,
} }
>
{ ( {
handleSubmit ,
handleChange ,
handleBlur ,
values ,
touched ,
isValid ,
errors ,
} ) => (
< Form noValidate onSubmit = { handleSubmit } >
< Row className = " mb-3 " >
< Form.Group as = { Col } md = " 4 " controlId = " validationFormik01 " >
< Form.Label > First name </ Form.Label >
< Form.Control
type = " text "
name = " firstName "
value = { values . firstName }
onChange = { handleChange }
isValid = { touched . firstName && ! errors . firstName }
/>
< Form.Control.Feedback > Looks good ! </ Form.Control.Feedback >
</ Form.Group >
< Form.Group as = { Col } md = " 4 " controlId = " validationFormik02 " >
< Form.Label > Last name </ Form.Label >
< Form.Control
type = " text "
name = " lastName "
value = { values . lastName }
onChange = { handleChange }
isValid = { touched . lastName && ! errors . lastName }
/>
< Form.Control.Feedback > Looks good ! </ Form.Control.Feedback >
</ Form.Group >
< Form.Group as = { Col } md = " 4 " controlId = " validationFormikUsername " >
< Form.Label > Username </ Form.Label >
< InputGroup hasValidation >
< InputGroup.Text id = " inputGroupPrepend " > @ </ InputGroup.Text >
< Form.Control
type = " text "
placeholder = " Username "
aria-describedby = " inputGroupPrepend "
name = " username "
value = { values . username }
onChange = { handleChange }
isInvalid = { ! ! errors . username }
/>
< Form.Control.Feedback type = " invalid " >
{ errors . username }
</ Form.Control.Feedback >
</ InputGroup >
</ Form.Group >
</ Row >
< Row className = " mb-3 " >
< Form.Group as = { Col } md = " 6 " controlId = " validationFormik03 " >
< Form.Label > City </ Form.Label >
< Form.Control
type = " text "
placeholder = " City "
name = " city "
value = { values . city }
onChange = { handleChange }
isInvalid = { ! ! errors . city }
/>
< Form.Control.Feedback type = " invalid " >
{ errors . city }
</ Form.Control.Feedback >
</ Form.Group >
< Form.Group as = { Col } md = " 3 " controlId = " validationFormik04 " >
< Form.Label > State </ Form.Label >
< Form.Control
type = " text "
placeholder = " State "
name = " state "
value = { values . state }
onChange = { handleChange }
isInvalid = { ! ! errors . state }
/>
< Form.Control.Feedback type = " invalid " >
{ errors . state }
</ Form.Control.Feedback >
</ Form.Group >
< Form.Group as = { Col } md = " 3 " controlId = " validationFormik05 " >
< Form.Label > Zip </ Form.Label >
< Form.Control
type = " text "
placeholder = " Zip "
name = " zip "
value = { values . zip }
onChange = { handleChange }
isInvalid = { ! ! errors . zip }
/>
< Form.Control.Feedback type = " invalid " >
{ errors . zip }
</ Form.Control.Feedback >
</ Form.Group >
</ Row >
< Form.Group className = " mb-3 " >
< Form.Check
required
name = " terms "
label = " Agree to terms and conditions "
onChange = { handleChange }
isInvalid = { ! ! errors . terms }
feedback = { errors . terms }
id = " validationFormik0 "
/>
</ Form.Group >
< Button type = " submit " > Submit form </ Button >
</ Form >
) }
</ Formik >
) ;
}
render ( < FormExample /> ) ;
If your form layout allows it, you can use the tooltip
prop to display validation feedback in a styled tooltip. Be sure to have a parent with position: relative
on it for tooltip positioning. In the example below, our column classes have this already, but your project may require an alternative setup.
const { Formik } = formik;
const schema = yup.object().shape({
firstName: yup.string().required(),
lastName: yup.string().required(),
username: yup.string().required(),
city: yup.string().required(),
state: yup.string().required(),
zip: yup.string().required(),
file: yup.mixed().required(),
terms: yup.bool().required().oneOf([true], 'terms must be accepted'),
});
function FormExample() {
return (
<Formik
validationSchema={schema}
onSubmit={console.log}
initialValues={{
firstName: 'Mark',
lastName: 'Otto',
username: '',
city: '',
state: '',
zip: '',
file: null,
terms: false,
}}
>
{({
handleSubmit,
handleChange,
handleBlur,
values,
touched,
isValid,
errors,
}) => (
<Form noValidate onSubmit={handleSubmit}>
<Row className="mb-3">
<Form.Group
as={Col}
md="4"
controlId="validationFormik101"
className="position-relative"
>
<Form.Label>First name</Form.Label>
<Form.Control
type="text"
name="firstName"
value={values.firstName}
onChange={handleChange}
isValid={touched.firstName && !errors.firstName}
/>
<Form.Control.Feedback tooltip>Looks good!</Form.Control.Feedback>
</Form.Group>
<Form.Group
as={Col}
md="4"
controlId="validationFormik102"
className="position-relative"
>
<Form.Label>Last name</Form.Label>
<Form.Control
type="text"
name="lastName"
value={values.lastName}
onChange={handleChange}
isValid={touched.lastName && !errors.lastName}
/>
<Form.Control.Feedback tooltip>Looks good!</Form.Control.Feedback>
</Form.Group>
<Form.Group as={Col} md="4" controlId="validationFormikUsername2">
<Form.Label>Username</Form.Label>
<InputGroup hasValidation>
<InputGroup.Text id="inputGroupPrepend">@</InputGroup.Text>
<Form.Control
type="text"
placeholder="Username"
aria-describedby="inputGroupPrepend"
name="username"
value={values.username}
onChange={handleChange}
isInvalid={!!errors.username}
/>
<Form.Control.Feedback type="invalid" tooltip>
{errors.username}
</Form.Control.Feedback>
</InputGroup>
</Form.Group>
</Row>
<Row className="mb-3">
<Form.Group
as={Col}
md="6"
controlId="validationFormik103"
className="position-relative"
>
<Form.Label>City</Form.Label>
<Form.Control
type="text"
placeholder="City"
name="city"
value={values.city}
onChange={handleChange}
isInvalid={!!errors.city}
/>
<Form.Control.Feedback type="invalid" tooltip>
{errors.city}
</Form.Control.Feedback>
</Form.Group>
<Form.Group
as={Col}
md="3"
controlId="validationFormik104"
className="position-relative"
>
<Form.Label>State</Form.Label>
<Form.Control
type="text"
placeholder="State"
name="state"
value={values.state}
onChange={handleChange}
isInvalid={!!errors.state}
/>
<Form.Control.Feedback type="invalid" tooltip>
{errors.state}
</Form.Control.Feedback>
</Form.Group>
<Form.Group
as={Col}
md="3"
controlId="validationFormik105"
className="position-relative"
>
<Form.Label>Zip</Form.Label>
<Form.Control
type="text"
placeholder="Zip"
name="zip"
value={values.zip}
onChange={handleChange}
isInvalid={!!errors.zip}
/>
<Form.Control.Feedback type="invalid" tooltip>
{errors.zip}
</Form.Control.Feedback>
</Form.Group>
</Row>
<Form.Group className="position-relative mb-3">
<Form.Label>File</Form.Label>
<Form.Control
type="file"
required
name="file"
onChange={handleChange}
isInvalid={!!errors.file}
/>
<Form.Control.Feedback type="invalid" tooltip>
{errors.file}
</Form.Control.Feedback>
</Form.Group>
<Form.Group className="position-relative mb-3">
<Form.Check
required
name="terms"
label="Agree to terms and conditions"
onChange={handleChange}
isInvalid={!!errors.terms}
feedback={errors.terms}
id="validationFormik106"
feedbackTooltip
/>
</Form.Group>
<Button type="submit">Submit form</Button>
</Form>
)}
</Formik>
);
}
render(<FormExample />); const { Formik } = formik ;
const schema = yup . object ( ) . shape ( {
firstName : yup . string ( ) . required ( ) ,
lastName : yup . string ( ) . required ( ) ,
username : yup . string ( ) . required ( ) ,
city : yup . string ( ) . required ( ) ,
state : yup . string ( ) . required ( ) ,
zip : yup . string ( ) . required ( ) ,
file : yup . mixed ( ) . required ( ) ,
terms : yup . bool ( ) . required ( ) . oneOf ( [ true ] , 'terms must be accepted' ) ,
} ) ;
function FormExample ( ) {
return (
< Formik
validationSchema = { schema }
onSubmit = { console . log }
initialValues = { {
firstName : 'Mark' ,
lastName : 'Otto' ,
username : '' ,
city : '' ,
state : '' ,
zip : '' ,
file : null ,
terms : false ,
} }
>
{ ( {
handleSubmit ,
handleChange ,
handleBlur ,
values ,
touched ,
isValid ,
errors ,
} ) => (
< Form noValidate onSubmit = { handleSubmit } >
< Row className = " mb-3 " >
< Form.Group
as = { Col }
md = " 4 "
controlId = " validationFormik101 "
className = " position-relative "
>
< Form.Label > First name </ Form.Label >
< Form.Control
type = " text "
name = " firstName "
value = { values . firstName }
onChange = { handleChange }
isValid = { touched . firstName && ! errors . firstName }
/>
< Form.Control.Feedback tooltip > Looks good ! </ Form.Control.Feedback >
</ Form.Group >
< Form.Group
as = { Col }
md = " 4 "
controlId = " validationFormik102 "
className = " position-relative "
>
< Form.Label > Last name </ Form.Label >
< Form.Control
type = " text "
name = " lastName "
value = { values . lastName }
onChange = { handleChange }
isValid = { touched . lastName && ! errors . lastName }
/>
< Form.Control.Feedback tooltip > Looks good ! </ Form.Control.Feedback >
</ Form.Group >
< Form.Group as = { Col } md = " 4 " controlId = " validationFormikUsername2 " >
< Form.Label > Username </ Form.Label >
< InputGroup hasValidation >
< InputGroup.Text id = " inputGroupPrepend " > @ </ InputGroup.Text >
< Form.Control
type = " text "
placeholder = " Username "
aria-describedby = " inputGroupPrepend "
name = " username "
value = { values . username }
onChange = { handleChange }
isInvalid = { ! ! errors . username }
/>
< Form.Control.Feedback type = " invalid " tooltip >
{ errors . username }
</ Form.Control.Feedback >
</ InputGroup >
</ Form.Group >
</ Row >
< Row className = " mb-3 " >
< Form.Group
as = { Col }
md = " 6 "
controlId = " validationFormik103 "
className = " position-relative "
>
< Form.Label > City </ Form.Label >
< Form.Control
type = " text "
placeholder = " City "
name = " city "
value = { values . city }
onChange = { handleChange }
isInvalid = { ! ! errors . city }
/>
< Form.Control.Feedback type = " invalid " tooltip >
{ errors . city }
</ Form.Control.Feedback >
</ Form.Group >
< Form.Group
as = { Col }
md = " 3 "
controlId = " validationFormik104 "
className = " position-relative "
>
< Form.Label > State </ Form.Label >
< Form.Control
type = " text "
placeholder = " State "
name = " state "
value = { values . state }
onChange = { handleChange }
isInvalid = { ! ! errors . state }
/>
< Form.Control.Feedback type = " invalid " tooltip >
{ errors . state }
</ Form.Control.Feedback >
</ Form.Group >
< Form.Group
as = { Col }
md = " 3 "
controlId = " validationFormik105 "
className = " position-relative "
>
< Form.Label > Zip </ Form.Label >
< Form.Control
type = " text "
placeholder = " Zip "
name = " zip "
value = { values . zip }
onChange = { handleChange }
isInvalid = { ! ! errors . zip }
/>
< Form.Control.Feedback type = " invalid " tooltip >
{ errors . zip }
</ Form.Control.Feedback >
</ Form.Group >
</ Row >
< Form.Group className = " position-relative mb-3 " >
< Form.Label > File </ Form.Label >
< Form.Control
type = " file "
required
name = " file "
onChange = { handleChange }
isInvalid = { ! ! errors . file }
/>
< Form.Control.Feedback type = " invalid " tooltip >
{ errors . file }
</ Form.Control.Feedback >
</ Form.Group >
< Form.Group className = " position-relative mb-3 " >
< Form.Check
required
name = " terms "
label = " Agree to terms and conditions "
onChange = { handleChange }
isInvalid = { ! ! errors . terms }
feedback = { errors . terms }
id = " validationFormik106 "
feedbackTooltip
/>
</ Form.Group >
< Button type = " submit " > Submit form </ Button >
</ Form >
) }
</ Formik >
) ;
}
render ( < FormExample /> ) ;
To properly show rounded corners in an <InputGroup>
with validation, the <InputGroup>
requires the hasValidation
prop.
<InputGroup hasValidation>
<InputGroup.Text>@</InputGroup.Text>
<Form.Control type="text" required isInvalid />
<Form.Control.Feedback type="invalid">
Please choose a username.
</Form.Control.Feedback>
</InputGroup> < InputGroup hasValidation >
< InputGroup.Text > @ </ InputGroup.Text >
< Form.Control type = " text " required isInvalid />
< Form.Control.Feedback type = " invalid " >
Please choose a username .
</ Form.Control.Feedback >
</ InputGroup >
For even more customization and cross browser consistency, use our completely custom form elements to replace the browser defaults. Theyโre built on top of semantic and accessible markup, so theyโre solid replacements for any default form control.
A switch has the markup of a custom checkbox but uses type="switch"
to render a toggle switch. Switches also support the same customizable children as <FormCheck>
.
<Form>
<Form.Check
type="switch"
id="custom-switch"
label="Check this switch"
/>
<Form.Check
disabled
type="switch"
label="disabled switch"
id="disabled-custom-switch"
/>
</Form> < Form >
< Form.Check
type = " switch "
id = " custom-switch "
label = " Check this switch "
/>
< Form.Check
disabled
type = " switch "
label = " disabled switch "
id = " disabled-custom-switch "
/>
</ Form >
You can also use the <Form.Switch>
alias which encapsulates the above, in a very small component wrapper.
import Form from 'react-bootstrap/Form'
Copy import code for the Form component Name Type Default Description ref ReactRef
The Form ref
will be forwarded to the underlying element,
which means, unless it's rendered as
a composite component,
it will be a DOM node, when resolved.
as elementType
<form>
You can use a custom element type for this component.
validated boolean
Mark a form as having been validated. Setting it to true
will
toggle any validation styles on the forms elements.
import Form from 'react-bootstrap/Form'
Copy import code for the Form component Name Type Default Description as elementType
<div>
You can use a custom element type for this component.
bsPrefix required string
'form-floating'
Change the underlying component CSS base class name and modifier class names prefix. This is an escape hatch for working with heavily customized bootstrap css.
import Form from 'react-bootstrap/Form'
Copy import code for the Form component Name Type Default Description ref ReactRef
The FormGroup ref
will be forwarded to the underlying element.
Unless the FormGroup is rendered as
a composite component,
it will be a DOM node, when resolved.
as elementType
<div>
You can use a custom element type for this component.
controlId string
Sets id
on <FormControl>
and htmlFor
on <FormGroup.Label>
.
import Form from 'react-bootstrap/Form'
Copy import code for the Form component Name Type Default Description ref ReactRef
The FormLabel ref
will be forwarded to the underlying element.
Unless the FormLabel is rendered as
a composite component,
it will be a DOM node, when resolved.
as elementType
<label>
Set a custom element for this component
column boolean | 'sm'
| 'lg'
false
Renders the FormLabel as a <Col>
component (accepting all the same props),
as well as adding additional styling for horizontal forms.
htmlFor string
Uses controlId
from <FormGroup>
if not explicitly specified.
visuallyHidden boolean
false
Hides the label visually while still allowing it to be
read by assistive technologies.
bsPrefix string
'form-label'
Change the underlying component CSS base class name and modifier class names prefix. This is an escape hatch for working with heavily customized bootstrap css.
import Form from 'react-bootstrap/Form'
Copy import code for the Form component Name Type Default Description ref ReactRef
The FormText ref
will be forwarded to the underlying element.
Unless the FormText is rendered as
a composite component,
it will be a DOM node, when resolved.
as elementType
<small>
You can use a custom element type for this component.
muted boolean
A convenience prop for add the text-muted
class,
since it's so commonly used here.
bsPrefix string
'form-text'
Change the underlying component CSS base class name and modifier class names prefix. This is an escape hatch for working with heavily customized bootstrap css.
import Form from 'react-bootstrap/Form'
Copy import code for the Form component Name Type Default Description ref ReactRef
The FormControl ref
will be forwarded to the underlying input element,
which means unless as
is a composite component,
it will be a DOM node, when resolved.
as 'input' | 'textarea' | elementType
'input'
The underlying HTML element to use when rendering the FormControl.
disabled boolean
Make the control disabled
htmlSize number
The size attribute of the underlying HTML element.
Specifies the visible width in characters if as
is 'input'
.
id string
Uses controlId
from <FormGroup>
if not explicitly specified.
isInvalid boolean
false
Add "invalid" validation styles to the control and accompanying label
isValid boolean
false
Add "valid" validation styles to the control
onChange function
A callback fired when the value
prop changes
plaintext boolean
Render the input as plain text. Generally used along side readOnly
.
readOnly boolean
Make the control readonly
size 'sm'
| 'lg'
type string
The HTML input type
, which is only relevant if as
is 'input'
(the default).
value string | arrayOf | number
controlled by: onChange
, initial prop: defaultValue
The value
attribute of underlying input
bsPrefix string
{'form-control'}
Change the underlying component CSS base class name and modifier class names prefix. This is an escape hatch for working with heavily customized bootstrap css.
import FormControl from 'react-bootstrap/FormControl'
Copy import code for the FormControl component Name Type Default Description as elementType
<div>
You can use a custom element type for this component.
tooltip boolean
false
Display feedback as a tooltip.
type 'valid'
| 'invalid'
'valid'
Specify whether the feedback is for valid or invalid fields
import Form from 'react-bootstrap/Form'
Copy import code for the Form component Name Type Default Description ref ReactRef
The FormCheck ref
will be forwarded to the underlying input element,
which means it will be a DOM node, when resolved.
as 'input' | elementType
'input'
The underlying HTML element to use when rendering the FormCheck.
children node
Provide a function child to manually handle the layout of the FormCheck's inner components.
< FormCheck >
< FormCheck.Input isInvalid type = { radio} />
< FormCheck.Label > Allow us to contact you? </ FormCheck.Label >
< Feedback type = " invalid" > Yo this is required </ Feedback >
</ FormCheck >
disabled boolean
false
feedback node
A message to display when the input is in a validation state
feedbackTooltip boolean
false
Display feedback as a tooltip.
id string
A HTML id attribute, necessary for proper form accessibility.
An id is recommended for allowing label clicks to toggle the check control.
This is required when type="switch"
due to how they are rendered.
inline boolean
false
Groups controls horizontally with other FormCheck
s.
isInvalid boolean
false
Manually style the input as invalid
isValid boolean
false
Manually style the input as valid
label node
title string
''
title
attribute for the underlying FormCheckLabel
.
type 'radio'
| 'checkbox'
| 'switch'
'checkbox'
bsPrefix string
'form-check'
Change the underlying component CSS base class name and modifier class names prefix. This is an escape hatch for working with heavily customized bootstrap css.
bsSwitchPrefix string
'form-switch'
bsPrefix override for the base switch class.
import FormCheck from 'react-bootstrap/FormCheck'
Copy import code for the FormCheck component Name Type Default Description as 'input' | elementType
'input'
The underlying HTML element to use when rendering the FormCheckInput.
id string
A HTML id attribute, necessary for proper form accessibility.
isInvalid boolean
false
Manually style the input as invalid
isValid boolean
false
Manually style the input as valid
type 'radio'
| 'checkbox'
'checkbox'
bsPrefix string
'form-check-input'
Change the underlying component CSS base class name and modifier class names prefix. This is an escape hatch for working with heavily customized bootstrap css.
import FormCheck from 'react-bootstrap/FormCheck'
Copy import code for the FormCheck component Name Type Default Description htmlFor string
The HTML for attribute for associating the label with an input
bsPrefix string
'form-check-label'
Change the underlying component CSS base class name and modifier class names prefix. This is an escape hatch for working with heavily customized bootstrap css.
import Form from 'react-bootstrap/Form'
Copy import code for the Form component Name Type Default Description disabled boolean
Make the control disabled
onChange function
A callback fired when the value
prop changes
value string | arrayOf | number
controlled by: onChange
, initial prop: defaultValue
The value
attribute of underlying input
bsPrefix string
{'form-range'}
Change the underlying component CSS base class name and modifier class names prefix. This is an escape hatch for working with heavily customized bootstrap css.
import Form from 'react-bootstrap/Form'
Copy import code for the Form component Name Type Default Description disabled boolean
Make the control disabled
htmlSize number
The size attribute of the underlying HTML element.
Specifies the number of visible options.
isInvalid boolean
false
Add "invalid" validation styles to the control and accompanying label
isValid boolean
false
Add "valid" validation styles to the control
onChange function
A callback fired when the value
prop changes
size 'sm'
| 'lg'
value string | arrayOf | number
controlled by: onChange
, initial prop: defaultValue
The value
attribute of underlying input
bsPrefix string
{'form-select'}
Change the underlying component CSS base class name and modifier class names prefix. This is an escape hatch for working with heavily customized bootstrap css.
import FloatingLabel from 'react-bootstrap/FloatingLabel'
Copy import code for the FloatingLabel component Name Type Default Description as elementType
You can use a custom element type for this component.
controlId string
Sets id
on <FormControl>
and htmlFor
on <label>
.
label required node