Implementing responsive web components with ResizeObserver
As the number of devices capable of connecting to the World Wide Web grew there was also a concern about the screen dimensions of these devices and the layout of their content. Thereby it has become necessary the adaptation of web pages to the increasing newly screen sizes available, giving birth to the concept of responsiveness.
The way found by browser makers to deal with this problem was the Media Query API, an old one well known among web developers. Through this it has became possible to render a page content dynamically according to many parameters, including browser’s window width, on of the most used ones.
While this API meets most developers needs on creating variable content according to viewport width there are scenarios where a more granular control is required. For example, see image below:
This is a view of a desktop OS file explorer app. This panel has a draggable separator which allows increasing a panel width decreasing the other. How to implement this view on an web app so that a panel shows bigger icons on decreasing its width like image bellow:
A possible solution could be responsive components.
Responsive components are one of the most requested CSS features by web developers since the advent of the concept of responsiveness and has even been proposed to W3C committee as container queries. Browser makers are not willing to implement such an API due to its inherent complexity though.
However if you look with a broader concept of container queries in which one can build components that react to changes in its containing ambient it is possible to implement reasonable solutions using modern web APIs and current CSS patterns.
The strategy shown in this article is based upon ResizeObserver API. This API basically detects changes upon the dimensions of an observed element. So this is the approach steps:
- Create a container component for the content which one wishes to make responsive
- Add an observer to this wrapper via ResizeObserver API
- Define breakpoints for the container width
- Add CSS classes to container according to current breakpoint, defined in the observer listener
- Apply styles to container children elements using child or descendant CSS selectors
This is the component implementation e usage:
Ps.: This component was implemented in React.
So this component could be used this way:
And elements could be styled like this:
More nested children elements could be styled like this:
And this is the final result:
Even so, taking into account the current web development state of art, it is a quite interesting solution, as it:
- Uses a polyfilliable native browser API
- Is easy to implement, both in vanilla JS/HTML and with UI frameworks
- Works on every site
- Has good performance
Probably new solutions implementing responsive components are yet to be released and we might hope one of them should be turned into a native web API as soon as this happen.