` 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 **base64 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
{% capture example %}
Check this custom checkbox
{% endcapture %}
{% include example.html content=example %}
Custom checkboxes can also utilize the `:indeterminate` pseudo class when manually set via JavaScript (there is no available HTML attribute for specifying it).
If you're using jQuery, something like this should suffice:
{% highlight js %}
$('.your-checkbox').prop('indeterminate', true)
{% endhighlight %}
#### Radios
{% capture example %}
Toggle this custom radio
Or toggle this other custom radio
{% endcapture %}
{% include example.html content=example %}
#### Inline
{% capture example %}
Toggle this custom radio
Or toggle this other custom radio
{% endcapture %}
{% include example.html content=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.
{% capture example %}
Check this custom checkbox
Toggle this custom radio
{% endcapture %}
{% include example.html content=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.
{% capture example %}
Open this select menu
One
Two
Three
{% endcapture %}
{% include example.html content=example %}
You may also choose from small and large custom selects to match our similarly sized text inputs.
{% capture example %}
Open this select menu
One
Two
Three
Open this select menu
One
Two
Three
{% endcapture %}
{% include example.html content=example %}
The `multiple` attribute is also supported:
{% capture example %}
Open this select menu
One
Two
Three
{% endcapture %}
{% include example.html content=example %}
As is the `size` attribute:
{% capture example %}
Open this select menu
One
Two
Three
{% endcapture %}
{% include example.html content=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.
{% capture example %}
Example range
{% endcapture %}
{% include example.html content=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.
{% capture example %}
Example range
{% endcapture %}
{% include example.html content=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"`.
{% capture example %}
Example range
{% endcapture %}
{% include example.html content=example %}
### File browser
{% capture callout %}
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.
{% endcapture %}
{% include callout.html content=callout type="info" %}
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.
{% capture example %}
Choose file
{% endcapture %}
{% include example.html content=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.
#### Translating or customizing the strings
The [`:lang()` pseudo-class](https://developer.mozilla.org/en-US/docs/Web/CSS/:lang) is used to allow for translation of the "Browse" text into other languages. Override or add entries to the `$custom-file-text` Sass variable with the relevant [language tag](https://en.wikipedia.org/wiki/IETF_language_tag) and localized strings. The English strings can be customized the same way. For example, here's how one might add a Spanish translation (Spanish's language code is `es`):
{% highlight scss %}
$custom-file-text: (
en: "Browse",
es: "Elegir"
);
{% endhighlight %}
Here's `lang(es)` in action on the custom file input for a Spanish translation:
{% capture example %}
Seleccionar Archivo
{% endcapture %}
{% include example.html content=example %}
You'll need to set the language of your document (or subtree thereof) correctly in order for the correct text to be shown. This can be done using [the `lang` attribute](https://developer.mozilla.org/en-US/docs/Web/HTML/Global_attributes/lang) on the `` element or the [`Content-Language` HTTP header](https://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.12), among other methods.