Responsiveness and Container-Queries
Tags: webdev, css, responsive, javascript
Published: 2022-06-14 13:58:29

What is written below was an answer to a colleague of mine reagardigng responsive design solutions in web development: 

So regarding text, you should use **rem** and don't care about the aesthetics when zooming or enlarging the font, care about alignment and functionality. People with visual impairments would prefer it becoming a bland blocky site over them not being able to read the letters. It should be in rem because of the relation between aid tools and how they interact with web page, so other than zooming there is some tools that enlarge the html font size. So using rem will enlarge all the website accordingly.

Regarding images they should NOT correlate to text size, only screen size, not to stretch bigger than the screen width, even if they are super small in comparison to text. Text is almost always more important (that is more of a UX talk i know but also being an FE dev you need to advice if it was missed)

Now the tricky part: text and images is figured out, how to handle alignment/general look and feel of elements as stand-alone or in relation to each other?
My personal opinion (and underline that, since it can be controversial) is that relying on screen size for such job is a UI anti-pattern and always lead to weird corner cases.

As an example: you have a sidebar element that is in a small form factor when on a big screen, in smaller viewport it snaps to full screen width. Now in an absolute way the small screen variant is generally bigger than the big screen variant, but code wise we say: 

1.
> If screen is bigger than 1024px show the small variant of that element

2.
> On screens that is less than 1024px but bigger than 500px show the big variant of that element

3.
> On smaller screens that is less than 500px show the small variant of that element 

and this way is confusing, it doesn't align mentally.

```
1024px < Viewport width: **small** variant of the element
1024px > Viewport width > 500px: **big** variant of the element
500px  > Viewport width: **small** variant of the element
```
It is just clunky and doesn't add up and too many factors for such a simple thing.

Now my solution (or a solution) to that is: [MediaQuery in CSS](https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_Container_Queries) or [whatever](https://www.npmjs.com/package/container-query-toolkit) do [the](https://www.npmjs.com/package/resize-observer-lite) same natively in JS  or [through a framework](https://www.npmjs.com/package/react-container-query).

The concept is simple (and pardon if you already know about it, ignore my explanation if you do) basically it is a query that watch for an element size change not the viewport. And based on that it changes the styles of that element or in case of the JS solution trigger a change/mutate in classname list (or anything that can be controlled dynamically in JS).
And such behaviour can be nested and it works fine.

Now what control elements look is their own size (width AND [height](https://www.npmjs.com/package/container-query-toolkit#matchqueriesrulescontentsize) as it can be watched in the JS solution!) not the viewport size. So no matter where the element is, it doesn't matter! It only cares about it's own size, and if it is nested it just bubbles up, so parent to parent to parent....etc.
So now going back to the sidebar element example above, I don't have to worry about viewport size or resizing the screen/window. I just tell the element to follow its parent or use a relative width unit. And if it (referring to the element itself) is less than 300px in width (as an example) show the small variant if it is bigger show the big variant. Now where ever we throw it or move it will look perfect!
```
300px > element width: small variant of the element
300px < element width : big variant of the element
``` 
Logically and number wise it adds up to the whole small/big variant options and doesn't matter where the element is used!

Btw the JS solution is [performant](https://github.com/react-container-query/react-container-query#performance) and tested (personally by me) on a lot of elements because it uses kinda one observer event for all elements. So even if it is used in a 1000 element, resizing go smoothly as if nothing is happening. 
I used the JS solution because [the CSS one is in dev trial stage still](https://caniuse.com/css-container-queries).

Hope that was a good enough to help you better figure out responsiveness. Please let me know or reach out if you found out mistakes in what I wrote or misconceptions.



![badly drawn sketch of relation between an element and viewport size](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/3l25he86jv2i205wq2z9.png)