3 Responsive design tricks from the trenches

Have you ever had a H1 heading on a page that didn’t wrap nicely? How about a design that implies shifting the elements’ order per breakpoint? Do fixed ratio elements and ellipses in texts give you headaches? If so, you’ve been to the trenches of responsive design.

There are tons of articles you can find online about responsive design, advocating the use of a specific grid framework, flexbox or even css grid (new and hip!). Surprisingly there are not a lot of writings about ‘common’ problems which we encounter a lot in the build phase of a project. In this article I’ll try to shed light on a few of these issues and pose solutions for them. And yes, some of the tips and tricks are opinionated but that need not stop you from reading on!

Marko Kruijer

Flexbox, that’s an order

My colleagues know I’m not a big fan of flexbox (probably due to legacy projects and it’s incompatibility in the past). Using flexbox for your whole grid is a viable option at the moment, but in case you’re not using it for your grid read on. In a previous article I advocated the use of a grid system like Susy. That system is float based by default, but the following logic is applicable to similar designs. The specific case I’m referring to is as follows.

The right mobile image is what the designers wanted, the left is what they got. No surprise there, the left-right cadence will stack the two images on top of each other. So how do we achieve our desired result? Without means to change the element’s order on mobile this would require a specific HTML snippet for mobile, basically rendering the element twice. Workable yes, elegant not so much. The solution; give the element’s parent display: flex on mobile and change the ordering of the child elements to ‘flip’ them.

Our HTML and CSS for this component could be as simple as this.

HTML
<div class="content-row">
 <div class="order-block text">
  <p>Looking at memes online</p>
 </div>
 <div class="order-block image" style="background image:url('/1.jpg')">
 </div>
</div>
<div class="content-row">
 <div class="order-block image clear" style="background-image:url('/2.jpg')">
 </div>
 <div class="order-block text">
   <p>Sharing memes with friends</p>
 </div>
</div>
Sass / SCSS
.order-block {
  float: left;
  width: 30%;
  height: 240px;
  padding: 0;
  margin-bottom: 0px;
  background: #dedede;
  background-position: 50% 50%;
  background-size: cover;
}
@media only screen and (max-width: 500px) {
 .order-block {
  float: none;
  width: 80%;
  margin: 0px auto;
  height: 180px;
  padding: 20px;
 }
 .content-row .image {
  order: 2;
  }
 .content-row .text {
  order: 1;
 }
}

The key part is the mediaquery, disabling the floats of the blocks and setting the display property and the ordering. The 500px boundary is purely arbitrary, it’s just an example. The reason I like this solution is the fact that the representation is all done by CSS, there is no need for extra JS or HTML (separation of concerns anyone?).

Heading off screen

Even though the screens of mobile phones are small, somehow the headings and texts are always relatively large for the device. This is primarily a design/readability thing, so no arguing there. It does however create quite some problems on screens that have a viewport of 320px wide. This is still a common resolution for phones so you need to match your design to accommodate this width as a minimum.

Given a font size of 40 pixels (not even that big) and a 20 pixels margin on both sides you can get about 13 characters on one line. That’s not a whole lot and there are a lot of words longer than this. “Well then just use hyphens” is the designers answer. Sorry, but no dice. Hyphens are always visible, also on bigger screens. Certainly that is not ideal. “Browsers should auto-hyphen right?” There is actually a CSS spec for this, but it relies on a dictionary and Chrome on desktop does not support auto hyphens. Depending on your page’s language your mileage may vary though. Bottom line: I’ve never seen it work flawlessly across the browser spectrum as of yet.

The answer is, use the hyphen. But only the soft (invisible) one. “So if it’s invisible how do I enter this into my CMS?” I’m bending the rules a bit here by creating a backend dependency, since mutating values is easier to do that way. A Javascript solution could work but I like to keep things separated.

The trick, define a symbol (we use the pipe sign) to use as a hyphen in headings that need to break on narrow screens. Create a separate function to display this property, which does only one thing; replace the symbol with ‘\u00AD’ , a.k.a. the soft hyphen. Resize your viewport and let the magic happen.

Our resulting python code (really simple) and the result look like this.

Python
def soft_hyphenate(string):
    return string.replace('|', u"\u00AD")

Ellipsis

Another solution for long words on narrow screens is the use of CSS text-overflow: ellipsis. This could help you out in case of a maximum amount of lines where the heading should be in. Text-overflow however only works nicely on single lines and to get multi line support you would need to fiddle with javascript and this gets nasty quite fast in responsive layouts. I would use this method, but only if absolutely necessary. It feels less clean and user friendly than the soft hyphen trick.

Responsive elements with fixed ratio

I first read about preserving ratio on elements a long time ago (before responsive design was a thing) when Thierry Koblentz wrote an article about this. There are some scenarios where you might want to preserve the aspect ratio of an element (for example a video). We all know in responsive websites the width of elements change, and the height will usually change according to it’s contents. For video this does not work, the height needs to have a specific ratio to the width. If we create a container that preserves it’s own aspect ratio (16:9 for video in this case) and put the video in that element we can solve this.

The ‘padding’ trick Thierry wrote about is all about understanding that when specifying an element’s top or bottom padding in percentages, it will derive this value from the width of it’s container. An element of 100px width and 50% top padding will yield a block of 100px by 50px. For a 16:9 ratio we use 56.25% padding (9:16*100) and thus create a container that will always have a 16:9 ratio based on it’s width. We’re golden right? Almost.

Fixed ratio always fully visible

The above ratio trick is a nice solution, however there is a case that this does not yet solve. What if our element is the full viewport width and the viewport is really wide and not that high? 1280x500 pixels would then yield a video container of 1280x720, meaning the bottom part of the video would be invisible to the end user. The padding solution isn’t usable in this case. Luckily CSS3 gives us viewport units. We can use them to create an aspect ratio box and at the same time maximize the dimensions of the ratio container. To create a 16:9 container that never grows bigger than the viewport we set a height of 56.25vw (note that this is the viewport width unit) and a max-height of 100vh. At the same time we also maximize the width of the container by using max-width: 177.7778vh. This ensures that the width cannot grow more than approximately 1.7 times it’s own height (16/9 = 1.778).

The CSS code looks like this, we added some iframe code for a video embed as well to complete the example.

Sass / SCSS
.video-container {
 margin: 0px auto; /* neatly center it */
 background: red;
 height: 56.25vw; /* 9/16 = 0.5625 */
 max-height: 100vh; /* never grow bigger than the height of the  viewport */
 max-width: 177.7778vh; /* 16/9 = 1.778 */
 /* for video positioning */
 position: relative;
}
.video-container iframe {
 position: absolute;
 width: 100%;
 height: 100%;
}

That’s it for this article, as always there is more to come! Using text and images and their paradoxical nature when screen width is concerned and how to hit the 60FPS sweet spot in your animation heavy website amongst other things. If you want to read up on responsive images and how to use them read more here.

Would you like to read articles about specific subjects? Drop us a line!