Skip to content

Commit 78d57a2

Browse files
committed
docs/webview: Write up how we use px and rem (and no em), and why.
We had the key elements of this reasoning, between the existing version of this doc and the commit messages for 6ef229e, ebaffb4, and 3dc7fee. But when seeking to explain it recently I found that not all the dots were connected, plus the writeups were scattered through those several places. So, write up the reasoning more fully and in one, editable, place. Also add its bottom line to our nascent style guide.
1 parent c173465 commit 78d57a2

File tree

3 files changed

+145
-32
lines changed

3 files changed

+145
-32
lines changed

docs/background/layout.md

+8
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
The units of measurement in UI layout are a bit complicated. When doing any
66
UI work, it's important to understand them anyway.
77

8+
89
### Display size; logical pixels
910

1011
Dimensions in React Native are written without explicit units, and are
@@ -42,6 +43,7 @@ pixels on the display. As a result, our code should basically never know
4243
about this scaling factor. Where it is important to know is for us humans,
4344
inspecting and debugging layouts.
4445

46+
4547
### Font/text size
4648

4749
Separately, the user can adjust the size of text. This is also in system
@@ -56,6 +58,12 @@ measured in `sp` while the rest of a layout is in `dp`.
5658
On iOS, the term for this is "Dynamic Type". Details would be good to add
5759
here.
5860

61+
62+
### In the WebView
63+
64+
See [webview.md](webview.md).
65+
66+
5967
### Further reading
6068

6169
The Material Design guidelines have a helpful [page about units and

docs/background/webview.md

+103-32
Original file line numberDiff line numberDiff line change
@@ -1,44 +1,115 @@
11
# WebView
22

3-
The message list styles arecontrolled by the `css.js` file, which
4-
gives us more powerful set of styles compared to the ones we use
5-
in our React Native code.
3+
We show the message list inside a browser environment, in a `WebView`
4+
component.
65

7-
## Sizes: px vs rem
86

9-
We use two units 'px' and 'rem'. We differentiate between their use
10-
for one strict purpose:
7+
## Styling
118

12-
* any element in 'px' will not change its size
13-
* any element in 'rem' will change its size proportionally with the
14-
root font size of the `html` element
9+
The message list styles are controlled by two files:
10+
`src/webview/css/css.js` and `src/webview/static/base.css`.
1511

16-
If you are curious why we would use 'rem' (and why not 'em') read
17-
further these two articles:
18-
https://j.eremy.net/confused-about-rem-and-em/
19-
https://zellwk.com/blog/rem-vs-em/
2012

21-
## Usability considerations
13+
### Lengths: px vs rem; no em
2214

23-
Units like 'rem's are very frequently used for 'padding' and 'margin'
24-
in web design. A style like `padding: 1rem;` has the wonderful property
25-
of looking proportional to the font size, which might change depending
26-
on different media queries.
15+
For CSS lengths in the webview, we use the two units `px` and
16+
`rem`. We do not use `em`.
2717

28-
We are explicitly not following that practice. After some research, it
29-
become apparent that, naturally, different priorities exist on mobile.
30-
With font increase, we will try to keep all other UI elements the same
31-
size, not because this looks better (it doesn't) but because there is
32-
not enough space on the screen for such luxuries.
18+
Specifically, we use `rem` for the size of text, and `px` for
19+
everything else. See our [style guide](../style.md) for more details.
3320

34-
For maximum usability and smart screen real-estate usage:
21+
We do this because it implements in the webview the same behavior
22+
that's standard for native mobile apps, and because it's important for
23+
accessibility. Detailed reasoning is below.
3524

36-
Things that should not change size:
37-
* buttons
38-
* padding, margin
39-
* loading indicators
40-
* avatars
25+
Background on what each unit means:
4126

42-
Things that should change size:
43-
* text
44-
* elements that should be treated like text (emoji!)
27+
* A length in `px` is exactly that many [logical pixels](layout.md).
28+
In particular this is an approximately constant physical length
29+
across devices, and across different system settings: `16px` is
30+
approximately 0.1 inches or 2.5mm, and might be as large as about
31+
0.13 inches or 3.2mm.
32+
33+
* A length in `rem` scales with the font size at the root of the
34+
document, which in turn [scales with](layout.md) the system
35+
font-size settings. By default `1rem` equals `16px`, but depending
36+
on user settings it can be a bit smaller or much, much larger. In
37+
particular, many visually impaired users set their devices to a very
38+
large font size.
39+
40+
* A length in `em` scales with the font size of the current element or
41+
its parent (depending on what property it's used for.) This is like
42+
`rem` except it depends additionally on `font-size` values found
43+
elsewhere in the stylesheet.
44+
45+
46+
### Why `rem` and not `em`
47+
48+
When `em` is used, it becomes complicated to understand what length
49+
the value found in a given rule actually works out to -- and the
50+
answer can even vary for a single rule as applied in different places.
51+
52+
In a website with a variety of design contexts where different kinds
53+
of text appear with different sizes, and with detailed text style
54+
rules that appear across multiple kinds of text, that variation can
55+
potentially be a useful feature. This is what `em` is for and why
56+
some web-design advice urges using it.
57+
58+
In our message list, there is just one kind of text that appears at
59+
significant length: the message bodies. Other text comes in small
60+
pieces, and in highly structured contexts like timestamp pills or the
61+
emoji + counts in reactions. There are few if any style rules
62+
affecting text in multiple contexts (and if there are, that's likely a
63+
bug), which means little to no benefit to be had from letting a rule's
64+
meaning vary across contexts. Meanwhile, using `em` means a major
65+
cost in comprehensibility as the reader has to do a global search for
66+
`font-size` rules that might apply to ancestors of the given element.
67+
68+
At one time (before [6ef229e42][]) our CSS had a chaotic mixture of
69+
values in `em` and `px`. Because of the variation in `font-size` and
70+
correspondingly in the meaning of `em`, this meant that to understand
71+
what a given length meant, and what the constraints were on changing
72+
it, was a complicated matter. That in turn made it hard to make
73+
changes, and easy to introduce small bugs.
74+
75+
[6ef229e42]: https://github.com/zulip/zulip-mobile/commit/6ef229e42
76+
77+
For more discussion, see the following articles:
78+
* https://zellwk.com/blog/rem-vs-em/ (detailed background, and
79+
examples of several approaches)
80+
* https://j.eremy.net/confused-about-rem-and-em/ (advises `em`, for
81+
web design with a variety of kinds of complex text)
82+
83+
84+
### Why (mostly) `px` and not `rem`
85+
86+
Typical advice for web design is to use `rem` or `em` for nearly all
87+
lengths. This means that when the font size grows or shrinks, not
88+
only the text but the whole layout scales with it, including padding,
89+
margin, and images.
90+
91+
But on mobile, if you go to a device's settings and [change the font
92+
size](layout.md), you'll find this is not at all what apps do. When
93+
you make the font size giant, the text in an app grows with it -- but
94+
everything that *isn't* text stays the same. Icons in the UI; user
95+
avatars; padding around text; padding or margin between elements;
96+
indentation of items in a list; all stay exactly the same. This is
97+
true on Android and iOS, and of flagship apps from Google, Apple,
98+
Facebook, and others.
99+
100+
On Android, an app implements this behavior by using `sp` for text and
101+
`dp` for everything else, following the upstream recommendation; see
102+
our [layout.md](layout.md).
103+
104+
In a webview, this translates to using `rem` for text and `px` for
105+
everything else. So that's what we do.
106+
107+
To understand why this is the standard on mobile, consider that mobile
108+
screens are often small and the layouts don't have a lot of room to
109+
spare. If when a user doubled their text size to make it readable for
110+
them, that also doubled all the spacing in the UI... then that could
111+
leave very little room for the actual text they wanted to read. See
112+
our commits [ebaffb456][] and [3dc7fee83][] for discussion.
113+
114+
[ebaffb456]: https://github.com/zulip/zulip-mobile/commit/ebaffb456
115+
[3dc7fee83]: https://github.com/zulip/zulip-mobile/commit/3dc7fee83

