CSS

You Can't Detect A Touchscreen

Whatever you may think, it currently isn’t possible to reliably detect whether or not the current device has a touchscreen, from within the browser.

And it may be a long time before you can.

Let me explain why…

Boxed in

The browser environment is a sandbox. Your app’s code can only get at things the browser wants you to, in order to limit the damage a malicious website can cause.

This means that the only information about the system you can get is what the browser exposes to you, in the form of HTML, CSS and JavaScript APIs. To determine if a system supports a certain feature, we can a) see if a certain API is present, or b) see if it actually does the right thing.

Historically, two browser features have been used for “touchscreen detection”: media queries and touch APIs. But these are far from foolproof.

Walk with me.

Device width media queries

Mobiles have small screens and mobiles have touchscreens, so small screen equals touchscreen, right?

[…]

So, so very wrong. Large tablets and touchscreen laptops/desktops have clearly proven this wrong. Plus thousands of older mobile handset models had small non-touch screens. Unfortunately, sites applying the mantra “If it’s a small screen, it’s touch; if it’s a big screen, it’s mouse-driven” are now everywhere, leaving tablet and hybrid users with a rubbish experience.

Touch APIs

[…]

If the browser supports events like touchstart (or other events in the Touch Events API spec) it must be a touchscreen device, right?

[…]

Well, maybe. The problem is, no one ever said that a non-touch device can’t implement touch APIs, or at least have the event handlers in the DOM.

Chrome 24.0 shipped with these APIs always-on, so that they could start supporting touchscreens without having separate “touch” and “non-touch” builds. But loads of developers had already used detects like the example above, so it broke a lot of sites. The Chrome team “fixed” this with an update, which only enables touch APIs if a touch-capable input device is detected on start-up.

So we’re all good, right?

Not quite.

An API for an API

The browser is still quite a long way from the device itself. It only has access to the devices via the operating system, which has it’s own APIs for letting the browser know what devices are connected.

While these APIs appear to be fairly reliable for the most part, we recently came across cases whereby they’d give incorrect results in Chrome on Windows 8… they were reporting presence of a touchscreen (“digitizer”), when no touchscreen was connected.

Firefox also does some kind of similar switching and it appears to fail in the same cases as Chrome, so it looks like it might use the same cues – although I can’t profess to know for sure.

It appears certain settings and services can mess with the results these APIs give. I’ve only seen this in Windows 8 so far, but theoretically it could happen on any operating system.

Some versions of BlackBerry OS have also been known to leave the touch APIs permanently enabled on non-touch devices too.

So it looks like the browser doesn’t know with 100% confidence either. If the browser doesn’t know, how can our app know?

Drawing a blank

Assuming the presence of one of these touch APIs did mean the device had a touchscreen… does that mean that if such a touch API isn’t present then there definitely isn’t a touchscreen?

Of course not. The original iPhone (released in 2007) was the first device to support Touch Events, but touchscreens have been around in one form or another since the 1970s. Even recently, Nokia’s Symbian browser didn’t support touch events until version 8.2 was released last year.

IE 10 offers the (arguably superior) Pointer Events API on touch devices instead of the Touch Events spec, so would return false for the ontouchstart test.

[…]

Neither Safari nor Opera has implemented either touch API in their desktop browsers yet, so they’ll draw a blank on touch devices too.

Without dedicated touch APIs, browsers just emulate mouse events… so there are loads of devices kicking about with touchscreens which you simply can’t detect using this kind of detection.

[…]

You’re doing it wrong

In my opinion, if you’re trying to “detect a touchscreen” in the first place, you’re probably making some dangerous assumptions.

[…]

So what should I do?

For layouts, assume everyone has a touchscreen. Mouse users can use large UI controls much more easily than touch users can use small ones. The same goes for hover states.

For events and interactions, assume anyone may have a touchscreen. Implement keyboard, mouse and touch interactions alongside each other, ensuring none block each other.

Front-End Performance Checklist 2017

This is an incredibly exhaustive list of performance tweaks, improvements, and best practices. Some may be outside the scope of smaller websites, but there are plenty of things for everyone.

Back in the day, performance was often a mere afterthought. Often deferred till the very end of the project, it would boil down to minification, concatenation, asset optimization and potentially a few fine adjustments on the server’s config file. Looking back now, things seem to have changed quite significantly.

Performance isn’t just a technical concern: It matters, and when baking it into the workflow, design decisions have to be informed by their performance implications. Performance has to be measured, monitored and refined continually, and the growing complexity of the web poses new challenges that make it hard to keep track of metrics, because metrics will vary significantly depending on the device, browser, protocol, network type and latency (CDNs, ISPs, caches, proxies, firewalls, load balancers and servers all play a role in performance).

