` to create our custom control. Structurally, this is the same approach as our default `.form-check`.
We use the sibling selector (`~`) for all our `
` states—like `:checked`—to properly style our custom form indicator. When combined with the `.custom-control-label` class, we can also style the text for each item based on the `
`'s state.
We hide the default `
` with `opacity` and use the `.custom-control-label` to build a new custom form indicator in its place with `::before` and `::after`. Unfortunately we can't build a custom one from just the `
` because CSS's `content` doesn't work on that element.
In the checked states, we use **embedded SVG icons** from [Open Iconic](https://github.com/iconic/open-iconic). This provides us the best control for styling and positioning across browsers and devices.
#### Checkboxes
{{< example >}}
Check this custom checkbox
{{< /example >}}
Custom checkboxes can also utilize the `:indeterminate` pseudo class when manually set via JavaScript (there is no available HTML attribute for specifying it).
{{< highlight js >}}
var checkbox = document.querySelector('.your-checkbox')
checkbox.indeterminate = true
{{< /highlight >}}
#### Radios
{{< example >}}
Toggle this custom radio
Or toggle this other custom radio
{{< /example >}}
#### Inline
{{< example >}}
Toggle this custom radio
Or toggle this other custom radio
{{< /example >}}
#### Disabled
Custom checkboxes and radios can also be disabled. Add the `disabled` boolean attribute to the `
` and the custom indicator and label description will be automatically styled.
{{< example >}}
Check this custom checkbox
Toggle this custom radio
{{< /example >}}
### Switches
A switch has the markup of a custom checkbox but uses the `.custom-switch` class to render a toggle switch. Switches also support the `disabled` attribute.
{{< example >}}
Toggle this switch element
Disabled switch element
{{< /example >}}
### Select menu
Custom `
` menus need only a custom class, `.custom-select` to trigger the custom styles. Custom styles are limited to the ``'s initial appearance and cannot modify the ``s due to browser limitations.
{{< example >}}
Open this select menu
One
Two
Three
{{< /example >}}
You may also choose from small and large custom selects to match our similarly sized text inputs.
{{< example >}}
Open this select menu
One
Two
Three
Open this select menu
One
Two
Three
{{< /example >}}
The `multiple` attribute is also supported:
{{< example >}}
Open this select menu
One
Two
Three
{{< /example >}}
As is the `size` attribute:
{{< example >}}
Open this select menu
One
Two
Three
{{< /example >}}
### Range
Create custom ` ` controls with `.custom-range`. The track (the background) and thumb (the value) are both styled to appear the same across browsers. As only IE and Firefox support "filling" their track from the left or right of the thumb as a means to visually indicate progress, we do not currently support it.
{{< example >}}
Example range
{{< /example >}}
Range inputs have implicit values for `min` and `max`—`0` and `100`, respectively. You may specify new values for those using the `min` and `max` attributes.
{{< example >}}
Example range
{{< /example >}}
By default, range inputs "snap" to integer values. To change this, you can specify a `step` value. In the example below, we double the number of steps by using `step="0.5"`.
{{< example >}}
Example range
{{< /example >}}
### File browser
{{< callout info >}}
The recommended plugin to animate custom file input: [bs-custom-file-input](https://www.npmjs.com/package/bs-custom-file-input), that's what we are using currently here in our docs.
{{< /callout >}}
The file input is the most gnarly of the bunch and requires additional JavaScript if you'd like to hook them up with functional *Choose file...* and selected file name text.
{{< example >}}
Choose file...
Browse
{{< /example >}}
Longer placeholder text is truncated and an ellipsis is added when there's not enough space.
{{< example >}}
Lorem ipsum posuere consectetur est at lobortis nulla vitae elit libero a pharetra augue fusce dapibus tellus ac cursus commodo tortor mauris condimentum nibh ut fermentum massa justo sit amet risus cras mattis consectetur purus sit amet fermentum
Browse
{{< /example >}}
We hide the default file ` ` via `opacity` and instead style the ``. The button is generated and positioned with `::after`. Lastly, we declare a `width` and `height` on the ` ` for proper spacing for surrounding content.