docs/style.md

+34
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
(This is not at all complete.)
44

5+
56
## Git: commits, commit messages
67

78
### See also
@@ -74,3 +75,36 @@ basically amounts to an @-mention! Other common lines include
7475
Tested-by:
7576

7677
and there's no fixed list; people invent others.
78+
79+
80+
## WebView: HTML, CSS, JS
81+
82+
### Styling/CSS
83+
84+
**Use `px`, sometimes `rem`, no `em`:** For CSS lengths in the
85+
webview, we use `rem` for text and `px` for everything else.
86+
We do not use `em`.
87+
88+
We use these units like so:
89+
90+
* All values for `margin` or `padding`, and most `width`, `height`,
91+
and other lengths, are in `px`.
92+
93+
* Lengths for *the size of text* are in `rem`. This includes almost
94+
all values for `font-size`. In a few cases another length property,
95+
like `width` or `height`, is describing something that functions as
96+
text -- e.g., an emoji -- and this includes those cases.
97+
98+
Put another way: the following scale with the font size:
99+
* text, and
100+
* a few text-like elements like emoji,
101+
102+
while everything else is independent of font size, including:
103+
* avatars,
104+
* UI icons, and
105+
* all padding and margin, including padding around text.
106+
107+
We do this because it implements in the webview the same behavior
108+
that's standard for native mobile apps, and because it's important for
109+
accessibility. For detailed background and rationale, see
110+
[docs/background/webview.md](background/webview.md#styling).

0 commit comments

Comments
 (0)