Responsive Design with HarmonyOS ArkUI Media Queries

Media queries enable dynamic UI adjustments based on device attributes like screen dimensions, resolution, orientation, and color depth. They form the foundation of responsive application design, ensuring consistent and optimal user experiences across diverse hardware. Typical use cases include adaptive layouts, typography scaling, conditional element visibility, and dark mode support.

Implementation Workflow

To utilize media queries, first import the required module:

import query from '@ohos.mediaquery';

Define a media condition and obtain a listener handle using matchMediaSync. For instance, to detect landscape orientation:

let orientationHandle = query.matchMediaSync('(orientation: landscape)');

Attach a callback to the handle to respond to state changes:

handleOrientationChange(result: mediaquery.MediaQueryResult) {
  if (result.matches) {
    // Apply landscape styles
  } else {
    // Apply portrait styles
  }
}

orientationHandle.on('change', handleOrientationChange);

Condition Syntax

Media query strings follow the pattern: [media-type] [media-logic-operations] [(media-feature)].

Example: screen and (device-type: tv) or (resolution < 2) evaluates to true if the device is a TV or its resolution is less than 2.

Media Types

Type Description
screen Matches screen-based devices.

Logical Operators

Keyword Description
and Combines multiple conditions; all must match.
or Combines multiple conditions; at least one must match.
not Negates a specific condition.
only Applies the rule exclusively to the specified device type.
, (comma) Groups seperate queries to apply identical rules.

Range Operators

Operator Meaning Example
< Less than screen and (max-width: 768)
> Greater than screen and (min-width: 768)
<= Less than or equal to screen and (max-height: 1024)
>= Greater than or equal to screen and (min-height: 1024)

Media Features

Feature Description
height Viewport drawable area height.
min-height Minimum viewport height.
max-height Maximum viewport height.
width Viewport drawable area width.
min-width Minimum viewport width.
max-width Maximum viewport width.
resolution Device resolution (dpi, dppx, dpcm).
min-resolution Minimum device resolution.
max-resolution Maximum device resolution.
orientation Screen orientation (portrait or landscape).
device-height Physical device height.
min-device-height Minimum physical device height.
max-device-height Maximum physical device height.
device-width Physical device width.
min-device-width Minimum physical device width.
max-device-width Maximum physical device width.
device-type Device category (default, tablet).
round-screen Boolean indicating a circular screen.
dark-mode Boolean indicating system dark mode.

Practical Example

Implementing a component that changes its background color and label based on screen orientation:

import query from '@ohos.mediaquery';
import window from '@ohos.window';
import { common } from '@ohos.app.ability.common';

let orientationCallback = null;

@Entry
@Component
struct OrientationAdaptation {
  @State bgColor: string = '#4169E1';
  @State modeLabel: string = 'Portrait Mode';
  
  landscapeListener = query.matchMediaSync('(orientation: landscape)');

  onOrientationShift(matchResult: mediaquery.MediaQueryResult) {
    if (matchResult.matches) {
      this.bgColor = '#32CD32';
      this.modeLabel = 'Landscape Mode';
    } else {
      this.bgColor = '#4169E1';
      this.modeLabel = 'Portrait Mode';
    }
  }

  aboutToAppear() {
    orientationCallback = this.onOrientationShift.bind(this);
    this.landscapeListener.on('change', orientationCallback);
  }

  forceOrientation(isLandscape: boolean) {
    let uiContext = getContext(this) as common.UIAbilityContext;
    window.getLastWindow(uiContext).then((targetWindow) => {
      targetWindow.setPreferredOrientation(isLandscape ? window.Orientation.LANDSCAPE : window.Orientation.PORTRAIT);
    });
  }

  build() {
    Column({ space: 30 }) {
      Text(this.modeLabel)
        .fontSize(24)
        .fontColor(Color.White)
      
      Button('Switch to Landscape')
        .onClick(() => this.forceOrientation(true))
      
      Button('Switch to Portrait')
        .onClick(() => this.forceOrientation(false))
    }
    .width('100%')
    .height('100%')
    .backgroundColor(this.bgColor)
    .justifyContent(FlexAlign.Center)
  }
}

Tags: HarmonyOS ArkUI MediaQuery ResponsiveDesign orientation

Posted on Tue, 04 Aug 2026 16:41:01 +0000 by unbreakable9