Nightmare.js Cannot Read Property 'focus' of Null

Y'all may have already seen a bunch of tutorials on how to mode the range input. While this is another article on that topic, information technology's not most how to go any specific visual result. Instead, it dives into browser inconsistencies, detailing what each does to display that slider on the screen. Understanding this is of import because it helps us take a clear idea almost whether nosotros tin can make our slider wait and behave consistently across browsers and which styles are necessary to do so.

Looking inside a range input

Before anything else, we demand to make sure the browser exposes the DOM within the range input.

In Chrome, we bring upward DevTools, go to Settings, Preferences, Elements and make certain the Show user agent shadow DOM choice is enabled.

Series of Chrome screenshots illustrating the steps described above.
Sequence of Chrome screenshots illustrating the steps from above.

In Firefox, we become to about:config and make sure the devtools.inspector.showAllAnonymousContent flag is set to true.

Series of Firefox screenshots illustrating the steps described above.
Sequence of Firefox screenshots illustrating the steps from in a higher place.

For a very long time, I was convinced that Edge offers no way of seeing what's inside such elements. Just while messing with it, I discovered that where there's a will and (and some impaired luck) there'south a way! We need to bring upwards DevTools, then get to the range input we want to inspect, right click it, select Inspect Chemical element and bam, the DOM Explorer console now shows the structure of our slider!

Series of Edge screenshots illustrating the steps described above.
Sequence of Edge screenshots illustrating the steps from above.

Apparently, this is a bug. Just it's also immensely useful, so I'g not lament.

The structure inside

Correct from the start, nosotros tin can see a source for potential issues: we have very different beasts inside for every browser.

In Chrome, at the top of the shadow DOM, we have a div nosotros cannot access anymore. This used to be possible back when /deep/ was supported, but then the ability to pierce through the shadow bulwark was deemed to be a bug, so what used to be a useful characteristic was dropped. Inside this div, we have another i for the track and, within the track div, we have a third div for the pollex. These terminal two are both conspicuously labeled with an id aspect, but another thing I detect strange is that, while we can access the track with ::-webkit-slider-runnable-rail and the thumb with ::-webkit-slider-pollex, only the track div has a pseudo attribute with this value.

Chrome screenshot of the structure we have inside a range input.
Inner structure in Chrome.

In Firefox, nosotros also come across three div elements within, only this fourth dimension they're non nested – all three of them are siblings. Furthermore, they're just obviously div elements, not labeled by whatsoever attribute, so we have no way of telling which is which component when looking at them for the showtime time. Fortunately, selecting them in the inspector highlights the corresponding component on the folio and that's how we tin tell that the start is the rails, the 2nd is the progress and the 3rd is the thumb.

Firefox screenshot of the structure we have inside a range input.
Inner structure in Firefox.

Nosotros can admission the track (starting time div) with ::-moz-range-track, the progress (second div) with ::-moz-range-progress and the thumb (last div) with ::-moz-range-thumb.

The construction in Edge is much more complex, which, to a certain extent, allows for a greater degree of command over styling the slider. However, nosotros tin merely access the elements with -ms- prefixed IDs, which means there are also a lot of elements we cannot admission, with baked in styles we'd often demand to change, like the overflow: hidden on the elements between the actual input and its rails or the transition on the thumb's parent.

Edge screenshot of the structure we have inside a range input.
Inner construction in Edge.

Having a different structure and existence unable to access all the elements inside in order to manner everything as we wish means that achieving the same result in all browsers can exist very hard, if not even incommunicable, fifty-fifty if having to utilize a dissimilar pseudo-chemical element for every browser helps with setting private styles.

