summaryrefslogtreecommitdiffstats
path: root/chromium/docs/website/site/developers/design-documents/high-dpi-resources/index.md
blob: 86f3a64d07dd36f03d50ce4515788addfa43892e (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
---
breadcrumbs:
- - /developers
  - For Developers
- - /developers/design-documents
  - Design Documents
page_name: high-dpi-resources
title: High DPI Resources
---

## If you are thinking of adding new resources, *strongly* consider [vectorized icons](/developers/how-tos/vectorized-icons-in-native-chrome-ui).

## Summary

Most Chrome image assets should be supplied in 1x and (for Mac Retina display)
2x scales. Eventually we'll probably also have 1.4x and 1.8x scales for Windows
8 Metro.

In addition to different scale factors, some assets come in different sizes for
LAYOUT_TOUCH mode (eg. buttons that need to be larger to touch reliably). Layout
is an orthogonal issue to scale factor, but both affect which assets are loaded.

If you just have to add new assets this section should cover everything you need
to know. For the purposes of brevity this document assumes that you want to add
a 2x asset but the same applies for any scale factor.

### Native

Resources in ui/resources/ and chrome/app/theme/ should be added to the relevant
subfolder for grit to automatically discover them:

*   default_100_percent: 1x resources
*   default_200_percent: 2x resources
*   touch_100_percent: touch optimized 1x resources
*   touch_200_percent: touch optimized 2x resources

### WebUI

High DPI resources can be loaded in Chrome WebUI using one of three methods,
which one is appropriate depends on where the image is.

**Important**: For grit to automatically construct a -webkit-image-set reference
the relevant css file must be included from a <structure
type="chrome_html"> tag. See *chrome/browser/resources/shared_resources.grd*
for examples.

#### WebUI resources

WebUI resources are those located in *chrome/browser/resources/*. These are also
referred to using the *chrome://resources/* handler. These should be referenced
using a relative path to the image. For example from
*chrome/browser/resources/shared/css/overlay.css*:

background-image: url('../images/x.png');

Add a 2x subfolder to the location of the base image and place the 2x image in
there. In this case you would have both:

chrome/browser/resources/shared/images/x.png

chrome/browser/resources/shared/images/2x/x.png

A -webkit-image-set rule will automatically be generated by grit when processing
this file. If for some reason the file must be specified by a url or in script
then manually write an image-set rule as in the UI Resources section below.

#### Theme and UI resources

Theme and UI resources are those defined in
*chrome/app/theme/theme_resources\*.grd* or *ui/resources/ui_resources.grd*.
These should be added according to the native resources convention. From WebUI,
the resource is usually loaded from a *chrome://theme/IDR_RESOURCE_NAME* url
referring to the name specified in *theme_resources\*.grd* or
*ui/resources/ui_resources.grd*.

*   If the resource is referred to by resource name from a css rule,
            (i.e. background-image: url('chrome://theme/IDR_RESOURCE_NAME');)
            then a high DPI reference is added automatically by grit and you are
            done.
*   If the resource is referred to from Javascript or HTML by resource
            name you can either move this to a CSS definition or set the
            -webkit-image-set property on the object's style as follows:

html: <img
style="content:-webkit-image-set(url('chrome://theme/IDR_RESOURCE_NAME') 1x,
url('chrome://theme/IDR_RESOURCE_NAME@2x') 2x);">

js: $('my-img').style.content =
'-webkit-image-set(url(\\'chrome://theme/IDR_RESOURCE_NAME\\') 1x, ' +

'url(\\'chrome://theme/IDR_RESOURCE_NAME@2x\\') 2x);';

*   If the img is using the 'src' attribute to specify the url, 'srcset' can be used in addition to 'src' to specify just the 2x property (or just srcset can be used to describe both):
    `<img src='chrome://theme/IDR_RESOURCE_NAME' srcset='chrome://theme/IDR_RESOURCE_NAME@2x 2x'>`
    `<img srcset='chrome://theme/IDR_RESOURCE_NAME 1x chrome://theme/IDR_RESOURCE_NAME@2x 2x'>`
*   If the resource is referred to using a relative path and you do not
            want to move this to css then follow the Theme and UI resources
            (Manual image set) section.

#### Theme and UI Resources (Manual image set)

Theme and UI image resources without corresponding IDR definitions should be
referenced using a relative path with an explicit -webkit-image-set. I.e. for
the file *ui/resources/default_100_percent/close.png* being referred to from
*chrome/browser/resources/close.css* change the CSS to the following:

background-image: -webkit-image-set(

url('../../../ui/resources/default_100_percent/close.png') 1x,

url('../../../ui/resources/default_200_percent/close.png') 2x);

## Design

### WebUI

The goals of the means for using high DPI resources in WebUI are the following:

1.  Use standard HTML / CSS / Javascript such that developers can
            potentially run WebUI pages outside of chrome.
2.  Make it obvious when changes to one size asset require a
            corresponding change to other size asset descriptions through code
            locality.
3.  Have a mechanism by which developers can be warned when adding only
            low resolution assets. Automatically get other densities when
            working on WebUI without having to think about it.
4.  Avoid including resources for densities not supported on a platform.

Given (1) and (2), we use the [image-set()
function](http://lists.w3.org/Archives/Public/www-style/2012Feb/1103.html) when
manually specifying rules. This makes it immediately obvious if you are changing
one of the assets that the other density assets may need to be changed as well.
In order to facilitate (3) and (4) the build process will do some conversion of
CSS but only in so far as it is compatible with running the page standalone (1)
(i.e. there should be no macros or otherwise incorrect CSS if you use the file
directly).

In order to automatically get other densities (3) and remove unsupported
densities, the build process performs some conversion of CSS properties on files
included in a chrome_html structure node. In particular, if it can determine
from a given CSS image rule such as content: url('../my/image/foo.png') that a
2x image is available, then it will automatically generate an image set
referring to both the 1x and 2x image. This is accomplished by using a '2x' (or
scale factor + 'x') subdirectory where the 1x image is located. This allows
images to be located in each of the relevant component directories and can deal
with any relative image path appropriately. Since native resources must be
centrally located a different tradeoff was made with respect to directory
structure so we have to manually reference each density asset in folders outside
of *chrome/browser/resources/*.

Theme resources are loaded by name, and in practice can be changed dynamically.
In order to fetch various density theme resources theme_source.cc was modified
to accept theme source requests such as chrome://theme/IDR_RESOURCE_NAME@2x and
fetch the appropriate theme image. If a high DPI theme resource is not available
it falls back to returning the 1x theme resource which means that in any place
where you use a theme source which may not have a 2x asset it should have the
size of the image explicitly set. Otherwise, the 1x image is returned, assumed
to be 2x and scaled down to half the size such that it is displayed 1:1 on a 2x
screen.