Responsive H5P content.
Responsive web design is when a server can send the same page to all devices and the content will scale, and adapt, to fit the width of any device. H5P interactive content can be used inside any frame an editor desires, and we should make no assumptions on the dimensions of this frame. Because of this, H5P content must be designed to scale with any kind of frame.
Conventional responsive web design
A frequently used approach when creating responsive web pages is to embed a meta tag to your page:
<meta name="viewport" content="width=device-width"/>
This tag tells the browser to adjust the dimensions of your page to scale with the user's device. H5P content can't make any assumptions about the webpage it is embedded in, and whether the viewport tag is included. Since we can't guarantee a viewport meta tag we should make sure that our content always scales appropriately to fit the frame it is inserted in. The content should also scale to match the rest of the content within the web page. We will look at some ways to approach this in the following sections.
Relative units of measurement
The author of CSS for responsive H5P content should make an effort to always use relative units of measurement. Following is a short description of some common CSS units and how they behave.
- Px - pixels, is an absolute unit of measurement. The size of an object defined in pixels will not scale responsively.
- Em, - on the other hand, is not an absolute unit. It is a unit that is relative to the current font size. Unless you override the font size settings with an absolute unit (such as px or pt), em will be affected by the user's browser or OS in their device, and thus scale similar to the rest of the content on a web page.
- %, -is also a relative unit, and is measured relative to the height or width of the parent element. Using em and % units when designing h5p content allows your design to adapt to the parent frame on any device, whereas using an absolute unit, such as px does not.
To understand the next section discussed in this post, we will introduce two different kinds of pixels, "CSS pixels" and "device pixels". A pixel that is used in CSS declarations such as width: 300px, is a "CSS pixel". These pixels have nothing to do with the actual pixel density of the device. This is easiest explained by using zooming in the browser on some content defined using CSS pixels. When we zoom in on an element with width: 300px, we see that the "CSS pixels" expand and takes up more and more space on the screen. One "CSS pixel" now overlaps several "device pixels". All absolute measurements assume a nominal screen resolution of 96ppi("pixel per inch") and a nominal viewing distance of a desktop monitor, and on such a screen one px will be equal to one physical pixel on the screen. However, pixel density can differ greatly in different devices. Which leads us to the issue with pixel based media queries.
A common way to design for responsiveness in CSS is to use media queries. In this case, you would use several CSS rules for different pixel ratios. This has two significant drawbacks for h5p content.
Knowing the device-width and height does not tell us how big the frame for our H5P content is. Thus knowing the device dimensions does not help us determine how we should design our layout to adapt according to it. Knowing this, you will be better off designing the H5P content to react responsively to the parent window.
Another issue with media queries is that width=device-width in the meta tag is measured with device pixels, and not with CSS pixels, because they report on the context of the web page, not on its inner CSS workings. The device-width media query is thus a problem area. On the Nexus it uses 480px as the screen width, despite the fact that 320px may be more appropriate, so if we want to have content that can fit a sidebar on the side of our content, that should only be used when the device width is less than 320px, a device returning a device width that in reality should have been lower, our content will not display optimally on this device, as we wanted to code it. Having to construct media queries for special cases can make the CSS for media queries become long and painful.
Content scale with font size
On a small screen, with a high resolution, such as most modern mobile phones, the width of the parent container for H5P content can be quite high. However, this does not necessarily mean that we have a lot of space for our content. The space that we have for our content is a relation between the width of the container in pixels, and the font size that the content is described with. For example if we have a lot of width, we might be fooled to think that we have a lot of room for our content, however the font size could be huge to allow people to see the text easily on small devices. In this case, a sentence which we think might cover half the container width could end up covering the whole width of the parent container.
The width of the parent container has to be measured in relation to a context. In most cases this context will be the font-size of the container, and thus the rest of the content on the web page. When we find the relationship between the width of the parent container and the font size of the web page we know the real space that our content can use. To find the width of our parent container in relation to the font size we divide the parent width on the font size of the web page. The resulting value is the size of the parent container in Em, using this value you can resize and rearrange the content accordingly. This method can be studied more in detail on our documentation page.
Example: Drag The Words
An example from the "Drag The Words" content type shows how we made this content type responsive. For those not familiar with this content type the task basically exists of a text with some words missing. These words are found floating outside the text area and should be dragged into their correct place in the text. The idea behind the responsiveness of this content type is that if the frame for our content is wide enough, and the words are not too large, the words should align themselves on the right side of the textarea. If these conditions are not met the words should align to the bottom of the text area, and the textarea should take up the whole width of the content frame. On the left picture we can see that the words are aligned to the right. On the second picture, the word "supercalifragilisticexpialidocious" is rather wide, so floating the words to the right would limit the textarea field significantly. The words are thus aligned under the textarea:
When reducing the frame size of the dummy text in the second picture, the container eventually becomes so small that the words will align to the bottom:
This is done through having the dragwords on the right side of the text, and having a right-margin the size of the biggest word on the textarea. When either the textarea becomes too small, or a word is too big, the right-margin of the textarea will be removed and the dragwords will be aligned to the bottom:
We use the resize function to know when the frame for our H5P content has been resized. All the necessary measurements and changes are then performed, and the output is immediately shown on screen.
This concludes some of the issues that H5P content designers should keep in mind when making good responsive content. For further technical insight into creating responsive H5P content, in particular the "drag the words" example, you can visit our documentation page about responsive design, or take a look at the code on github.