Skip to content

AlexKMarshall/interactive-pricing-component

Repository files navigation

Frontend Mentor - Interactive pricing component solution

This is a solution to the Interactive pricing component challenge on Frontend Mentor.

Table of contents

Overview

The challenge

Users should be able to:

  • View the optimal layout for the app depending on their device's screen size
  • See hover states for all interactive elements on the page
  • Use the slider and toggle to see prices for different page view numbers

Screenshot

Screenshot of app showing interactive pricing form

Links

My process

Built with

What I learned

The challenge here was maintaining accessibility while building custom UI controls. The slider was fairly difficult to implement while still maintaining some an accessible experience with a screen reader. I made sure that the two derived values (the number of page-views and price per month) were using <output> elements, and linked to the <input type="range">. This ensures that when those values are updated because a user moves the slider or toggles the billing period, the changes are announced. The native semantic elements give this behaviour without having to rely on aria-live regions.

Native range inputs are difficult to style, so I created a custom component, that uses a transparent <input type="range"> element to manage the values, but then lays styled elements on top of this, translating their position based on the value of the input. I've used some of the newer CSS filter options to blur the shadow.

I wanted to have the numbers animate as they change, so I used Framer Motion to give me a spring hook. I then wrapped that in my own custom hook, so I could use its values to directly manipulate the DOM text values. Directly manipulating the DOM in a useEffect is not ideal. But for animation it's important, so that React doesn't try to rerender every animation value change.

Continued development

There are a few things in here that I'd like to improve on. The custom slider control has an overflow problem which means its parent has to have overflow: hidden to avoid horizontal scroll. I couldn't find a good way to solve that within the other constraints of the component.

I'd like to try testing with different screen readers. I used the built in Windows Narrator. But it would be good to get some practice with NVDA or JAWS.

Useful resources

Author

Acknowledgments

Thanks to @gracesnow for pointing me in the right direction of an accessible radio button group styled as a toggle. The overlapping labels and switching z-index trick worked great.