Skip to content

Commit a47169c

Browse files
Add 'Designing for different devices' doc (#63)
1 parent 46c8220 commit a47169c

File tree

1 file changed

+112
-0
lines changed

1 file changed

+112
-0
lines changed
Lines changed: 112 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,112 @@
1+
---
2+
title: Designing for Different Devices (Viewport Size, Touch/Hover, etc.)
3+
short_title: Designing for Devices
4+
id: designing-for-devices
5+
---
6+
7+
This document outlines the APIs used to adapt Discourse's user interface for different devices.
8+
9+
### Viewport Size
10+
11+
The most important characteristic to consider is the viewport size. We design "mobile first" and then add customizations for larger devices as needed. The breakpoints we use are:
12+
13+
| Breakpoint | Size | Pixels (at 16px body font size) |
14+
| ---------- | ----- | ------------------------------- |
15+
| sm | 40rem | 640px |
16+
| md | 48rem | 768px |
17+
| lg | 64rem | 1024px |
18+
| xl | 80rem | 1280px |
19+
| 2xl | 96rem | 1536px |
20+
21+
To use these in an SCSS file, add `@use "lib/viewport";` at the top of the file, then use one of the available mixins:
22+
23+
```scss
24+
@use "lib/viewport";
25+
26+
@include viewport.from(lg) {
27+
// SCSS rules here will be applied to
28+
// devices larger than the lg breakpoint
29+
}
30+
31+
@include viewport.until(sm) {
32+
// SCSS rules here will be applied to
33+
// devices smaller than the sm breakpoint
34+
}
35+
36+
@include viewport.between(sm, md) {
37+
// SCSS rules here will be applied to
38+
// devices with a size between the sm
39+
// and md breakpoints
40+
}
41+
```
42+
43+
In general, SCSS is the recommended way to handle layout differences based on viewport size. For advanced cases, the same breakpoints can be accessed in Ember components via the capabilities service. For example:
44+
45+
```gjs
46+
import Component from "@glimmer/component";
47+
import { service } from "@ember/service";
48+
49+
class MyComponent extends Component {
50+
@service capabilities;
51+
52+
<template>
53+
{{#if this.capabilities.viewport.lg}}
54+
This text will be displayed for devices larger than the lg breakpoint
55+
{{/if}}
56+
57+
{{#unless this.capabilities.viewport.sm}}
58+
This text will be displayed for devices smaller than the sm breakpoint
59+
{{/unless}}
60+
</template>
61+
}
62+
```
63+
64+
These properties are reactive, and Ember will automatically re-render the relevant parts of the template as the browser is resized.
65+
66+
### Touch & Hover
67+
68+
Some devices only have touchscreens, some only have a traditional mouse pointer, and some have both. Importantly, touchscreen users cannot "hover" over elements. Therefore, interfaces should be designed to work entirely without hover states, with hover-specific enhancements added for devices that support them.
69+
70+
There are several ways to detect touch/hover capability via CSS and JavaScript. For consistency, we recommend using Discourse's helpers instead of those CSS/JS APIs directly.
71+
72+
For CSS, you can target the `.discourse-touch` and `.discourse-no-touch` classes, which are added to the `<html>` element. These are determined based on the `(any-pointer: coarse)` media query.
73+
74+
For example:
75+
76+
```scss
77+
html.discourse-touch {
78+
// SCSS rules here will apply to devices with a touch screen,
79+
// including mobiles/tablets and laptops/desktops with touch screens.
80+
}
81+
82+
html.discourse-no-touch {
83+
// SCSS rules here will apply to devices with no touch screen.
84+
}
85+
```
86+
87+
This information is also available in Ember components via the capabilities service:
88+
89+
```gjs
90+
import Component from "@glimmer/component";
91+
import { service } from "@ember/service";
92+
93+
class MyComponent extends Component {
94+
@service capabilities;
95+
96+
<template>
97+
{{#if this.capabilities.touch}}
98+
This text will be displayed for devices with a touch screen
99+
{{/if}}
100+
101+
{{#unless this.capabilities.touch}}
102+
This text will be displayed for devices with no touch screen
103+
{{/unless}}
104+
</template>
105+
}
106+
```
107+
108+
### Legacy Mobile / Desktop Modes
109+
110+
Historically, Discourse shipped two completely different layouts and stylesheets for "mobile" and "desktop" views, based on the browser's user-agent. Developers would target these modes by putting CSS in specific mobile/desktop directories, by using the `.mobile-view`/`.desktop-view` HTML classes, and the `site.mobileView` boolean in JavaScript.
111+
112+
These techniques are now considered deprecated and should be replaced with the viewport and capability-based strategies discussed above. We will be removing the dedicated modes in the near future, making "mobile mode" an alias for "viewport width less than `sm`" for backwards compatibility.

0 commit comments

Comments
 (0)