10
头图
Welcome to my public account: front-end detective

How to customize the style of the native input range sliding input bar has always been a hurdle in my heart. Under normal circumstances, it can be easily beautified to this extent

image

Why is it easy? Because these are all corresponding pseudo-elements that can be modified

::-webkit-slider-container {
  /*可以修改容器的若干样式*/
}
::-webkit-slider-runnable-track {
  /*可以修改轨道的若干样式*/
}
::-webkit-slider-thumb {
  /*可以修改滑块的若干样式*/
}

However, there is no style that has been slid over. If you want to define the following style, pure CSS may not be able to achieve it

image

Note: Firefox has a separate pseudo-class that can be modified, this article discusses the Chrome implementation

1. My realization idea

Since there is no special pseudo-element to modify the color of the part that has been slid over, and only the slider is movable, is it possible to get started with the slider?

Suppose there is a rectangle on the left side of the slider, which follows the slider,

Kapture 2022-02-28 at 19.27.51

When this rectangle is long enough, it can completely cover the track on the left. In the visible range, can it indicate that the part on the left has slid over? The illustration is as follows (translucent on the left means outside the slider)

Kapture 2022-02-28 at 17.33.24

Tried the pseudo element idea, like this

::-webkit-slider-thumb::after{
  /*本想绘制一个足够长的矩形*/
}

Unfortunately, pseudo elements cannot be generated again in pseudo elements.

So, how to draw a rectangle outside the element?

2. Drawing graphics outside the element through border-image

What are some ways to draw graphics outside of elements? After thinking about it, there are box-shadow and outline , but it doesn't seem to be suitable for this situation. What we need to draw is a rectangle with a controllable size, and neither of these two methods can control the shape very well. Is there any other way?

There really is! I just saw an article by Mr. Zhang Xinxu two days ago: 's underestimated border-image property , one of which is that builds the image outside the element, and does not occupy any space. Try it now, draw a rectangle with a width of 99vw (enough to cover the slider), the code is 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; /*绘制元素外矩形*/
}

The effect is as follows

Kapture 2022-02-28 at 19.31.06

A few things to note:

  1. For border-image to take effect, 0622ea8bb774b7 must be specified, and border is set border: 1px solid transparent;
  2. The rectangle is drawn with a linear gradient linear-gradient(#f44336,#f44336)
  3. In border-image, 8 20 8 0 represents border-image-width , the distance from the top, right, bottom, and left. Since the size of the slider itself is 20 * 20, it can be determined that the height is 4 (20 - 8- 8), and the position is the slider itself far left (20 from the right)
  4. In border-image, 0 0 0 99vw represents the extension size of border-image-outset , which refers to the distance of extending 99vw to the left

Next, you can hide the outer part through overflow:hidden

::-webkit-slider-container {
    /*其他样式*/
    overflow: hidden;
}

Kapture 2022-02-28 at 19.34.22

The full code can be accessed at: input range (codepen.io)

The complete code is attached below (codepen seems to be unstable recently)

[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;
}

Third, there are still some limitations

The above implementation cost is actually very low. Compared with the conventional implementation, only one line is added for drawing rectangles outside the element.

border-image: linear-gradient(#f44336,#f44336) 0 fill / 8 20 8 0 / 0px 0px 0 2000px;

However, because the excess part is cut out by way of over-hidden, the edge of the slider is "one size fits all", so if the slider is required to have rounded corners, this implementation will not work

image-20220303225610880

If you have any good ideas, please leave a message to discuss

Fourth, a brief summary

Regarding the attribute border-image-outset , in fact, I have seen it on MDN before, but it is only a simple understanding, but I still feel it is very tasteless. Now it seems that these attributes are not useless, but I have not encountered a suitable application scenario. Here is a brief summary:

  1. The slider has 3 pseudo elements to customize the container, track, slider
  2. Pseudo-elements can no longer be nested within pseudo-elements
  3. There are three methods for drawing outside the element: box-shadow, outline, border-image
  4. border-image can use any image format, including CSS gradients
  5. This solution cannot achieve rounded corners

Of course, these ideas are just "home remedies". For example, Firefox fully supports custom styles. Unfortunately, the desktop side is still the world of Chrome, so we can only slowly look forward to the later updates of Chrome. Finally, if you think it's good and helpful to you, please like, bookmark, and forward ❤❤❤

Welcome to my public account: front-end detective

XboxYan
18.1k 声望14.1k 粉丝