We should always aim to keep the private styles to a minimum, only sometimes it's simply not possible, as setting the aforementioned style can produce very different results due to having different structures. For case, setting properties such every bit opacity or filter or fifty-fifty transform on the track would also touch the thumb in Chrome and Edge (where it's a kid/ descendant of the track), but not in Firefox (where information technology's its sibling).

The most efficient way I've institute to set common styles is by using a Sass mixin considering the following won't piece of work:

          input::-webkit-slider-runnable-track,  input::-moz-range-rail,  input::-ms-track { /* mutual styles */ }        

To brand information technology work, we'd need to write it like this:

          input::-webkit-slider-runnable-rails { /* common styles */ } input::-moz-range-track { /* common styles */ } input::-ms-runway { /* common styles */ }        

But that's a lot of repetition and a maintainability nightmare. This is what makes the mixin solution the sanest selection: we only take to write the common styles in one case so, if we decide to modify something in the common styles, so we only need to make that change in ane place – in the mixin.

          @mixin track() { /* common styles */ }  input {   &::-webkit-slider-runnable-rail { @include track }   &::-moz-range-track { @include track }   &::-ms-runway { @include track } }        

Note that I'm using Sass hither, but you may use whatever other preprocessor. Whatever you lot prefer is good as long as it avoids repetition and makes the code easier to maintain.

Initial styles

Next, nosotros take a look at some of the default styles the slider and its components come up with in order to amend sympathize which properties need to be set explicitly to avoid visual inconsistencies between browsers.

Just a warning in advance: things are messy and complicated. It'southward not just that we have different defaults in different browsers, but also irresolute a property on one element may change another in an unexpected style (for example, when setting a groundwork also changes the colour and adds a border).

WebKit browsers and Edge (because, yep, Edge also applies a lot of WebKit prefixed stuff) also have two levels of defaults for certain properties (for example those related to dimensions, borders, and backgrounds), if we may call them that – earlier setting -webkit-appearance: none (without which the styles we set won't piece of work in these browsers) and later on setting it. The focus is going to exist however on the defaults after setting -webkit-appearance: none considering, in WebKit browsers, we cannot mode the range input without setting this and the whole reason we're going through all of this is to understand how nosotros can make our lives easier when styling sliders.

Annotation that setting -webkit-appearance: none on the range input and on the thumb (the track already has it set by default for some reason) causes the slider to completely disappear in both Chrome and Border. Why that happens is something we'll discuss a bit later in this commodity.

The bodily range input element

The first property I've thought about checking, box-sizing, happens to accept the same value in all browsers – content-box. Nosotros can see this past looking up the box-sizing belongings in the Computed tab in DevTools.

Comparative screenshots of DevTools in the three browsers showing the computed values of box-sizing for a range input.
The box-sizing of the range input, comparative look at all three browsers (from top to bottom: Chrome, Firefox, Edge).

Sadly, that's non an indication of what's to come. This becomes obvious in one case nosotros have a look at the properties that give us the chemical element's boxes – margin, border, padding, width, pinnacle.

By default, the margin is 2px in Chrome and Edge and 0 .7em in Firefox.

Before we move on, let's see how we got the values to a higher place. The computed length values we go are always px values.

However, Chrome shows u.s. how browser styles were set (the user agent stylesheet rule sets on a grey background). Sometimes the computed values we get weren't explicitly set, so that'southward no utilise, but in this detail case, we can meet that the margin was indeed fix as a px value.

Screenshot of Chrome DevTools showing where to look for how browser styles were set.
Tracing browser styles in Chrome, the margin case.

Firefox also lets us trace the source of the browser styles in some cases, as shown in the screenshot beneath:

Screenshot of Firefox DevTools showing where to look for how browser styles were set.
Tracing browser styles in Firefox and how this fails for the margin of our range input.

However, that doesn't work in this item example, so what we can exercise is look at the computed values in DevTools and then checking whether these computed values change in one of the following situations:

  1. When irresolute the font-size on the input or on the html, which entails is was set as an em or rem value.
  2. When irresolute the viewport, which indicates the value was set using % values or viewport units. This can probably be safely skipped in a lot of cases though.
Gif recording showing how changing the font-size on the range input changes the margin value in Firefox.
Changing the font-size of the range input in Firefox too changes its margin value.

The same goes for Edge, where nosotros can trace where user styles come from, but not browser styles, so we need to bank check if the computed px value depends on annihilation else.

Gif recording showing how changing the font-size on the range input doesn't change the margin value in Edge.
Changing the font-size of the range input in Edge doesn't change its margin value.

In any event, this all means margin is a belongings we demand to prepare explicitly in the input[type='range'] if we want to accomplish a consequent wait across browsers.

Since nosotros've mentioned the font-size, let's cheque that as well. Sure enough, this is likewise inconsistent.

First off, nosotros have 13.3333px in Chrome and, in spite of the decimals that might advise it's the result of a computation where nosotros divided a number by a multiple of 3, it seems to have been set as such and doesn't depend on the viewport dimensions or on the parent or root font-size.

Screenshot of Chrome DevTools showing the user agent rule where the font-size for inputs is set.
The font-size of the range input in Chrome.

Firefox shows united states of america the same computed value, except this seems to come from setting the font shorthand to -moz-field, which I was get-go very confused nigh, especially since background-color is ready to -moz-Field, which ought to be the same since CSS keywords are case-insensitive. But if they're the same, and so how can information technology be a valid value for both properties? Plainly, this keyword is some sort of alias for making the input look similar what whatsoever input on the current OS looks similar.

Screenshot of Firefox DevTools showing how the font-size for inputs is set.
The font-size of the range input in Firefox.

Finally, Edge gives us 16px for its computed value and this seems to be either inherited from its parent or gear up equally 1em, as illustrated by the recording below:

Recording of Edge DevTools showing the computed value of  font-size for inputs and how this changes when changing the font-size of the parent.
The font-size of the range input in Edge.

This is important because we often want to set up dimensions of sliders and controls (and their components) in general using em units so that their size relative to that of the text on the page stays the same – they don't await as well small-scale when we increase the size of the text or as well big when nosotros decrease the size of the text. And if we're going to fix dimensions in em units, then having a noticeable font-size departure between browsers here will result in our range input existence smaller in some browsers and bigger in others.

For this reason, I always make sure to explicitly set a font-size on the actual slider. Or I might set the font autograph, even though the other font-related properties don't thing hither at this point. Possibly they will in the future, simply more on that later, when we talk over tick marks and tick marker labels.

Before we move on to borders, let'southward get-go run into the color belongings. In Chrome this is rgb(196,196,196) (prepare as such), which makes it slightly lighter than silvery (rgb(192,192,192)/ #c0c0c0), while in Edge and Firefox, the computed value is rgb(0,0,0) (which is solid black). We have no style of knowing how this value was set in Edge, just in Firefox, it was set via some other similar keyword, -moz-fieldtext.

Comparative screenshots of DevTools in the three browsers showing the computed values of color for a range input.
The color of the range input, comparative look at all three browsers (from superlative to bottom: Chrome, Firefox, Edge).

The border is set to initial in Chrome, which is equivalent to none medium currentcolor (values for border-manner, border-width and edge-color). How thick a medium border is exactly depends on the browser, though it's at least as thick as a thin 1 everywhere. In Chrome in item, the computed value we become here is 0.

Screenshot of Chrome DevTools showing how the border for inputs is set.
The border of the range input in Chrome.

In Firefox, nosotros also have a none medium currentcolor value ready for the edge, though here medium seems to be equivalent to 0.566667px, a value that doesn't depend on the element or root font-size or on the viewport dimensions.

Screenshot of Firefox DevTools showing how the border for inputs is set.
The edge of the range input in Firefox.

We can't see how everything was set in Border, but the computed values for border-style and border-width are none and 0 respectively. The edge-colour changes when nosotros change the colour belongings, which means that, simply like in the other browsers, it'southward set to currentcolor.

Recording of Edge DevTools showing the computed values of border properties for inputs and how border-color changes when changing the element's color property.
The border of the range input in Border.

The padding is 0 in both Chrome and Edge.

Comparative screenshots of DevTools in Chrome and Edge browsers showing the computed values of padding for a range input.
The padding of the range input, comparative look at Chrome (top) and Edge (bottom).

Yet, if we want a pixel-perfect result, then we need to prepare it explicitly considering it's set to 1px in Firefox.

Screenshot of Firefox DevTools showing how the padding for inputs is set.
The padding of the range input in Firefox.

Now let's take some other detour and check the backgrounds earlier we try to make sense of the values for the dimensions. Here, we become that the computed value is transparent/ rgba(0, 0, 0, 0) in Edge and Firefox, simply rgb(255,255,255) (solid white) in Chrome.

Comparative screenshots of DevTools in the three browsers showing the computed values of background-color for a range input.
The background-colour of the range input, comparative wait at all 3 browsers (from peak to bottom: Chrome, Firefox, Border).

And… finally, allow'south look at the dimensions. I've saved this for last because here is where things start to get actually messy.

Chrome and Edge both give usa 129px for the computed value of the width. Unlike with previous properties, we can't see this being set anywhere in Chrome, which would commonly atomic number 82 me to believe it'due south something that depends either on the parent, stretching horizontally to fit as all cake elements exercise (which is definitely not the instance hither) or on the children. There'south also a -webkit-logical-width property taking the same 129px value in the Computed panel. I was a bit confused by this at commencement, but it turns out information technology's the writing-mode relative equivalent – in other words, it'southward the width for horizontal writing-way and the superlative for vertical writing-mode.

Gif recording showing how changing the font-size on the range input doesn't change its width value in Chrome.
Irresolute the font-size of the range input in Chrome doesn't change its width value.

In any event, it doesn't depend on the font-size of the input itself or of that of the root element nor on the viewport dimensions in either browser.

Gif recording showing how changing the font-size on the range input doesn't change its width value in Edge.
Changing the font-size of the range input in Edge doesn't change its width value.

Firefox is the odd i out hither, returning a computed value of 160px for the default width. This computed value does however depend on the font-size of the range input – it seems to be 12em.

Gif recording showing how changing the font-size on the range input also changes its width value in Firefox.
Changing the font-size of the range input in Firefox also changes its width value.

In the case of the height, Chrome and Border again both agree, giving us a computed value of 21px. Merely like for the width, I cannot come across this existence ready anywhere in the user agent stylesheet in Chrome DevTools, which usually happens when the elevation of an element depends on its content.

Gif recording showing how changing the font-size on the range input doesn't change its height value in Chrome.
Irresolute the font-size of the range input in Chrome doesn't change its acme value.

This value also doesn't depend on the font-size in either browser.

Gif recording showing how changing the font-size on the range input doesn't change its height value in Edge.
Changing the font-size of the range input in Edge doesn't change its pinnacle value.

Firefox is one time again different, giving us 17.3333px as the computed value and, again, this depends on the input's font-size – it's 1.3em.

Gif recording showing how changing the font-size on the range input also changes its height value in Firefox.
Changing the font-size of the range input in Firefox also changes its height value.

Simply this isn't worse than the margin case, right? Well, and so far, information technology isn't! But that's just nigh to change considering we're now moving on to the track component.

The range track component

There'south one more possibility regarding the actual input dimensions that we haven't even so considered: that they're influenced by those of its components. Then let's explicitly set some dimensions on the track and see whether that influences the size of the slider.

Patently, in this situation, nothing changes for the actual slider in the case of the width, merely nosotros can spot more inconsistencies when it comes to the track width, which, past default, stretches to make full the content-box of the parent input in all three browsers.

In Firefox, if we explicitly set a width, whatever width on the track, so the track takes this width nosotros requite it, expanding outside of its parent slider or shrinking inside, but always staying middle aligned with it. Great at all, but, sadly, it turns out Firefox is the only browser that behaves in a sane style here.

Gif recording showing how changing the width on the track component doesn't influence the width of the range input in Firefox only that of the track. Furthermore, the track and the actual range input are always middle aligned horizontally.
Explicitly setting a width on the track changes the width of the runway in Firefox, simply non that of the parent slider.

In Chrome, the rails width we ready is completely ignored and information technology looks like there's no sane style of making it have a value that doesn't depend on that of the parent slider.

Gif recording showing how changing the width on the track component doesn't do anything in Chrome.
Irresolute the width of the runway doesn't do annihilation in Chrome (computed value remains 129px).

Every bit for insane ways, using transform: scaleX(factor) seems to exist the just way to make the rail wider or narrower than its parent slider. Do note doing this also causes quite a few side effects. The thumb is scaled horizontally as well and its motion is limited to the scaled downwardly track in Chrome and Edge (every bit the thumb is a child of the track in these browsers), but not in Firefox, where its size is preserved and its movement is even so limited to the input, not the scaled down track (since the track and thumb are siblings here). Any lateral padding, border or margin on the rail is likewise going to exist scaled.

Moving on to Edge, the runway again takes any width we prepare.

Gif recording showing how Edge allows us to change the width of the track without changing that of the parent slider.
Edge as well allows us to gear up a track width that's different from that of the parent slider.

This is not the same situation as Firefox however. While setting a width greater than that of the parent slider on the rails makes it aggrandize outside, the two are non middle aligned. Instead, the left border limit of the rail is left aligned with the left content limit of its range input parent. This alignment inconsistency on its ain wouldn't be that much of a problem – a margin-left gear up only on ::-ms-track could fix it.

However, everything outside of the parent slider's content-box gets cut out in Edge. This is not equivalent to having overflow set up to hidden on the actual input, which would cut out everything outside the padding-box, not content-box. Therefore, information technology cannot be stock-still past setting overflow: visible on the slider.

This clipping is caused past the elements between the input and the runway having overflow: hidden, merely, since we cannot access these, we also cannot ready this problem. Setting everything such that no component (including its box-shadow) goes exterior the content-box of the range is an option in some cases, simply not always.

For the height, Firefox behaves in a like manner information technology did for the width. The track expands or shrinks vertically to the height we set without affecting the parent slider and always staying heart aligned to it vertically.

Gif recording showing how changing the height on the track component doesn't influence the height of the range input in Firefox only that of the track. Furthermore, the track and the actual range input are always middle aligned vertically.
Explicitly setting a height on the rail changes the superlative of the track in Firefox, but not that of the parent slider.

The default value for this summit with no styles set on the actual input or track is .2em.

Gif recording showing how changing the font-size on the track changes its computed height in Firefox.
Changing the font-size on the track changes its computed height in Firefox.

Dissimilar in the instance of the width, Chrome allows the rail to take the superlative we set and, if we're not using a % value here, information technology too makes the content-box of the parent slider aggrandize or shrink such that the edge-box of the rail perfectly fits in information technology. When using a % value, the bodily slider and the track are middle aligned vertically.

Gif recording showing how changing the height on the track component doesn't influence the height of the range input in Chrome if the value we set is a % value. Otherwise, the track expands or shrinks such that the track perfectly fits in. Furthermore, in the % case, the track and the actual range input are always middle-aligned vertically.
Explicitly setting a height on the track in % changes the summit of the track in Chrome, but not that of the parent slider. Using other units, the bodily range input expands or shrinks vertically such that the track perfectly fits inside.

The computed value we get for the height without setting any custom styles is the same equally for the slider and doesn't alter with the font-size.

Gif recording showing how changing the font-size on the track doesn't change its computed height in Chrome.
Changing the font-size on the track doesn't change its computed height in Chrome.

What about Border? Well, nosotros can change the height of the track independently of that of the parent slider and they both stay middle aligned vertically, but all of this is simply as long equally the track height nosotros set is smaller than the initial height of the bodily input. Above that, the track'due south computed summit is always equal to that of the parent range.

Gif recording showing how changing the height on the track component doesn't influence the height of the range input in Edge. The track and the actual range input are always middle aligned vertically. However, the height of the track is limited by that of the parent slider.
Explicitly setting a height on the track in Edge doesn't change the elevation of the parent slider and the two are middle aligned. All the same, the superlative of the track is limited by that of the actual input.

The initial track height is 11px and this value doesn't depend on the font-size or on the viewport.

Gif recording showing how changing the font-size on the track doesn't change its computed height in Edge.
Changing the font-size on the track doesn't alter its computed meridian in Edge.

Moving on to something less mindbending, we take box-sizing. This is border-box in Chrome and content-box in Edge and Firefox so, if nosotros're going to take a non-zip border or padding, so box-sizing is a belongings we need to explicitly set in order to fifty-fifty things out.

Comparative screenshots of DevTools in the three browsers showing the computed values of box-sizing for the track.
The box-sizing of the track, comparative wait at all three browsers (from top to bottom: Chrome, Firefox, Border).

The default runway margin and padding are both 0 in all 3 browsers – finally, an haven of consistency!

Comparative screenshots of DevTools in the three browsers showing the computed values of margin for the track.
The box-sizing of the track, comparative look at all iii browsers (from acme to bottom: Chrome, Firefox, Border).

The values for the color holding tin be inherited from the parent slider in all three browsers.

Comparative screenshots of DevTools in Chrome and Firefox browsers showing the computed values of color for the track.
The color of the track, comparative look at Chrome (top) and Firefox (lesser).

All the same, Edge is the odd one here, changing information technology to white, though setting it to initial changes it to black, which is the value we have for the actual input.

Resetting the color to initial in Edge.
Resetting the colour to initial in Edge.

Setting -webkit-advent: none on the bodily input in Border makes the computed value of the color on the runway transparent (if nosotros oasis't explicitly prepare a color value ourselves). Also, once nosotros add a background on the track, the computed track color suddenly changes to black.

Adding a background on the track in Edge changes its computed color from white to black.
Unexpected consequence of adding a groundwork rails in Edge.

To a sure extent, the power to inherit the color belongings is useful for theming, though inheriting custom properties tin can practise a lot more here. For example, consider we want to use a silverish for secondary things and an orange for what nosotros want highlighted. We tin can define two CSS variables on the body so use them beyond the page, even inside our range inputs.

          torso {   --fading: #bbb;   --bear upon: #f90 }  h2 { border-bottom: solid .125em var(--touch) }  h6 { colour: var(--fading) }  [type='range']:focus { box-shadow: 0 0 2px var(--impact) }  @mixin rails() { background: var(--fading) }  @mixin thumb() { groundwork: var(--impact) }        

Sadly, while this works in Chrome and Firefox, Edge doesn't currently permit custom backdrop on the range inputto be inherited downward to its components.

Screenshots of the expected result (and what we get in Chrome and Firefox) vs. the result we get in Edge (neither the thumb or the track show up)
Expected result (left) vs. outcome in Edge (correct), where no track or thumb show upward (alive demo).

By default, at that place is no edge on the runway in Chrome or Firefox (border-width is 0 and border-style is none).

Comparative screenshots of DevTools in Chrome and Firefox browsers showing the computed values of border for the track.
The border of the track, comparative await at Chrome (top) and Firefox (bottom).

Edge has no edge on the track if we have no background assault the actual input and no background fix on the track itself. However, once that changes, we get a sparse (1px) black rails border.

Adding a background on the track or actual input in Edge gives the track a solid 1px black border.
Another unexpected event of adding a rail or parent slider background in Edge.

The default groundwork-colour is shown to be inherited every bit white, but then somehow we get a computed value of rgba(0,0,0,0) (transparent) in Chrome (both before and later on -webkit-appearance: none). This also makes me wonder how come nosotros can encounter the runway earlier, since at that place's no background-color or background-prototype to give u.s.a. anything visible. Firefox gives us a computed value of rgb(153,153,153) (#999) and Border transparent (even though we might initially think it'due south some kind of silver, that is not the background of the ::-ms-rails element – more than on that a bit afterward).

Comparative screenshots of DevTools in the three browsers showing the computed values of background-color for the track.
The background-colour of the rails, comparative wait at all three browsers (from top to bottom: Chrome, Firefox, Edge).

The range pollex component

Ready for the nearly abrasive inconsistency nonetheless? The thumb moves within the limits of the track'southward content-box in Chrome and within the limits of the bodily input'south content-box in Firefox and Edge, even when nosotros make the track longer or shorter than the input (Chrome doesn't allow this, forcing the rails's border-box to fit the slider'southward content-box horizontally).

The way Chrome behaves is illustrated below:

Chrome only moves the thumb within the left and right limits of the track's content-box.
Recording of the thumb motion in Chrome from ane cease of the slider to the other.

The padding is transparent, while the content-box and the edge are semitransparent. We've used orange for the actual slider, red for the track and purple for the thumb.

For Firefox, things are a bit different:

Firefox moves the thumb within the left and right limits of the actual range input's content-box.
Recording of the thumb motion in Firefox from one end of the slider to the other (the 3 cases from top to bottom: the border-box of the runway perfectly fits the content-box of the slider horizontally, information technology's longer and it'due south shorter).

In Chrome, the pollex is the child of the rails, while in Firefox it's its sibling, and so, looking at information technology this way, it makes sense that Chrome would motion the thumb inside the limits of the rail'south content-box and Firefox would move information technology inside the limits of the slider's content-box. However, the thumb is inside the rails in Border too and information technology still moves within the limits of the slider'south content-box.

Animated gif. Shows how Edge moves the thumb within the left and right limits of the actual range input's content-box.
Recording of the thumb motility in Edge from one end of the slider to the other (the three cases from summit to bottom: the border-box of the track perfectly fits the content-box of the slider horizontally, information technology's longer and it'due south shorter).

While this looks very strange at first, it's because Border forces the position of the rail to static and nosotros cannot change that, even if we set information technology to relative with !of import.

Animated gif. Recording of the following steps: 1) checking the computed value of the position property on the track in Edge DevTools - it's static 2) setting ::-ms-track { position: relative } 3) checking the computed value again - it's still static 4) adding !important to the rule previously set on the track 5) checking the computed value a third time - annoyingly, it's still static!
Trying (and failing) to change the value of the position holding on the track in Edge.

This means we may style our slider exactly the aforementioned for all browsers, but if its content-box doesn't coincide to that of its track horizontally (then if we have a not-aught lateral padding or edge on the track), it won't move within the same limits in all browsers.

Furthermore, if nosotros scale the track horizontally, then Chrome and Firefox conduct as they did before, the pollex moving within the limits of the now scaled track's content-box in Chrome and within the limits of the actual input's content-box in Firefox. Still, Edge makes the pollex move within an interval whose width equals that of the runway'south border-box, merely starts from the left limit of the track's padding-box, which is probably explained past the fact that the transform property creates a stacking context.

Edge moves the thumb within an interval equal to the scaled track's border-box, starting from the left limit of the padding-box
Recording of the thumb motion in Edge when the rails is scaled horizontally.

Vertically, the thumb is middle-aligned to the track in Firefox, seemingly center-aligned in Border, though I've been getting very confusing different results over multiple tests of the same situation, and the top of its edge-box is aligned to the top of the runway's content-box in Chrome in one case we've gear up -webkit-advent: none on the bodily input and on the thumb so that we can style the slider.

While the Chrome decision seems weird at showtime, is abrasive in most cases and lately has even contributed to breaking things in… Border (merely more about that in a moment), there is some logic behind it. Past default, the height of the track in Chrome is determined past that of the thumb and if nosotros look at things this way, the top alignment doesn't seem similar complete insanity anymore.

Nonetheless, nosotros often want a pollex that's bigger than the rails's height and is middle aligned to the track. Nosotros can correct the Chrome alignment with margin-tiptop in the styles we prepare on the ::-webkit-slider-thumb pseudo.

Unfortunately, this way we're breaking the vertical alignment in Edge. This is because Edge at present applies the styles set via ::-webkit-slider-thumb as well. At least we take the option of resetting margin-top to 0 in the styles nosotros assail ::-ms-pollex. The demo below shows a very uncomplicated example of this in action.

See the Pen by thebabydino (@thebabydino) on CodePen.

Just like in the instance of the track, the value of the box-sizing property is border-box in Chrome and content-box in Edge and Firefox, so, for consistent results across browsers, we need to set it explicitly if we want to accept a not-zero edge or padding on the pollex.

The margin and padding are both 0 by default in all iii browsers.

After setting -webkit-appearance: none on both the slider and the thumb (setting it on only ane of the two doesn't change anything), the dimensions of the pollex are reset from 10x21 (dimensions that don't depend on the font-size) to 129x0 in Chrome. The height of the track and actual slider also get reset to 0, since they depend on that of their content (the thumb inside, whose summit has go 0).

Animated gif. Shows Chrome DevTools with the thumb selected. Changing the font-size on the thumb doesn't change its dimensions. Setting -webkit-appearance: none on both the thumb and the actual slider resets its dimensions to 129x0
The thumb box model in Chrome.

This is also why explicitly setting a summit on the thumb makes the track take the aforementioned height.

According to Chrome DevTools, at that place is no edge in either example, even though, before setting -webkit-advent: none, information technology sure looks similar in that location is one.

Screenshot. Before setting -webkit-appearance:none, it looks like there is a border on the thumb, even though Chrome DevTools says there isn't.
How the slider looks in Chrome before setting -webkit-appearance: none.

If that's non a border, information technology might be an outline or a box-shadow with no blur and a positive spread. Simply, co-ordinate to Chrome DevTools, nosotros don't accept an outline, nor box-shadow on the pollex.

Screenshot. The computed value for outline in Chrome DevTools is none 0px rgb(196, 196, 196), while that for box-shadow is none.
Computed values for outline and box-shadow in Chrome DevTools.

Setting -webkit-appearance: none in Edge makes the pollex dimensions go from 11x11 (values that don't depend on the font-size) to 0x0. Explicitly setting a height on the thumb makes the track take the initial height (11px).

Animated gif. Shows Edge DevTools with the thumb selected. Changing the font-size on the thumb doesn't change its dimensions. Setting -webkit-appearance: none on both the thumb and the actual slider resets its dimensions to 0x0
The thumb box model in Edge.

In Edge, there'south initially no edge on the thumb. However, after setting a background on either the bodily range input or any of its components, we all of a sudden get a solid 1px white lateral one (left and correct, just not top and bottom), which visually turns to blackness in the :active country (fifty-fifty though Edge DevTools doesn't seem to notice that). Setting -webkit-appearance: none removes the edge-width.

Animated gif. Shows Edge DevTools with the thumb selected. There is originally no border, but setting a background on either the slider or its components makes the lateral borders solid 1px white ones. Setting -webkit-appearance: none on both the thumb and the actual slider removes this border (as well as making both thumb dimensions 0).
The thumb border in Edge.

In Firefox, without setting a belongings similar background on the range input or its components, the dimensions of the thumb are 1.666x3.333 and, in this case, they don't alter with the font-size. However, if we set something similar groundwork: transparent on the slider (or any groundwork value on its components), and then both the width and height of the pollex become 1em.

Animated gif. Shows Firefox DevTools with the thumb selected. Changing the font-size on the thumb doesn't change initially its dimensions. However, after setting a background on the actual input, the thumb dimensions become equal to the font-size (1em).
The thumb box model in Firefox.

In Firefox, if we are to believe what we meet in DevTools, we initially accept a solid thick gray (rgb(153, 153, 153)) border.

Screenshot. Shows Firefox DevTools displaying the computed values for the slider thumb border.
The pollex edge in Firefox DevTools.

Visually however, I tin't spot this thick gray border anywhere.

Screenshot of the slider in its initial state in Firefox, before setting a background on it or on any of its components. I cannot see any border on the thumb, even Firefox DevTools says there is a pretty thick one.
How the slider looks initially in Firefox, before setting a background on information technology or on any of its components.

Afterwards setting a background on the bodily range input or one of its components, the thumb border really becomes visually detectable and it seems to exist .1em.

Animated gif. Shows Firefox DevTools with the thumb selected. In DevTools we originally see a thickish grey border, with a different width on every side, but setting a background on either the slider or its components makes this border thinner an uniform around the thumb. Its width varies with the font-size and it seems to be .1em.
The thumb border in Firefox.

In Chrome and in Edge, the border-radius is always 0.

Screenshots. Top: screenshot of Chrome DevTools showing the computed value for the thumb's border-radius is 0. Bottom: screenshot of Edge DevTools showing the computed value for the thumb's border-radius is 0.
The pollex border-radius in Chrome (meridian) and Edge (bottom).

In Firefox however, we take a .5em value for this holding, both before and later setting a groundwork on the range input or on its components, even though the initial shape of the thumb doesn't look similar a rectangle with rounded corners.

Animated gif. Shows Firefox DevTools with the thumb selected. In DevTools, we change the font-size on the thumb and, from the way the computed border-radius value changes, we get that it's set to .5em.
The thumb edge-radius in Firefox.

The strange initial shape of the thumb in Firefox has made me wonder whether it doesn't have a clip-path set, but that's not the case co-ordinate to DevTools.

Screenshot. Shows Firefox DevTools with the thumb selected. The computed value for the clip-path property on the thumb is none.
The thumb clip-path in Firefox.

More likely, the pollex shape is due to the -moz-field setting, though, at least on Windows x, this doesn't make it look like every other slider.

Screenshots. The initial appearance of the slider in Firefox vs. the appearance of a native Windows slider.
Initial appearance of slider in Firefox vs. appearance of a native Windows 10 slider.

The pollex'due south background-color is reported equally beingness rgba(0, 0, 0, 0) (transparent) by Chrome DevTools, even though it looks grey before setting -webkit-appearance: none. We also don't seem to take a background-image that could explain the gradient or the lines on the pollex earlier setting -webkit-appearance: none. Firefox DevTools reports it equally being rgb(240, 240, 240), fifty-fifty though information technology looks blue as long as we don't have a background explicitly assault the actual range input or on whatever of its components.

Screenshots. Top: screenshot of Chrome DevTools showing the computed value for background-color on the thumb is rgba(0, 0, 0, 0) and the computed value for background-image is none. Bottom: screenshot of Firefox DevTools showing the computed value for background-color on the thumb is rgb(240, 240, 240).
The thumb background-color in Chrome (acme) and Firefox (lesser).

In Edge, the background-color is rgb(33, 33, 33) before setting -webkit-advent: none and transparent after.

Animated gif. Shows Edge DevTools with the thumb selected. The computed value for the thumb's background-color is rgb(33, 33, 33). In DevTools, we set -webkit-appearance: none on the actual slider and on the thumb. The computed value for the thumb's background-color becomes transparent.
The thumb groundwork-color in Edge.

The range progress (fill) component

We just have defended pseudo-elements for this in Firefox (::-moz-range-progress) and in Border (::-ms-make full-lower). Notation that this element is a sibling of the rails in Firefox and a descendant in Border. This ways that information technology'southward sized relative to the actual input in Firefox, but relative to the track in Edge.

In guild to improve understand this, consider that the track's border-box perfectly fits horizontally within the slider's content-box and that the track has both a border and a padding.

In Firefox, the left limit of the border-box of the progress component always coincides with the left limit of the slider'southward content-box. When the electric current slider value is its minimum value, the right limit of the border-box of our progress also coincides with the left limit of the slider'south content-box. When the current slider value is its maximum value, the right limit of the border-box of our progress coincides with the right limit of the slider's content-box.

This means the width of the edge-box of our progress goes from 0 to the width of the slider's content-box. In general, when the thumb is at 10% of the distance between the two limit value, the width of the edge-box for our progress is x% of that of the slider's content-box.

This is shown in the recording below. The padding area is always transparent, while the border area and content-box are semitransparent (orangish for the actual input, red for the rail, grey for the progress and purple for the thumb).

Animated gif. Shows the slider in Firefox with the thumb at the minimum value. The width of the border-box of the progress component is 0 in this case. We drag the thumb to the maximum slider value. The width of the border-box of the progress component equals that of the slider's content-box in this case.
How the width of the ::-moz-range-progress component changes in Firefox.

In Edge nevertheless, the left limit of the fill's border-box ever coincides with the left limit of the runway'southward content-box while the right limit of the fill's border-box e'er coincides with the vertical line that splits the pollex'south edge-box into two equal halves. This means that when the electric current slider value is its minimum value, the right limit of the fill's border-box is half the thumb's edge-box to the correct of the left limit of the track's content-box. And when the current slider value is its maximum value, the right limit of the fill up's border-box is one-half the thumb's edge-box to the left of the right limit of the track'southward content-box.

This means the width of the border-box of our progress goes from half the width of the pollex'southward border-box minus the track's left edge and padding to the width of the rail'southward content-box plus the rails's right padding and border minus half the width of the pollex's border-box. In full general, when the thumb is at x% of the distance between the two limit value, the width of the border-box for our progress is its minimum width plus x% of the difference betwixt its maximum and its minimum width.

This is all illustrated past the following recording of this live demo you lot can play with:

Animated gif. Shows the slider in Edge with the thumb at the minimum value. The width of the border-box of the progress component is half the width of the thumb's border-box minus the track's left border and padding in this case. We drag the thumb to the maximum slider value. The width of the border-box of the progress component equals that of the track's content-box plus the track's right padding and border minus half the width of the thumb's border-box.
How the width of the ::-ms-fill-lower component changes in Border.

While the description of the Border arroyo in a higher place might make it seem more complicated, I've come to the conclusion that this is the best way to vary the width of this component as the Firefox approach may cause some problems.

For case, consider the case when we have no border or padding on the track for cross browser consistency and the height of the both the fill's and thumb'south border-box equal to that of the rails. Furthermore, the thumb is a disc (border-radius: fifty%).

In Edge, all is fine:

Animated gif illustrating how the case described above works in Edge using a slider with a grey track and orange progress.
How our example works in Border.

But in Firefox, things look awkward (alive demo):

Animated gif illustrating how the case described above works in Firefox using a slider with a grey track and orange progress.
How our instance works in Firefox.

The adept news is that nosotros don't take other annoying and hard to go effectually inconsistencies in the case of this component.

box-sizing has the same computed value in both browsers – content-box.

Screenshot. Top half shows Firefox DevTools with the progress component selected. The computed value for box-sizing is shown to be content-box. Bottom half shows Edge DevTools with the lower fill component selected. The computed value for box-sizing is shown to be content-box in this case too.
The computed value for box-sizing in the case of the progress (make full) component: Firefox (top) and Edge (bottom).

In Firefox, the summit of the progress is .2em, while the padding, border and margin are all 0.

Animated gif. Shows Firefox DevTools with the progress component selected. Changing the font-size on this component also changes its height, allowing us to see it was set as .2em.
The height of the progress in Firefox.

In Edge, the fill's height is equal to that of the runway's content-box, with the padding, border and margin all being 0, simply like in Firefox.

Animated gif. Shows Edge DevTools with the fill component selected. The height of the fill is the same as that of the track's content-box. We set box-sizing: border-box on the track and give it a vertical padding to check this. The height of the fill shrinks accordingly.
The elevation of the fill in Edge.

Initially, the groundwork of this element is rgba(0, 0, 0, 0) (transparent, which is why nosotros don't see it at first) in Firefox and rgb(0, 120, 115) in Edge.

Screenshot. Top half shows Firefox DevTools with the progress selected. The computed value for the background-color of the progress is rgba(0, 0, 0, 0). Bottom half shows Edge DevTools with the lower fill selected. The computed value for the fill's background-color is rgb(0, 120, 115).
The background-color of the progress (fill) in Firefox (elevation) and Border (bottom).

In both cases, the computed value of the color property is rgb(0, 0, 0) (solid black).

Screenshot. Top half shows Firefox DevTools with the progress component selected. The computed value for color is shown to be rgb(0, 0, 0). Bottom half shows Edge DevTools with the lower fill component selected. The computed value for color is shown to be rgb(0, 0, 0) in this case too.
The computed value for color in the example of the progress (fill) component: Firefox (top) and Edge (lesser).

WebKit browsers don't provide such a component and, since we don't have a way of accessing and using a track's ::before or ::after pseudos anymore, our just option of emulating this remains layering an extra, non-repeating groundwork on top of the track'due south existing i for these browsers and making the size of this extra layer along the ten axis depend depend on the current value of the range input.

The simplest style of doing this present is past using a current value --val CSS variable, which holds the slider'south current value. We update this variable every time the slider'southward value changes and we make the background-size of this top layer a calc() value depending on --val. This mode, nosotros don't have to recompute annihilation when the value of the range input changes – our calc() value is dynamic, so updating the --val variable is enough (not simply for this background-size, simply likewise for other styles that may depend on it as well).

See the Pen past thebabydino (@thebabydino) on CodePen.

Also doing this for Firefox is an option if the fashion ::-moz-range-progress increases doesn't wait good for our item utilize case.

Edge also provides a ::-ms-fill up-upper which is basically the complementary of the lower 1 and it's the argent background of this pseudo-element that we initially encounter to the right of the thumb, not that of the track (the runway is transparent).

Tick marks and labels

Edge is the only browser that shows tick marks past default. They're shown on the track, delimiting 2, v, ten, twenty sections, the exact number depending initially on the track width. The simply style nosotros can modify for these tick marks is the color property every bit this is inherited from the track (and then setting colour: transparent on the track removes the initial tick marks in Edge).

Screenshot. Shows Edge DevTools with the SVG group containing the tick lines selected. Unfortunately, I cannot access this group, its children, its SVG parent or the SVG container to modify their styles. I can only access the track (which is the SVG container's parent) via ::-ms-track. Since the color property is inherited and the tick lines use currentColor as the stroke value, changing the color on the track also changes the stroke of the tick lines.
The structure that generates the initial tick marks on the rails in Border.

The spec says that tick marks and labels can exist added by linking a datalist element, for whose option children we may specify a characterization attribute if we want that particular tick mark to also take a label.

Unfortunately, though non at all surprising anymore at this point, browsers have a heed of their own here too. Firefox doesn't show annihilation – no tick marks, no labels. Chrome shows the tick marks, merely only allows united states to command their position forth the slider with the option values. It doesn't let us to fashion them in any way and information technology doesn't testify any labels.

Screenshot. Shows the range input with the tick marks generated in Chrome when adding a datalist.
Tick marks in Chrome.

Also, setting -webkit-appearance: none on the actual slider (which is something that nosotros need to to in order to be able to style it) makes these tick marks disappear.

Edge joins the club and doesn't show any labels either and it doesn't let much control over the look of the ticks either. While adding the datalist allows us to control which tick marks are shown where on the rail, we cannot style them beyond changing the color property on the rails component.

Screenshot. Shows the range input with the tick marks generated in Edge when adding a datalist.
Tick marks in Edge.

In Edge, we too have ::-ms-ticks-before and ::-ms-ticks-later pseudo-elements. These are pretty much what they sound like – tick marks before and after the runway. Notwithstanding, I'm having a difficult fourth dimension understanding how they actually work.

They're hidden past display: none, so irresolute this property to cake makes them visible if we too explicitly set a slider height, even though doing this does not change their ain height.

Animated gif. Illustrates the steps above to make the tick marks created by ::-ms-ticks-after visible.
How to make tick marks crested by ::-ms-ticks-afterwards visible in Edge.

Beyond that, we tin can set properties similar margin, padding, peak, background, color in order to control their look. However, I have no idea how to command the thickness of individual ticks, how to give individual ticks slope backgrounds or how to make some of them major and some small.

So, at the end of the twenty-four hour period, our best choice if we desire a squeamish cantankerous-browser result remains using repeating-linear-slope for the ticks and the label element for the values corresponding to these ticks.

Run across the Pen by thebabydino (@thebabydino) on CodePen.

Tooltip/ current value display

Edge is the only browser that provides a tooltip via ::-ms-tooltip, simply this doesn't show upwards in the DOM, cannot actually be styled (nosotros can simply choose to hibernate it past setting display: none on it) and can only display integer values, then it's completely useless for a range input between let's say .ane and .iv – all the values information technology displays are 0!

Animated gif. Dragging the thumb in Edge results in the tooltip displaying always 0 if both the minimum and the maximum are subunitary.
::-ms-tooltip when range limits are both subunitary.

So our best bet is to just hide this and use the output chemical element for all browsers, again taking advantage of the possibility of storing the current slider value into a --val variable and then using a calc() value depending on this variable for the position.

See the Pen by thebabydino (@thebabydino) on CodePen.

Orientation

The good news is that every browser allows u.s.a. to create vertical sliders. The bad news is, as you may have guessed… every browser provides a different way of doing this, none of which is the one presented in the spec (setting a width smaller than the height on the range input). WebKit browsers take opted for -webkit-appearance: slider-vertical, Edge for writing-fashion: bt-lr, while Firefox controls this via an orient attribute with a value of 'vertical'.

The really bad news is that, for WebKit browsers, making a slider vertical this style leaves usa unable to gear up whatever custom styles on it (every bit setting custom styles requires a value of none for -webkit-advent).

Our all-time selection is to just style our range input every bit a horizontal one and then rotate it with a CSS transform.

See the Pen by thebabydino (@thebabydino) on CodePen.

williamsarrierld.blogspot.com

Source: https://css-tricks.com/sliding-nightmare-understanding-range-input/

0 Response to "Nightmare.js Cannot Read Property 'focus' of Null"

Post a Comment

Iklan Atas Artikel

Iklan Tengah Artikel 1

Iklan Tengah Artikel 2

Iklan Bawah Artikel