Skip to content

Slider with gradient background styling. #521

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
Westbrook opened this issue Feb 5, 2020 · 7 comments
Closed

Slider with gradient background styling. #521

Westbrook opened this issue Feb 5, 2020 · 7 comments
Labels
ask design Questions or topics for the design team sync to jira These will be pushed into adobe internal jira

Comments

@Westbrook
Copy link
Contributor

Westbrook commented Feb 5, 2020

Description

With the current slider track DOM structure: [===Left Track===] (Knob) [===Right Track===]

<div class="spectrum-Slider-track" style="width: 40%"></div>
<div class="spectrum-Slider-handle" style="left: 40%;">
      <input type="range" class="spectrum-Slider-input" value="14" step="2" min="10" max="20">
</div>
<div class="spectrum-Slider-track" style="width: 60%"></div>

The ability to create a gradient slider, a la https://spectrum.adobe.com/page/slider/#Gradient, is pretty difficult. Particularly because both .spectrum-Slider-track elements are assigned the same --spectrum-slider-track-color custom property to manage their background. As solid color, this is fine, but for a gradient that should uniformly span the width of the slider element the hacks to work around that are dubious.

I'd like to suggest the possibility of addressing this UI by altering the clip-path of the .spectrum-Slider-track elements, rather than their width.

<div class="spectrum-Slider-track" style="
clip-path: polygon(
    calc(40% - var(
                --spectrum-slider-handle-gap,
                var(
                    --spectrum-alias-border-size-thicker
                )
            )) 0,
    100%  0,
    100% 100%,
    calc(40% - var(
                --spectrum-slider-handle-gap,
                var(
                    --spectrum-alias-border-size-thicker
                )
            )) 100%
);"></div>
<div class="spectrum-Slider-handle" style="left: 40%;">
      <input type="range" class="spectrum-Slider-input" value="14" step="2" min="10" max="20">
</div>
<div class="spectrum-Slider-track" style="
clip-path: polygon(
    calc(40% + var(
                --spectrum-slider-handle-gap,
                var(
                    --spectrum-alias-border-size-thicker
                )
            )) 0,
    100%  0,
    100% 100%,
    calc(40% - var(
                --spectrum-slider-handle-gap,
                var(
                    --spectrum-alias-border-size-thicker
                )
            )) 100%
);"></div>

It's a pretty heavy lift to have all of that clip-path rule in the inline styles, but this could be translated to a single --spectrum-slider-track-percentage property that hid all of that complexity inside of the delivered styles.

The main alteration that is needed from Spectrum CSS is to ensure .spectrum-Slider-track { width: 100%; } and then the same track color (e.g. --spectrum-slider-track-color: linear-gradient(to right, red, green 100%)) would be applicable to both tracks and allow the UI desired. Doing the same to .spectrum-Slider-fill would similarly allow the --spectrum-slider-fill-track-color custom property to support the same when the filled variant is used.

The Spectrum Web Components team has previously prototyped this in the following PR: adobe/spectrum-web-components#456
image

Why do you need this feature or component?

Cleaner support for Spectrum specification for usage in our applications.

Possible issues:

clip-path has mixed browser support in the long tail, so I'm not sure how it intersection with your browser support matrix; needs checking in Edge/IE 11 as clip-path is listed as "only supporting url()" in those browsers depending on which Can I Use you rely on: https://caniuse.com/#search=clip-path

synced to jira: https://jira.corp.adobe.com/browse/CSS-215

@lazd
Copy link
Member

lazd commented Jul 20, 2020

If clip-path works in all supported browsers, I'm in.

@mischnic
Copy link
Contributor

Another alternative would be keeping the current HTML structure, applying the gradient via --spectrum-slider-track-color and using background-size and background-position to offset the background in the individual tracks:

https://codepen.io/mischnic/pen/WNwgjvg

@Westbrook
Copy link
Contributor Author

That's really nice @mischnic! Managing background-size: calc(100% / ${valueAsDecimal); in that way simplifies a lot of logic and removes the need for a lot of things. Funnily to the timing, we just finally merged our PR for the in SWC yesterday, but it's not released yet, so I'm definitely gonna take a look at applying this functionality this way before we do. Thanks!

@Westbrook
Copy link
Contributor Author

Looking deeper at this, the approach does require a little bit more of the actual CSS that is being generated, but a good amount less overall. The changes looks like:

background becomes background-image so as not to over write background-size:

.spectrum-Slider-track:before {
    background: var(
        --spectrum-slider-track-color,
        var(--spectrum-global-color-gray-300)
    );
    background-size: var(--spectrum-slider-track-background-size, 100%); /* not 100% sure a fallback is needed here... */
}

And the following addition:

:host([dir="ltr"]) #track-right:before {
    background-position: 100%;
}

:host([dir="rtl"]) #track-left:before {
    background-position: 100%;
}

With the sample HTML being updated to include --spectrum-slider-track-background-size:

<div class="spectrum-Slider-track" style="width: 40%; --track-background-size: calc(100% / 0.4);"></div>
<div class="spectrum-Slider-handle" style="left: 40%;">
      <input type="range" class="spectrum-Slider-input" value="14" step="2" min="10" max="20">
</div>
<div class="spectrum-Slider-track" style="width: 60%; --track-background-size: calc(100% / 0.6);"></div>

All with the added benefit of maintaining the browser support matrix (IE11 and Edge live to fight another day...).

If this makes sense to everyone, I can take a look at what would be needed to get a PR together for this.

@Westbrook
Copy link
Contributor Author

One thing unaddressed in either of these solutions is support for RTL in the gradient. Sadly, there isn't support for logical properties in the linear-gradient syntax. Would this point to the need for something like:

[dir="rtl"] .spectrum-Slider-track:before {
    background: var(
        --spectrum-slider-track-color-rtl,
        var(
            --spectrum-slider-track-color,
            var(--spectrum-global-color-gray-300)
        )
    );
}

@mischnic
Copy link
Contributor

Here's how I've implemented this for React Spectrum: adobe/react-spectrum@c702d55

Demo: https://reactspectrum.blob.core.windows.net/reactspectrum/f0e1bef8b1906f25cd7ededb4b7d48f22e7c0d35/storybook/index.html?path=/story/slider--trackbackground

(Missing RTL support, I didn't even think of that when writing this 😄 )

@mischnic
Copy link
Contributor

mischnic commented Sep 23, 2020

If this makes sense to everyone

Does someone from the Spectrum CSS team have thoughts on this?

@misterbrownlee misterbrownlee added the ask design Questions or topics for the design team label Apr 11, 2022
@pfulton pfulton added the sync to jira These will be pushed into adobe internal jira label Jul 1, 2022
@pfulton pfulton closed this as completed Jul 1, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
ask design Questions or topics for the design team sync to jira These will be pushed into adobe internal jira
Projects
None yet
Development

No branches or pull requests

5 participants