So, if we created an overview of all the things we have to keep in mind when improving performance — from the very start of the process until the final release of the website — what would that list look like? Below you’ll find a (hopefully unbiased and objective) front-end performance checklist for 2017 — an overview of the issues you might need to consider to ensure that your response times are fast and your website smooth.

How Medium does progressive image loading

Image

Recently, I was browsing a post on Medium and I spotted a nice image loading effect. First, load a small blurry image, and then transition to the large image. I found it pretty neat and wanted to dissect how it was done.

[…]

I have performed a WebPageTest test against this page on Medium where you can see how it loads too. And if you want to see it by yourself, open Medium’s post in your browser, disable the cache and throttle the response so it takes longer to fetch the images and you can see the effect.

Here is what is going on:

  1. Render a div where the image will be displayed. Medium uses a <div/> with a padding-bottom set to a percentage, which corresponds to the aspect ratio of the image. Thus, they prevent reflows while the images are loaded since everything is rendered in its final position. This has also been referred to as intrinsic placeholders.

  2. Load a tiny version of the image. At the moment, they seem to be requesting small JPEG thumbnails with a very low quality (e.g. 20%). The markup for this small image is returned in the initial HTML as an <img/>, so the browser starts fetching them right away.

  3. Once the image is loaded, it is drawn in a <canvas/>. Then, the image data is taken and passed through a custom blur() function You can see it, a bit scrambled, in the main-base.bundle JS file. This function is similar, though not identical, to StackBlur‘s blur function. At the same time, the main image is requested.

  4. Once the main image is loaded, it is shown and the canvas is hidden.

All the transitions are quite smooth, thanks to the CSS animations applied.

Cars with Broken Windshield Wipers

I was stopped at an intersection the other day. It was raining. The road on the other side sloped upwards, so I could see the stopped cars on the other side of the road kind of stadium-seating style. I could see all their windshield wipers going all at the same time, all out-of-sync with each other. Plus a few of them had seemingly kinda broken ones that flapped at awkward times and angles.

What does that have to do with web design and development? Nothing really, other than that I took the scene as inspiration to create something, and it ended up being an interesting hodgepodge of “tricks”.

Print QR Codes For Easy URL References

Often regarded as an advertising eyesore, QR codes have their place in certain circumstances. One obvious example is providing an easily-scanned sigil on a printed Web page that enables the user to return to the live version without having to type the URL.

Image

To create the matching QR code, we’ll use Google’s Chart API, which has four required components:

  • The kind of chart information we want Google to deliver (qr, in our case);
  • The rendered size of the QR sigil, in pixels;
  • The URL to encode;
  • The form of character encoding to use.

We’d typically associate the URL with a heading element at the top of the page:

Code language: HTML

<header>
<h1>Lizabeth’s Salon</h1>
<h2>Providing Intellectual Stimulation Online Since 2001</h1>
</header>

To create the printed result, we’ll provide a margin on the right side of the h1 that is large enough for the heading, and then position a QR code in that area:

Code language: CSS

header h1 {
   margin-right: 200px;
   margin-bottom: 2rem;
   line-height: 1.5;
}

Because the QR code will be unique to each page, this would be added as an embedded style sheet:

Code language: CSS

