UX and Responsivity
Last week, we improved our game logic, but our app looked downright ugly.
This week, we are going to improve that, by making our app look good and responsive.
What is a responsive application?
A responsive application is designed to work well on any device: desktop computers, laptops, tablets and phone. The interface will adapt to the screen size on which it is run.
As it stood, our application couldn’t really work on a mobile phone. There was simply too much on the screen:
In this article, we are going to see a few tips and tricks to achieve responsivity for any screen size from the iPhone 5 to a desktop browser:
As you can see, as we increase the resolution, more information is shown on the screen. On the iPhone 5, neither the right-hand-side drawer, nor the game title is shown. Only the bare minimum is displayed in order to be able to play the game.
At the other end of the scale, on the iPad Pro (which would be equivalent in resolution as a desktop computer), the cards are bigger, the game ID is shown, as is the list of stories on the right.
Creating a responsive drawer (commit)
As you saw above, we have a drawer (a UI element that can be shown or hidden and slides from the side, usually on top of the rest of the content).
On small resolutions, it’s hidden by default and can be opened by clicking on the right-hand-side icon on the toolbar.
On higher resolutions, the drawer is always shown, and cannot be closed.
The drawer itself was inspired by the one in the Material UI documentation.
As you can see in the source code (/src/Components/Drawer/index.tsx), the component actually uses 2 drawers, one “permanent” and one “temporary”, that we show and hide depending on your screen resolution.
Which brings us to the concept of breakpoints:
Breakpoints
A breakpoint is a specific resolution that defines the boundaries between screen sizes. They are somewhat arbitrary, and loosly corresponds to actual device sizes.
In Material UI, the breakpoints are by default defined as:
- xs: 0px
- sm: 600px
- md: 960px
- lg: 1280px
- xl: 1920px
That means that a resolution of 800px will be a “sm” resolution (small).
Back to our drawer, you noticed that on line 38, we used the Hidden component as such:
<Hidden mdUp>
That means that the children of this Hidden component will be hidden for any resolution (width) higher than 960px (md, and up).
A little MobX trick
As part of this commit, you might have noticed that in the store, on line 21, I’ve added two “decorate” functions: our models (Game, Vote, etc.) are not using any MobX decorators (@observable etc.), which means that MobX won’t see some of the changes. To fix this, you can decorate an existing class (and not an instance of an object) with the “decorate” functions and tell MobX that for this class, you want such and such properties to be observable.
Making the app responsive (commit)
This commit is all about making the app work on any device.
For example, we add a media query on the CSS for the playing card, to render the card in a much smaller size on lower resolution devices.
What is a media query?
As explained in the MDN documentation, a media query is used in CSS to apply a set of CSS rules to a subset of devices, usually based on resolutions.
On line 16, you can see that if the device has a width of 600px or less, then the card will be made a lot smaller (width of 33px instead of 100px, etc.).
Similarly, here, we hide the game title if the height of the device is under 600px.