The Material UI Switch component is has the same functionality as a checkbox while providing a more tangible look and feel. We can customize anything we want with the Switch, including the color, size, track and thumb.
Here’s the Switch example that we will create. I will include DOM screenshots to show what classes are needed for nested selectors.

The Resources section has full code and related article links.
Material UI Switch Icon and DOM
The MUI Switch component doesn’t actually use an icon. It is instead created with a “track” and a “thumb”, both of which are styled spans.
For example, the thumb is a span with 50% border radius.

If you need to change the look of the Switch, the MuiSwitch-switchBase
, MuiSwitch-thumb
, and MuiSwitch-track
are important classes to target with selectors.
Material UI Switch Thumb Color
The thumb can be styled by targeting either the specific thumb class or the root class MuiSwitch-switchBase
.
MUI adds a class called Mui-checked
when the Switch is checked. I targeted this class to style the thumb only when it was checked.
"& .MuiSwitch-switchBase.Mui-checked": {
color: "green"
}
Material UI Switch Track Color
The Switch track was more challenging to target than the Switch thumb.
There were two quirks:
- I needed to target an invisible
Mui-checked+
class. This was not visible in the DOM but was visible in the dev tools styles area - I also needed to target MuiSwitch-track and MuiSwitch-switchBase.
Here’s a screenshot of the invisible DOM class:

Here’s example code for setting the track color. Notice I had to target background color.
"& .MuiSwitch-switchBase.Mui-checked+.MuiSwitch-track": {
backgroundColor: 'lightgreen'
}
Material UI Switch Hover
Hover worked well on the Switch. I targeted the hover pseudo-class at the root level, and then targeted the nested MuiSwitch-switchBase
class.
This applies a hover color only to the thumb. It also likely tries to apply to the track, but the track needs a more specific selector. Also, strangely, in the screenshot in the last section the track does not seem to have MuiSwitch-switchBase
in the DOM but it has it in the styles section as part of a selector.
"&:hover .MuiSwitch-switchBase": {
color: 'brown'
}
Material UI Switch onChange and Value
The Switch onChange
behaves exactly like the Checkbox. Here we see the change handler take the new checked
field from the handler and apply it to the state.
Be careful not to use the event.target.value
field. In Checkboxes and Switches, this only has a value of on
. Even when the Switch is not selected, the value
is still on
.
const [state, setState] = React.useState({
pickles: true,
mustard: false,
salt: false
});
const handleChange = (event: React.ChangeEvent<HTMLInputElement>) => {
setState({
...state,
[event.target.name]: event.target.checked
});
console.log(event.target.value); //don't use this
}
Resources
Related Posts:
- Awesome MUI Checkbox Examples: Color, Size, Labels, More
- Every Material-UI Form Component Explained (MUI v5)
- The Ultimate Guide to Material-UI FormControl: 3 Examples
- Custom FormControlLabel Examples: Font Size, Width, Error
Full React code for this tutorial:
import * as React from "react";
import FormLabel from "@mui/material/FormLabel";
import FormControl from "@mui/material/FormControl";
import FormGroup from "@mui/material/FormGroup";
import FormControlLabel from "@mui/material/FormControlLabel";
import Switch from "@mui/material/Switch";
import Paper from "@mui/material/Paper";
const switchStyle = {
borderRadius: 2,
"& .MuiSwitch-switchBase.Mui-checked": {
color: "green"
},
"& .MuiSwitch-switchBase.Mui-checked+.MuiSwitch-track": {
backgroundColor: 'lightgreen'
},
"&:hover .MuiSwitch-switchBase": {
color: 'brown'
},
}
export default function SwitchForm() {
const [state, setState] = React.useState({
pickles: true,
mustard: false,
salt: false
});
const handleChange = (event: React.ChangeEvent<HTMLInputElement>) => {
setState({
...state,
[event.target.name]: event.target.checked
});
console.log(event.target.value);
}
const { pickles, mustard, salt } = state;
return (
<form>
<Paper sx={{ padding: 4, display: 'flex', justifyContent: 'center' }}>
<FormControl
component="fieldset"
sx={{ m: 3 }}
variant="standard"
>
<FormLabel component="legend">Choose your lunch order.</FormLabel>
<FormGroup>
<FormControlLabel
control={
<Switch
checked={pickles}
onChange={handleChange}
name="pickles"
sx={switchStyle}
/>
}
label="Pickles"
/>
<FormControlLabel
control={
<Switch
checked={mustard}
onChange={handleChange}
name="mustard"
sx={switchStyle}
/>
}
label="Mustard"
/>
<FormControlLabel
control={
<Switch
checked={salt}
onChange={handleChange}
name="salt"
sx={switchStyle}
/>
}
label="Salt"
/>
</FormGroup>
</FormControl>
</Paper>
</form>
);
}
The FormControlLabels can also be used to wrap Radio components.