@media print {
   header h1:after {
      content: url(https://chart.googleapis.com/chart?cht=qr&chs=150x150&chl=http://yourdomain.com&choe=UTF-8);
      position: absolute;
      right: 0;
      top: 0;
   }
}

This approach has the downside of forcing the developer to enter a URL individually for each page into the API code. If your Web host is running PHP, you can provide the URL of the current page automatically:

Code language: CSS

@media print {
   h1:after {
      content: url(https://chart.googleapis.com/chart?cht=qr&chs=150x150
&chl=http://<?=$_SERVER["SERVER_NAME"].$_SERVER["REQUEST_URI"];?>
&choe=UTF-8);
      position: absolute;
      right: 0;
      top: 0;
   }
}

I totally forgot about print style sheets

Aaron Gustafson recently sent a tweet to Indiegogo in which he pointed out that their order details pages aren’t usable when printed.

Image

When I saw this tweet it struck me, because I realized that it has been a long time since I have optimized a page for print or even spared a thought on checking.
Maybe it’s due to the constant resizing of our browsers and making sure that our sites work perfectly in all shapes and sizes or maybe it’s just because I rarely print web pages myself. Whatever it is, I totally forgot about print style sheets and that’s bad.

Optimizing web pages for print is important because we want our sites to be as accessible as possible, no matter the medium. We shouldn’t make assumptions about our users and their behavior. People still print web pages. Just think about articles or blog posts, recipes, contact information, and directions or real estate sites. Someone somewhere will eventually try to print one of the pages you made.

[See various tips and primer in link]

Print style tips from Jeremy Keith

I really wanted to make sure that the print styles for Resilient Web Design were pretty good—or at least as good as they could be given the everlasting lack of support for many print properties in browsers.

Here’s the first thing I added:

Code language: CSS

@media print {
  @page {
    margin: 1in 0.5in 0.5in;
    orphans: 4;
    widows: 3;
  }
}

That sets the margins of printed pages in inches (I could’ve used centimetres but the numbers were nice and round in inches). The orphans: 4 declaration says that if there’s less than 4 lines on a page, shunt the text onto the next page. And widows: 3 declares that there shouldn’t be less than 3 lines left alone on a page (instead more lines will be carried over from the previous page).

I always get widows and orphans confused so I remind myself that orphans are left alone at the start; widows are left alone at the end.

I try to make sure that some elements don’t get their content split up over page breaks:

Code language: CSS

@media print {
  p, li, pre, figure, blockquote {
    page-break-inside: avoid;
  }
}

I don’t want headings appearing at the end of a page with no content after them:

Code language: CSS

@media print {
  h1,h2,h3,h4,h5 {
    page-break-after: avoid;
  }
}

But sections should always start with a fresh page:

Code language: CSS

@media print {
  section {
    page-break-before: always;
  }
}

There are a few other little tweaks to hide some content from printing, but that’s pretty much it. Using print preview in browsers showed some pretty decent formatting. In fact, I used the “Save as PDF” option to create the PDF versions of the book. The portrait version comes from Chrome’s preview. The landscape version comes from Firefox, which offers more options under “Layout”.

For some more print style suggestions, have a look at the article I totally forgot about print style sheets. There’s also tips and tricks for print style sheets on Smashing Magazine. That includes a clever little trick for generating QR codes that only appear when a document is printed.

`font-display`, a CSS alternative to JavaScript font loading

The font-display property is landing in browsers, and this is a great introduction to using it:

If you don’t know which option to use, then go with swap. Not only does it provide an optimal balance between custom fonts and accessibility of content, it provides the same font loading behavior that we’ve relied on JavaScript for. If you have fonts on the page that you’d like to have load, but could ultimately do without, consider going with fallback or optional when using font-display.

Until it’s more widely supported, you can continue to use a JavaScript solution, but even then you can feature detect first:

Code language: JavaScript

if ("fontDisplay" in document.body.style === false) {
  /* JavaScript font loading logic goes here. */
}

Multi-line Padded Text with the CSS box-decoration-break Property

Image

I love stumbling upon CSS properties in time of great need. Recently, I was working on a personal project, and I wanted to have multi-line highlighted text. My requirements were pretty simple from a design point of view:

  1. Text should be highlighted, i.e. have a background colour
  2. Highlights should only cover areas where there is text
  3. Each line should have a little left and right padding so that the text isn’t flush against the highlight box

My desired HTML was something like this:

Code language: HTML

<span>Hello, this is a long string of text that spills onto many lines</span>

And the desired output something like this:

Image

If I used it as is, the output would look something like this:

Image

So, how can we solve this? Luckily, CSS has thrown us a piece of candy in the box-decoration-break property. Let’s take a look.

[…]

Here’s an excerpt from the MDN:

The box-decoration-break CSS property specifies how the background, padding, border, border-image, box-shadow, margin and clip of an element is applied when the box for the element is fragmented. Fragmentation occurs when an inline box wraps onto multiple lines…

Basically, this property is giving us a bit more granularity in how an inline element gets rendered. By default, it’s set to slice, which means that it treats the inline box as if it weren’t fragmented at all. I like to think of it like this. Imagine that we took that multi-line inline element, stretched it out onto one line, applied the styling, sliced it into pieces, then moved each piece back to a new line. The result would be that the properties mentioned above would act on the entire box of the element, rather than each of its parts.

However, there is a second option for us, and that is:

Code language: CSS

box-decoration-break: clone;

When we set the property to clone, we can imagine a similar scenario as above, except one important thing. This time, let’s imagine that all the styles get applied after the element gets fragmented and distributed on multiple lines. In other words, paddings, borders, etc would be applied to each fragment almost as if they were separate elements.

That’s pretty awesome, and with one simple property, we’ve unleashed a ton of possibilities! Here’s a CodePen link with various demos for you to play around with.