It doesn’t matter whether you are creating a website or an app – you don’t want to use the default style of a slider. It won’t match any of the modern sexy designs. You could use external libraries like Bootstrap or Foundation but most of the time, you don’t want to install an additional package just for one component. What you actually want to use is an HTML input range element. In this tutorial, we will focus on styling the slider without JavaScript. It will be as simple as possible so you can achieve a really nice effect in a short amount of time.

You may ask what <input type="range"> actually is. It’s an HTML element typically represented by a slider which lets a user specify a numeric value. It consists of two main elements – track and thumb.

Before opening my code editor I always specify the colour theme and design I want to achieve. While looking for the desired colour palette I search for inspiration on different websites, for example, ColorHunt. To create a small minimalistic slider in sunset colours we will use palette no. 11833. We are going to apply the gradient from pink to dark blue for a slider’s track and the orange colour for the thumb.

After establishing the colours it is time to write some code. For the tutorial purpose and to make code more explicit we will style pure HTML tag instead of a class. To apply own style to a component we need to set the none value to appearance property. Its default state is responsible for displaying the platform-native styling of a component based on the user’s operating system’s theme. To limit the width of the element we will set it to 200px. In the end, whenever I tested the code in different browsers it appeared that only on Firefox slider’s background was still white. Setting background-color as transparent will fix this problem. Let’s see the code below:

input[type="range"] {
  -webkit-appearance: none;
  -moz-appearance: none;
  appearance: none;
  width: 200px;
  background-color: transparent;
}

The groove in which the indicator slides, popularly called “track”, can be styled with its pseudo-element ::-webkit-slider-runnable-track. Setting appearance to none will let us apply our own styles once again. After that, we can start creating the desired shape of the component. The first thing we will change is height as I always find it too big. Next thing we will be focusing on is the track’s colour – and here the fun part begins. The slider doesn’t need to have a solid background. You can apply a gradient or even an image! Although I recommend adding a solid colour to the background – just in case your image stops working. Let’s see how this part of the code looks:

input[type="range"]::-webkit-slider-runnable-track {
  -webkit-appearance: none;
  appearance: none;
  height: 3px;
  background: rgb(246, 114, 128);
  background: -webkit-linear-gradient(
    left,
    rgba(246, 114, 128, 1) 0%,
    rgba(192, 108, 132, 1) 50%,
    rgba(53, 92, 125, 1) 100%
  );
  background: linear-gradient(
    to right,
    rgba(246, 114, 128, 1) 0%,
    rgba(192, 108, 132, 1) 50%,
    rgba(53, 92, 125, 1) 100%
  );
  filter: progid:DXImageTransform.Microsoft.gradient(
    startColorstr="#f67280",
    endColorstr="#355c7d",
    GradientType=1
  );
}

Finally, we can take care of the slider’s thumb. As in the previous parts, the first thing we have to do is disabling a default styling of the element. Setting proper size and border parameters will help us create the desired shape. Adding box-shadow will add depth to the slider. As I don’t want the thumb to have a solid colour, we will set a small icon in the background attribute. To properly style thumb’s location on the track we need to set the position value to relative. Changing bottomΒ property will make its bottom edge move above its normal position. Another answer to this situation is to set a negative value for a margin. Personally, I don’t like this solution as it can lead to unwanted overlapping of content and introduce small bugs which can be difficult to spot later.

As I like adding small details to the design I’ve decided to add different types of the cursor when you hover a thumb and when you are using it. To do so I will set cursor to grab as default and grabbing type on active state. This is how the code for the styled thumb looks like:

input[type="range"]::-webkit-slider-thumb {
  -webkit-appearance: none;
  appearance: none;
  border: 2px solid #f8b195;
  border-radius: 50%;
  height: 20px;
  width: 20px;
  position: relative;
  bottom: 8px;
  background: #222
    url("http://codemenatalie.com/wp-content/uploads/2019/09/slider-thumb.png") center no-repeat;
  background-size: 50%;
  box-shadow: 0px 3px 5px 0px rgba(0, 0, 0, 0.4);
  cursor: grab;

    &:active {
      cursor: grabbing;
    }
}

The finishing touch we always need to remember about is browser compatibility. To achieve that we have to duplicate styling for CSS browser prefixes, also known as vendor prefixes. Thanks to that all the browsers will support our style changes as different browser creators implement the same properties with slightly different syntax. For example to make sure the slider will look as we want in Firefox we have to use ::-moz-range-track to style a track and ::-moz-range-thumb to style a thumb. To disable default styling of elements we need to add -moz-appearance: none to each of it.

Below you can find the final result and complete code. If you have any questions don’t hesitate to drop me a message on my Twitter! πŸ™‚

See the Pen Pure CSS – classy slider by Natalie (@CodeMeNatalie) on CodePen.