Reputation: 8122
https://codesandbox.io/s/slider-example-ev250?file=/src/App.js
I am attempting to create an <input type='range'>
Styled Component that has a custom appearance:
const SliderInput = styled.input.attrs((props) => {
const val = Number(props.value ?? 0);
const min = Number(props.min ?? 0);
const max = Number(props.max ?? 1);
const breakpoint = 100 * ((val - min) / (max - min));
return {
style: {
background: `linear-gradient(to right, ${props.color}, ${props.color} ${breakpoint}%, white ${breakpoint}%, white 100%)`,
border: `solid 1px ${props.color}`
}
};
})`
-webkit-appearance: none;
width: 200px;
height: 8px;
border-radius: 12px;
&::-webkit-slider-thumb {
-webkit-appearance: none;
background: ${(props) => props.color};
border: 2px solid white;
border-radius: 50%;
width: 16px;
height: 16px;
}
&:hover {
cursor: grab;
}
`;
The issue I am facing is that the background color of the thumb slider changes too frequently, which causes lagging and I see the following warning:
Over 200 classes were generated for component styled.input with the id of "sc-dlnjwi".
Consider using the attrs method, together with a style object for frequently changed styles.
Example:
const Component = styled.div.attrs(props => ({
style: {
background: props.background,
},
}))`width: 100%;`
How can this be achieved with pseudo-selectors like ::-webkit-slider-thumb
?
I've tried:
style: {
background: `linear-gradient(to right, ${props.color}, ${props.color} ${breakpoint}%, white ${breakpoint}%, white 100%)`,
border: `solid 1px ${props.color}`
"::WebkitSliderThumb": {
background: props.color
}
}
To no avail.
Any suggestions?
Upvotes: 1
Views: 843
Reputation: 2653
It's not possible to style psuedo-selectors using inline styles (see this SO thread for more context). In other words, this isn't possible:
<input type="range" style="::WebkitSliderThumb:background:red" />
That's what styled-components
's .attrs
is doing under the hood, it's just applying inline styles [docs].
The only way to apply styles to psuedo-selectors is to use CSS, and as you've already seen it's not practical to do this with styled-components
. I'd suggest determining a fixed number of slider steps, generating CSS classes for each of those ahead of time (you can use a preprocessor like SASS to do this effeciently), and then just dynamically applying the correct class when the slider's value changes.
Upvotes: 1