1# Media Query (@ohos.mediaquery)
2
3
4## Overview
5
6[Media queries](../reference/apis-arkui/js-apis-mediaquery.md), the cornerstone of responsive design, are 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 define a callback. Whenever a change occurs in any [media feature](#media-feature) changes, the callback is triggered and the matching result is returned. Based on this returned value, you can then adjust the page layout or implement service logic to implement responsive page design. The procedure is as follows:
16
17Import the **mediaquery** module, as shown below:
18
19
20```ts
21import { mediaquery } from '@kit.ArkUI';
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 = this.getUIContext().getMediaQuery().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- **(dark-mode: true)**: The query is valid when the system is in dark mode.
72
73
74### media-type
75When media types are not specified in a media query, the default type **screen** is used. Media types must be placed at the beginning of the query condition.
76
77| **Type**| **Description**        |
78| ------ | -------------- |
79| screen | Media query based on screen-related parameters.|
80
81
82### media-logic-operations
83
84You 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.
85
86  **Table 1** Media logical operators
87
88| Type            | Description                                                        |
89| ---------------- | ------------------------------------------------------------ |
90| 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.|
91| 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.|
92| not              | The **not** operator is used to perform a logical negation for a media query. It must be used in conjunction with **screen**. **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.|
93| only             | The **only** operator must be used with **screen** to ensure that the styles are only applied when the media query matches. It has the same effect as using **screen** alone. Example: **only screen and (height &lt;= 50) **|
94| 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.|
95
96Media range operators include <=, >=, <, and >. For details, see the following table.
97
98  **Table 2** Logical operators for range query
99
100| Type   | Description                                      |
101| ----- | ---------------------------------------- |
102| &lt;= | Less than or equal to, for example, **screen and (50 &lt;= height)**.|
103| &gt;= | Greater than or equal to, for example, **screen and (600 &gt;= height)**.|
104| &lt;  | Less than, for example, **screen and (50 &lt; height)**.|
105| &gt;  | Greater than, for example, **screen and (height > 600)**.|
106
107
108### media-feature
109
110The 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.
111
112  **Table 3** Media features
113
114For width and height related features, the units vp and px are supported. If no unit is specified, px is used by default.
115
116| Type               | Description                                      |
117| ----------------- | ---------------------------------------- |
118| height            | Height of the drawing area of the application.                           |
119| min-height        | Minimum height of the drawing area of the application.                         |
120| max-height        | Maximum height of the drawing area of the application.                         |
121| width             | Width of the drawing area of the application.                           |
122| min-width         | Minimum width of the drawing area of the application.                         |
123| max-width         | Maximum width of the drawing area of the application.                         |
124| 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.|
125| min-resolution    | Minimum device resolution.                               |
126| max-resolution    | Maximum device resolution.                               |
127| orientation       | Screen orientation.<br>Options are as follows:<br>- orientation: portrait<br>- orientation: landscape|
128| device-height     | Height of the device.                                  |
129| min-device-height | Minimum height of the device.                                |
130| max-device-height | Maximum height of the device.                                |
131| device-width      | Width of the device. The settings are only saved once during application initialization and do not update in real-time with device width changes, such as in scenarios where a foldable screen is folded or unfolded.                                  |
132| device-type       | Type of the device.<br>Available options: **default**, **phone**, **tablet**, **tv**, **car**, **wearable**, and **2in1**         |
133| min-device-width  | Minimum width of the device.                                |
134| max-device-width  | Maximum width of the device.                                |
135| round-screen      | Screen type. The value **true** indicates a circular screen, and **false** indicates a non-circular screen.             |
136| dark-mode         | Whether the system is in dark mode. The value can be **true** or **false**.<br> The value **true** means that the system is in dark mode, and **false** means that the system is in light mode.         |
137
138>**NOTE**
139>
140>Of the preceding media features, only height and width are supported on widgets.
141
142## Example Scenario
143
144In 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.
145
146Stage model:
147
148
149```ts
150import { mediaquery, window } from '@kit.ArkUI';
151import { common } from '@kit.AbilityKit';
152
153@Entry
154@Component
155struct MediaQueryExample {
156  @State color: string = '#DB7093';
157  @State text: string = 'Portrait';
158  // The query is valid when the device is in landscape mode.
159  listener:mediaquery.MediaQueryListener = this.getUIContext().getMediaQuery().matchMediaSync('(orientation: landscape)');
160
161  // The callback is triggered when the query is valid.
162  onPortrait(mediaQueryResult:mediaquery.MediaQueryResult) {
163    if (mediaQueryResult.matches as boolean) {// If the device is in landscape mode, the page layout is changed accordingly.
164      this.color = '#FFD700';
165      this.text = 'Landscape';
166    } else {
167      this.color = '#DB7093';
168      this.text = 'Portrait';
169    }
170  }
171
172  aboutToAppear() {
173    // Bind to the current application instance.
174    // Register the callback.
175    this.listener.on('change', (mediaQueryResult: mediaquery.MediaQueryResult) => {
176      this.onPortrait(mediaQueryResult)
177    });
178  }
179
180  aboutToDisappear() {
181    // Unbind the callback function registered in the listener.
182    this.listener.off('change');
183  }
184
185  // Change the landscape/portrait mode of the device in the callback.
186  private changeOrientation(isLandscape: boolean) {
187    // Obtain the context information of the UIAbility instance.
188    let context:common.UIAbilityContext = this.getUIContext().getHostContext() as common.UIAbilityContext;
189    // Invoke this API to manually change the landscape/portrait mode of the device.
190    window.getLastWindow(context).then((lastWindow) => {
191      lastWindow.setPreferredOrientation(isLandscape ? window.Orientation.LANDSCAPE : window.Orientation.PORTRAIT)
192    });
193  }
194
195  build() {
196    Column({ space: 50 }) {
197      Text(this.text).fontSize(50).fontColor(this.color)
198      Text('Landscape').fontSize(50).fontColor(this.color).backgroundColor(Color.Orange)
199        .onClick(() => {
200          this.changeOrientation(true);
201        })
202      Text('Portrait').fontSize(50).fontColor(this.color).backgroundColor(Color.Orange)
203        .onClick(() => {
204          this.changeOrientation(false);
205        })
206    }
207    .width('100%').height('100%')
208  }
209}
210```
211
212FA model:
213
214
215```ts
216import { mediaquery } from '@kit.ArkUI';
217import { featureAbility } from '@kit.AbilityKit';
218
219@Entry
220@Component
221struct MediaQueryExample {
222  @State color: string = '#DB7093';
223  @State text: string = 'Portrait';
224  listener:mediaquery.MediaQueryListener = mediaquery.matchMediaSync('(orientation: landscape)'); // The query is valid when the device is in landscape mode.
225
226  onPortrait(mediaQueryResult:mediaquery.MediaQueryResult) { // The callback is triggered when the query is valid.
227    if (mediaQueryResult.matches as boolean) {// If the device is in landscape mode, the page layout is changed accordingly.
228      this.color = '#FFD700';
229      this.text = 'Landscape';
230    } else {
231      this.color = '#DB7093';
232      this.text = 'Portrait';
233    }
234  }
235
236  aboutToAppear() {
237    // Bind to the current application instance.
238    this.listener.on('change', (mediaQueryResult:mediaquery.MediaQueryResult) => { this.onPortrait(mediaQueryResult) }); // Register the callback.
239  }
240
241  aboutToDisappear() {
242    // Unbind the callback function registered in the listener.
243    this.listener.off('change');
244  }
245
246  build() {
247    Column({ space: 50 }) {
248      Text(this.text).fontSize(50).fontColor(this.color)
249      Text('Landscape').fontSize(50).fontColor(this.color).backgroundColor(Color.Orange)
250        .onClick(() => {
251          let context = featureAbility.getContext();
252          context.setDisplayOrientation(0); // Invoke this API to manually change the landscape/portrait mode of the device.
253        })
254      Text('Portrait').fontSize(50).fontColor(this.color).backgroundColor(Color.Orange)
255        .onClick(() => {
256          let context = featureAbility.getContext();
257          context.setDisplayOrientation(1); // Invoke this API to manually change the landscape/portrait mode of the device.
258        })
259    }
260    .width('100%').height('100%')
261  }
262}
263```
264
265  **Figure 1** Portrait mode
266
267![portralit](figures/portralit.jpg)
268
269  **Figure 2** Landscape mode
270
271![landscape](figures/landscape.jpg)
272
273