2

In order to use Tailwind CSS for styling the input slider's track and thumb, I have to rely on two different pseudo elements (WebKit and Mozilla), which results in code duplication.

However, since these selectors are not standardized, it may be necessary to apply different styles for each system separately.

It is possible to implement this with arbitrary values, but the code becomes very long and unreadable.

<script src="https://cdn.jsdelivr.net/npm/@tailwindcss/browser@4"></script>
<input
  type="range"
  class="
    m-5 appearance-none w-[20em] h-[2em] outline-none overflow-hidden rounded
    
    /* Track for webkit */
    [&::-webkit-slider-runnable-track]:bg-slate-300
    [&::-webkit-slider-runnable-track]:h-full
    [&::-webkit-slider-runnable-track]:rounded
    
    /* Track for moz */
    [&::-moz-range-track]:bg-slate-300
    [&::-moz-range-track]:h-full
    [&::-moz-range-track]:rounded
    
    /* Thumb for webkit */
    [&::-webkit-slider-thumb]:h-full
    [&::-webkit-slider-thumb]:w-[8px]
    [&::-webkit-slider-thumb]:bg-blue-500
    [&::-webkit-slider-thumb]:[box-shadow:_-20em_0_0_20em_black]
    /* Custom for webkit */
    [&::-webkit-slider-thumb]:appearance-none
    
    /* Thumb for moz */
    [&::-moz-range-thumb]:h-full
    [&::-moz-range-thumb]:w-[8px]
    [&::-moz-range-thumb]:bg-blue-500
    [&::-moz-range-thumb]:[box-shadow:_-20em_0_0_20em_black]
    /* Custom for moz */
    [&::-moz-range-thumb]:border-0
    [&::-moz-range-thumb]:rounded-none
  "
/>

I tried creating a custom variant, but it seems it doesn't work:

<script src="https://cdn.jsdelivr.net/npm/@tailwindcss/browser@4"></script>
<style type="text/tailwindcss">
@custom-variant slider-track (&::-webkit-slider-runnable-track, &::-moz-range-track));
</style>

<input
  type="range"
  class="
    m-5 appearance-none w-[20em] h-[2em] outline-none overflow-hidden rounded
    
    /* Track for webkit & moz */
    slider-track:bg-slate-300
    slider-track:h-full
    slider-track:rounded
    
    /* Thumb for webkit */
    [&::-webkit-slider-thumb]:h-full
    [&::-webkit-slider-thumb]:w-[8px]
    [&::-webkit-slider-thumb]:bg-blue-500
    [&::-webkit-slider-thumb]:[box-shadow:_-20em_0_0_20em_black]
    /* Custom for webkit */
    [&::-webkit-slider-thumb]:appearance-none
    
    /* Thumb for moz */
    [&::-moz-range-thumb]:h-full
    [&::-moz-range-thumb]:w-[8px]
    [&::-moz-range-thumb]:bg-blue-500
    [&::-moz-range-thumb]:[box-shadow:_-20em_0_0_20em_black]
    /* Custom for moz */
    [&::-moz-range-thumb]:border-0
    [&::-moz-range-thumb]:rounded-none
  "
/>

How can I make the variants in class names more readable, and how can I eliminate code duplication this way?

1 Answer 1

2

You're on the right track - using custom variants, you can make the values written as arbitrary values more readable. Not only single-line custom variants can be created, but much more complex ones as well. In this case, the styles passed to the variant need to be declared twice: once for WebKit and once for Mozilla, and these cannot be merged.

<script src="https://cdn.jsdelivr.net/npm/@tailwindcss/browser@4"></script>
<style type="text/tailwindcss">
@custom-variant slider-track {
  &::-webkit-slider-runnable-track {
    @slot;
  }
  &::-moz-range-track {
    @slot;
  }
}

@custom-variant slider-thumb {
  &::-webkit-slider-thumb {
    @slot;
  }
  &::-moz-range-thumb {
    @slot;
  }
}
</style>

<input
  type="range"
  class="
    m-5 appearance-none w-[20em] h-[2em] outline-none overflow-hidden rounded

    slider-track:h-full
    slider-track:bg-slate-300 slider-track:rounded

    slider-thumb:h-full slider-thumb:w-[8px]
    slider-thumb:bg-sky-500 slider-thumb:[box-shadow:_-20em_0_0_20em_black]
  "
/>

Note: The example is not perfect yet, as it lacks Mozilla-specific and WebKit-specific styling.

After that, we can create additional custom variant - with consistent naming - that apply styles specifically for WebKit or Mozilla only.

<script src="https://cdn.jsdelivr.net/npm/@tailwindcss/browser@4"></script>
<style type="text/tailwindcss">
@custom-variant slider-track {
  &::-webkit-slider-runnable-track {
    @slot;
  }
  &::-moz-range-track {
    @slot;
  }
}
@custom-variant slider-track--webkit (&::-webkit-slider-runnable-track);
@custom-variant slider-track--moz (&::-moz-range-track);

@custom-variant slider-thumb {
  &::-webkit-slider-thumb {
    @slot;
  }
  &::-moz-range-thumb {
    @slot;
  }
}
@custom-variant slider-thumb--webkit (&::-webkit-slider-thumb);
@custom-variant slider-thumb--moz (&::-moz-range-thumb);
</style>

<input
  type="range"
  class="
    m-5 appearance-none w-[20em] h-[2em] outline-none overflow-hidden rounded

    slider-track:h-full
    slider-track:bg-slate-300 slider-track:rounded

    slider-thumb:h-full slider-thumb:w-[8px]
    slider-thumb:bg-sky-500 slider-thumb:[box-shadow:_-20em_0_0_20em_black]

    slider-thumb--webkit:appearance-none
    slider-thumb--moz:border-0 slider-thumb--moz:rounded-none
  "
/>

Sign up to request clarification or add additional context in comments.

1 Comment

Just interested example from this answer: jsfiddle.net/z1u0jq5r

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.