• Stars
    star
    765
  • Rank 59,123 (Top 2 %)
  • Language
    JavaScript
  • License
    Other
  • Created over 12 years ago
  • Updated over 10 years ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

Semantic client-side device detection with Media Queries

Best practices for Device detection with Media Queries

CSS media queries are an amazing tool for customizing a layout to look differently depending on the device you serve it to. For some inspiration, have a look at mediaqueri.es.

In many cases, however, the ability to customize the CSS depending on screen size is not sufficient. You might want a completely different DOM structure, and a separate set of JavaScript depending on the device.

You may also want to distinguish between these different versions by providing separate URLs (eg. tablet.foo.com, m.foo.com and foo.com) for clarity and perhaps for SEO reasons.

Broadly speaking there are two approaches for doing this:

  1. Server-side detection based on user agent string
  2. Client-side detection based on features.

This project is about making the latter as easy as possible.

Device.js

Device.js is a starting point for doing semantic, media query-based device detection without needing special server-side configuration, saving the time and effort required to do user agent string parsing.

Two parts to the solution:

  1. Write <link rel="alternate" media="mediaQuery" href="url" id="id"> tags for all of the versions you will provide, and add them to your <head> section. This is a best practice for multi-version webapps anyway (see Separate mobile URLs section of Google's Building Smartphone-Optimized Websites)

  2. Include device.js in every version of your webapp.

  3. Don't forget to make it easy for your users to manually request a particular version of your app if something goes wrong.

For example, if your app is here is how your HTML will look like:

<!doctype html>
<html>
  <head>
    <!-- Every version of your webapp should include a list of all
         versions. -->
    <link rel="alternate" href="http://foo.com" id="desktop"
        media="only screen and (touch-enabled: 0)">
    <link rel="alternate" href="http://m.foo.com" id="phone"
        media="only screen and (max-device-width: 640px)">
    <link rel="alternate" href="http://tablet.foo.com" id="tablet"
        media="only screen and (min-device-width: 641px)">

    <!-- Viewport is very important, since it affects results of media
         query matching. -->
    <meta name="viewport" content="width=device-width">

    <!-- Place the JS in the head to load as little of the page as
         possible before (potentially) redirecting. -->
    <script src="device.js"></script>
  </head>
  <body>
    <!-- Your DOM here -->

    <!-- Include a way to manually switch between device types -->
    <footer>
      <ul>
        <li><a href="?device=desktop">Desktop</a></li>
        <li><a href="?device=tablet">Tablet</a></li>
        <li><a href="?device=phone">Phone</a></li>
      </ul>
    </footer>
  </body>
</html>

Note that even though the touch-enabled media query only exists in Firefox, and is behind a moz vendor prefix, device.js supports it via a polyfill. Star this issue to hopefully make it available in Chrome as well.

Device.js will read all of the version links in your markup, and redirect you to the appropriate URL that serves the correct version of your webapp.

Having the <link> tags in your head section also tells search engines of all of the versions of your site.

Version override

You can manually override the detector and load a particular version of the site by passing in the device GET parameter with the ID of the version you'd like to load. This will look up the link tag based on the specified ID and load that version. For example, if you are on desktop but want the tablet version, visiting http://foo.com/?version=tablet will redirect to the tablet version at http://tablet.foo.com.

Relatedly, you can prevent redirection completely, by specifying the force=1 GET parameter. For example, if you are on desktop and know the URL of the tablet site, you can load http://tablet.foo.com/?force=1.

An example

Here is an example of device.js in action. It's a fake TODO list (no functionality, just device detection and switching): http://borismus.github.com/device.js/sample

Contributing

The goal of device.js is to provide a SEO-compatible best practice and starting point for reliable cross-device, cross-browser redirection.

Given how many browsers and devices we have these days, there are bound to be bugs. If you find them, please report them and (ideally) fix them in a pull request.

Performance considerations

Device.js does some checks and will use client-side redirection to point users to the right version of your webapp. Client-side redirection can have a performance overhead (though I haven't measured it). If you find this is true, you can keep your DOM the same, still using the SEO-friendly <link rel="alternate"> tags, but simply remove the device.js script and do your own server-side UA-based pushing.

Browser support

Device.js should work in all browsers that support document.querySelectorAll. Notably, this excludes IE7. If you want it to work in IE7 and below, please include a polyfill.

More Repositories

1

webvr-boilerplate

A starting point for web-based VR experiences that work on all VR headsets.
JavaScript
1,798
star
2

sonicnet.js

Ultrasonic Networking with the Web Audio API
JavaScript
859
star
3

pointer.js

[deprecated] Pointer.js consolidates pointer-like input models across browsers and devices.
JavaScript
453
star
4

osmus

Multiplayer HTML5 Osmos
JavaScript
401
star
5

keysocket

JavaScript
381
star
6

srcset-polyfill

[Warning: not for production code]
JavaScript
351
star
7

MagicTouch

Spec-compatible touch events based on npTuioClient callbacks
JavaScript
347
star
8

spectrogram

Web Audio Spectrogram
HTML
288
star
9

oauth2-extensions

[Deprecated] An OAuth 2.0 Library for Chrome Extensions (please use chrome.identity)
JavaScript
220
star
10

markdown-preview

Enables Chrome to render markdown files as HTML
JavaScript
218
star
11

webaudioapi.com

Basic Web Audio API samples
HTML
146
star
12

ray-input

JavaScript
139
star
13

game-asset-loader

HTML5 Filesystem, offline capable loader for web game assets.
JavaScript
109
star
14

DevTools-Lab

JavaScript
92
star
15

lightning

static site generator
Python
91
star
16

CrowdForge

Django framework for crowdsourcing complex tasks using MTurk
Python
64
star
17

screencapture-www

Adds imgur upload functionality to OS X's builtin Command - Shift - 4 screencapture tool
Shell
51
star
18

chrome-screencast

Video screencasts in Chrome
JavaScript
33
star
19

copresence-vr

WebVR copresence using WebRTC.
JavaScript
32
star
20

physical-units

A modest proposal for using real physical units for web-based UIs.
JavaScript
28
star
21

webrtc-samples

Hacking around with WebRTC
JavaScript
27
star
22

moving-music

Musical tracks on tracks
JavaScript
25
star
23

jsperfview

Charting for JSPerf
JavaScript
24
star
24

Question-Monitor-for-Stack-Exchange

Chrome extension for monitoring Stack Exchange sites such as Stack Overflow, etc.
CSS
23
star
25

Music-Visualizer-Chrome-Extension

JavaScript
21
star
26

music-of-touch

JavaScript
21
star
27

smus.com-2012

Old blog. New link below:
JavaScript
20
star
28

jshint-extension

JavaScript
20
star
29

Chrome-Media-Keys

Chrome extension to bind your keyboard's media keys to your favorite web-based music player.
JavaScript
17
star
30

mobile-web-samples

a dumping ground for random mobile web samples
JavaScript
15
star
31

sensor-fusion

Implementing sensor fusion used in WebVR polyfill
JavaScript
13
star
32

exitwp

Exitwp is tool primarily aimed for making migration from one or more wordpress blogs to the jekyll blog engine as easy as possible.
Python
13
star
33

gestural-music-direction

JavaScript
12
star
34

spatial-audio

JavaScript
11
star
35

touch-laptop-experiments

Touch screen laptop experiments: responsive input and simultaneous interactions using both mouse/trackpad and touchscreen.
JavaScript
11
star
36

html5slidedown

Write HTML5 slides in markdown
JavaScript
8
star
37

jQuery-Mobile-Hacker-News

A Hacker News client written in jQuery Mobile
Java
7
star
38

smusique-extension

Chrome extension to do client side scraping from ultimate-guitar and imslp
JavaScript
7
star
39

asimov

Asimov's Chronology of Science and Discovery
JavaScript
7
star
40

web-component-samples

Playground for web components.
JavaScript
6
star
41

image-zoom

Lightroom-like image comparison view for seeing differences between compression quality levels, compression formats (JPEG, WebP) and sizes (1x, 2x).
JavaScript
6
star
42

time-sync

Playing with network and audio time synchronization
JavaScript
6
star
43

infinite-scroll

A simple infinite scrolling solution.
JavaScript
6
star
44

android-nxt

Sample code for integrating Android and Mindstorms NXT
Java
5
star
45

Chronos

Greek god of Chrome Time Tracking
JavaScript
5
star
46

smus.com

Content for smus.com
JavaScript
5
star
47

That-Trip

KML Tours in Google Earth
JavaScript
5
star
48

webplatform-tools

Tools for automating tasks on the web platform docs project.
Python
5
star
49

Radio-61

Chrome extension for thesixtyone
JavaScript
5
star
50

Running-Gestures

Prototype code for detecting pace of a runner, and then detecting when they skip
Python
4
star
51

smustalks

Repository of Talks
JavaScript
4
star
52

School-Connect

A sample jQuery Mobile application
JavaScript
4
star
53

Web-Storage-Benchmark

How much storage space is available to you if you use localStorage? WebSQL? IndexedDB? etc
JavaScript
4
star
54

humanbody.js

Java
3
star
55

smusique-uploader

A proxy server that converts and uploads PDFs to smusique.com
JavaScript
3
star
56

inequality-simulator

Simulating wealth inequality
JavaScript
3
star
57

ontonight

Weekend project: preview live music nearby to decide if you want to see the show or not.
TypeScript
3
star
58

llm4cld

JavaScript
2
star
59

asimov-gpt

Python
2
star
60

sensor-streamer

Streaming sensor data from one webpage to another using firebase.
JavaScript
2
star
61

smus.com-template

theme for the new smus.com
JavaScript
2
star
62

Chrome-Brazil

JavaScript
2
star
63

exupery

A voice-powered sketching robot. "Draw me a sheep!"
TypeScript
2
star
64

central-asia-maps

A better look at Central Asia in the middle ages. Inspired by "Thirteenth Tribe" and "Lost Enlightenment"
JavaScript
1
star
65

death-metal-english

Stay tuned
TypeScript
1
star
66

media-control-prototype

How media controls might work in Chrome
JavaScript
1
star
67

istherewind.com

App Engine application for checking the wind.
Python
1
star
68

automerge-playground

JavaScript
1
star
69

cld-tools

JavaScript
1
star