Public id: Front-end detective
How to customize the style of the native Input range slider has always been a question in my mind. In general, it is easy to beautify to this extent
Why is it easy? Because these are all pseudo-elements that can be modified
::-webkit-slider-container {/* You can modify some of the container styles */} ::-webkit-slider-runnable-track {/* You can modify some of the track styles */} ::-webkit-slider-thumb {/* You can modify several styles of the slider */}Copy the code
However, there is no style that has been slid, if you want to define the following style, simple CSS may not be able to implement
Note: Firefox has a separate pseudo class that can be modified; this article discusses the Chrome implementation
First, my implementation ideas
Since there are no special pseudo-elements that can change the color of the part that has been slid, and only the slider is movable, is it possible to work on the slider?
Let’s say I have a rectangle to the left of the slider that follows the slider,
When the rectangle is long enough to completely cover the track on the left, is it visible that the left part has slipped over? The image is shown below (left semi-transparent shows the outside of the slider)
Tried the idea of pseudo-elements, like this
::-webkit-slider-thumb::after{/* I want to draw a long enough rectangle */}Copy the code
Unfortunately, you can’t reproduce pseudo-elements in pseudo-elements.
So, how do you draw a rectangle outside of an element?
Draw a graph outside the element using border-image
What are some ways to draw outside of an element? After thinking about it, there are box-shadow and outline, but it seems not suitable for this situation. What we need to draw is a controllable rectangle, and neither of these two methods can control the shape well. Is there any other way?
Also is there! I just read an article by Zhang Xinxu two days ago: the undervalued border-image attribute, one of which is to build images outside of elements and not occupy any space. Let’s try and draw a rectangle with a width of 99vw (just enough to cover the slider) as follows
::-webkit-slider-thumb {
-webkit-appearance: none;
appearance: none;
width: 20px;
height: 20px;
border-radius: 50%;
background-color: #f44336;
border: 1px solid transparent;
margin-top: -8px;
border-image: linear-gradient(#f44336.#f44336) 0 fill / 8 20 8 0 / 0 0 0 99vw; /* Draws a rectangle outside the element */
}
Copy the code
Results the following
A few points to note:
- Border-image must be specified for this parameter to take effect
border
, and this is set toborder: 1px solid transparent;
- Rectangles are drawn with a linear gradient
linear-gradient(#f44336,#f44336)
- Border – the image
8 20 8 0
saidborder-image-width
, the distance from top, right, bottom and left. Since the size of the slider itself is 20 * 20, the height can be determined to be 4 (20-8-8), and the position is the leftmost of the slider itself (20 from the right). - Border – the image
0 0 0 99vw
saidborder-image-outset
Expand the size, in this case, to the left99vw
The distance from the
The next step is to hide the outside with Overflow: Hidden
::-webkit-slider-container {/* Other styles */ overflow: hidden; }Copy the code
The full code can be accessed: Input range (codepen.io)
The complete code is attached below (Codepen seems to be a bit unstable lately)
[type="range"] {
-webkit-appearance: none;
appearance: none;
margin: 0;
outline: 0;
background-color: transparent;
width: 500px;
}
[type="range"]::-webkit-slider-runnable-track {
height: 4px;
background: #eee;
}
[type="range" i]::-webkit-slider-container {
height: 20px;
overflow: hidden;
}
[type="range"]::-webkit-slider-thumb {
-webkit-appearance: none;
appearance: none;
width: 20px;
height: 20px;
border-radius: 50%;
background-color: #f44336;
border: 1px solid transparent;
margin-top: -8px;
border-image: linear-gradient(#f44336.#f44336) 0 fill / 8 20 8 0 / 0px 0px 0 2000px;
}
Copy the code
Third, there are some limitations
The above implementation cost is actually very low, compared to the normal implementation basis, only 1 more line for drawing the rectangle outside the element.
border-image: linear-gradient(#f44336.#f44336) 0 fill / 8 20 8 0 / 0px 0px 0 2000px;
Copy the code
However, since the edges of the slider are “one-size-fits-all” by clipping out the extra parts beyond their hiding, this approach is not possible if the slider is required to have rounded corners
If you have any good ideas, please leave a comment
Four, a brief summary
As for the attribute “border-image-outset”, I have seen it on MDN before, but I think it is not very useful but I have not met the suitable application scenarios. Here is a brief summary:
- The slider has three pseudo-elements for customizing containers, tracks, and sliders
- Pseudo-elements can no longer be nested in pseudo-elements
- Outside the element, there are three methods to draw box-shadow, outline and border-image
- Border-image can use images in any format, including CSS gradients
- Rounded corners cannot be achieved in this scheme
Of course, these ideas are only “partial”, like Firefox fully support custom style, unfortunately desktop is still Chrome, can only slowly look forward to Chrome behind the update. Finally, if you think it’s good and helpful, please like, bookmark and retweet ❤❤❤