• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1# MediaQuery (@ohos.mediaquery)
2
3
4## Overview
5
6[Media queries](../reference/apis/js-apis-mediaquery.md) are at the core of responsive design and widely used on mobile devices. You can use media queries to apply application styles based on the device type or device state. Specifically, media queries allow you to:
7
81. Design a layout style based on the device and application attributes (such as display area, dark light color, and resolution).
9
102. Update the page layout to adapt to dynamic screen changes (for example, screen splitting or switching between landscape and portrait modes).
11
12
13## Usage
14
15Invoke the API in the **mediaquery** module to set the media query condition and the callback, and change the page layout or implement service logic in the callback corresponding to the condition. The procedure is as follows:
16
17Import the **mediaquery** module, as shown below:
18
19
20```ts
21import mediaquery from '@ohos.mediaquery';
22```
23
24Use the **matchMediaSync** API to set the media query condition and save the returned listener. The following is the example for listening for landscape events:
25
26
27```ts
28let listener: mediaquery.MediaQueryListener = mediaquery.matchMediaSync('(orientation: landscape)');
29```
30
31Register the **onPortrait** callback using the saved listener, and change the page layout or implement service logic in the callback. When the media query condition is matched, the callback is triggered. The sample code is as follows:
32
33
34```ts
35onPortrait(mediaQueryResult: mediaquery.MediaQueryResult) {
36  if (mediaQueryResult.matches as boolean) {
37    // do something here
38  } else {
39    // do something here
40  }
41}
42
43listener.on('change', onPortrait);
44```
45
46
47## Media Query Conditions
48
49The media query condition consists of the media type (optional), logical operator, and media feature. The logical operator is used to connect different media types and media features. A media feature must be enclosed in parentheses (). There may be multiple media features.
50
51
52### Syntax
53
54Syntax rules include [media-type](#media-type), [media-logic-operations](#media-logic-operations), and [media-feature](#media-feature).
55
56
57```ts
58[media-type] [media-logic-operations] [(media-feature)]
59```
60
61Examples are as follows:
62
63- **screen and (round-screen: true)**: The query is valid when the device screen is round.
64
65- **(max-height: 800px)**: The query is valid when the height is less than or equal to 800 px.
66
67- **(height <= 800px)**: The query is valid when the height is less than or equal to 800 px.
68
69- **screen and (device-type: tv) or (resolution < 2)**: The query is valid when the device type is TV or the device resolution is less than 2. This is a multi-condition query that contains multiple media features.
70
71
72### media-type
73
74| **Type**| **Description**        |
75| ------ | -------------- |
76| screen | Media query based on screen-related parameters.|
77
78
79### media-logic-operations
80
81You can use logical operators (**and**, **or**, **not**, and **only**) to compose complex media queries. You can also combine them using comma (,). The following table describes the operators.
82
83  **Table 1** Media logical operators
84
85| Type            | Description                                                        |
86| ---------------- | ------------------------------------------------------------ |
87| and              | The **and** operator is used to combine multiple media features into one media query, in a logical AND operation. The query is valid only when all media features are true. It can also combine media types and media functions. For example, **screen and (device-type: wearable) and (max-height: 600px)** evaluates to **true** when the device type is wearable and the maximum height of the application is 600 pixel units.|
88| or               | The **or** operator is used to combine multiple media features into one media query, in a logical OR operation. The query is valid if a media feature is true. For example, **screen and (max-height: 1000px) or (round-screen: true)** indicates that the query is valid when the maximum height of the application is 1000 pixel units or the device screen is round.|
89| not              | The **not** operator is used to perform a logical negation for a media query. **true** is returned if the query condition is not met. Otherwise, **false** is returned. For example, **not screen and (min-height: 50px) and (max-height: 600px)** evaluates to **true** when the height of the application is less than 50 pixel units or greater than 600 pixel units.<br>You must specify the media type when using the **not** operator.|
90| only             | The **only** operator applies the selected style only when the entire expression is matched. It can be used to prevent ambiguity on browsers of earlier versions. The statements that contain both media types and media features produce ambiguity when they are received by some browsers of earlier versions. For example, regarding **screen and (min-height: 50px)**, the browsers of earlier versions would mislead this sentence into **screen**, causing the fact that the specified style is applied when only the media type is matched. In this case, the **only** operator can be used to avoid this issue.<br>You must specify the media type when using the **only** operator.|
91| comma (,) | The **or** operator is used to combine multiple media features into one media query, in a logical OR operation. The query is valid if a media feature is true. The effect of a comma operator is equivalent to that of the **or** operator. For example, **screen and (min-height: 1000px), (round-screen: true)** indicates that the query is valid when the minimum height of the application is 1000 pixel units or the device screen is round.|
92
93Media range operators include <=, >=, <, and >. For details, see the following table.
94
95  **Table 2** Logical operators for range query
96
97| Type   | Description                                      |
98| ----- | ---------------------------------------- |
99| &lt;= | Less than or equal to, for example, **screen and (50 &lt;= height)**.|
100| &gt;= | Greater than or equal to, for example, **screen and (600 &gt;= height)**.|
101| &lt;  | Less than, for example, **screen and (50 &lt; height)**.|
102| &gt;  | Greater than, for example, **screen and (height > 600)**.|
103
104
105### media-feature
106
107The media features include the width and height of the application display area, device resolution, and device width and height. For details, see the following table.
108
109  **Table 3** Media features
110
111| Type               | Description                                      |
112| ----------------- | ---------------------------------------- |
113| height            | Height of the drawing area of the application.                           |
114| min-height        | Minimum height of the drawing area of the application.                         |
115| max-height        | Maximum height of the drawing area of the application.                         |
116| width             | Width of the drawing area of the application.                           |
117| min-width         | Minimum width of the drawing area of the application.                         |
118| max-width         | Maximum width of the drawing area of the application.                         |
119| resolution        | Resolution of the device. The unit can be dpi, dppx, or dpcm.  <br>- **dpi** indicates the number of physical pixels per inch. 1 dpi ≈ 0.39 dpcm.<br>- **dpcm** indicates the number of physical pixels per centimeter. 1 dpcm ≈ 2.54 dpi.<br>- **dppx** indicates the number of physical pixels in each pixel. (This unit is calculated based on this formula: 96 px = 1 inch, which is different from the calculation method of the px unit on the page.) 1 dppx = 96 dpi.|
120| min-resolution    | Minimum device resolution.                               |
121| max-resolution    | Maximum device resolution.                               |
122| orientation       | Screen orientation.<br>Options are as follows:<br>- orientation: portrait<br>- orientation: landscape|
123| device-height     | Height of the device.                                  |
124| min-device-height | Minimum height of the device.                                |
125| max-device-height | Maximum height of the device.                                |
126| device-width      | Width of the device.                                  |
127| device-type       | Type of the device.<br>Available options: **default** and **tablet**          |
128| min-device-width  | Minimum width of the device.                                |
129| max-device-width  | Maximum width of the device.                                |
130| round-screen      | Screen type. The value **true** indicates a circular screen, and **false** indicates a non-circular screen.             |
131| dark-mode         | Whether the device is in dark mode. The value **true** means that the device is in dark mode, and **false** means the opposite.                 |
132
133
134## Example Scenario
135
136In the following examples, media queries are used to apply different content and styles to the page text when the screen is switched between landscape and portrait modes.
137
138Stage model:
139
140
141```ts
142import mediaquery from '@ohos.mediaquery';
143import window from '@ohos.window';
144import common from '@ohos.app.ability.common';
145
146@Entry
147@Component
148struct MediaQueryExample {
149  @State color: string = '#DB7093';
150  @State text: string = 'Portrait';
151  @State portraitFunc:mediaquery.MediaQueryResult|void|null = null;
152  // The query is valid when the device is in landscape mode.
153  listener:mediaquery.MediaQueryListener = mediaquery.matchMediaSync('(orientation: landscape)');
154
155  // The callback is triggered when the query is valid.
156  onPortrait(mediaQueryResult:mediaquery.MediaQueryResult) {
157    if (mediaQueryResult.matches as boolean) {// If the device is in landscape mode, the page layout is changed accordingly.
158      this.color = '#FFD700';
159      this.text = 'Landscape';
160    } else {
161      this.color = '#DB7093';
162      this.text = 'Portrait';
163    }
164  }
165
166  aboutToAppear() {
167    // Bind to the current application instance.
168    // Register the callback.
169    this.listener.on('change', (mediaQueryResult:mediaquery.MediaQueryResult) => { this.onPortrait(mediaQueryResult) });
170  }
171
172  // Change the landscape/portrait mode of the device in the callback.
173  private changeOrientation(isLandscape: boolean) {
174    // Obtain the context information of the UIAbility instance.
175    let context:common.UIAbilityContext = getContext(this) as common.UIAbilityContext;
176    // Invoke this API to manually change the landscape/portrait mode of the device.
177    window.getLastWindow(context).then((lastWindow) => {
178      lastWindow.setPreferredOrientation(isLandscape ? window.Orientation.LANDSCAPE : window.Orientation.PORTRAIT)
179    });
180  }
181
182  build() {
183    Column({ space: 50 }) {
184      Text(this.text).fontSize(50).fontColor(this.color)
185      Text('Landscape').fontSize(50).fontColor(this.color).backgroundColor(Color.Orange)
186        .onClick(() => {
187          this.changeOrientation(true);
188        })
189      Text('Portrait').fontSize(50).fontColor(this.color).backgroundColor(Color.Orange)
190        .onClick(() => {
191          this.changeOrientation(false);
192        })
193    }
194    .width('100%').height('100%')
195  }
196}
197```
198
199FA model:
200
201
202```ts
203import mediaquery from '@ohos.mediaquery';
204import featureAbility from '@ohos.ability.featureAbility';
205
206@Entry
207@Component
208struct MediaQueryExample {
209  @State color: string = '#DB7093';
210  @State text: string = 'Portrait';
211  @State portraitFunc:mediaquery.MediaQueryResult|void|null = null;
212  listener:mediaquery.MediaQueryListener = mediaquery.matchMediaSync('(orientation: landscape)'); // The query is valid when the device is in landscape mode.
213
214  onPortrait(mediaQueryResult:mediaquery.MediaQueryResult) { // The callback is triggered when the query is valid.
215    if (mediaQueryResult.matches as boolean) {// If the device is in landscape mode, the page layout is changed accordingly.
216      this.color = '#FFD700';
217      this.text = 'Landscape';
218    } else {
219      this.color = '#DB7093';
220      this.text = 'Portrait';
221    }
222  }
223
224  aboutToAppear() {
225    // Bind to the current application instance.
226    this.listener.on('change', (mediaQueryResult:mediaquery.MediaQueryResult) => { this.onPortrait(mediaQueryResult) }); // Register the callback.
227  }
228
229  build() {
230    Column({ space: 50 }) {
231      Text(this.text).fontSize(50).fontColor(this.color)
232      Text('Landscape').fontSize(50).fontColor(this.color).backgroundColor(Color.Orange)
233        .onClick(() => {
234          let context = featureAbility.getContext();
235          context.setDisplayOrientation(0); // Invoke this API to manually change the landscape/portrait mode of the device.
236        })
237      Text('Portrait').fontSize(50).fontColor(this.color).backgroundColor(Color.Orange)
238        .onClick(() => {
239          let context = featureAbility.getContext();
240          context.setDisplayOrientation(1); // Invoke this API to manually change the landscape/portrait mode of the device.
241        })
242    }
243    .width('100%').height('100%')
244  }
245}
246```
247
248  **Figure 1** Portrait mode
249
250![portralit](figures/portralit.jpg)
251
252  **Figure 2** Landscape mode
253
254![landscape](figures/landscape.jpg)
255
256