The **\<Button>** component is usually activated by user clicks to perform a specific action, for example, submitting a form. Buttons are classified as capsule, circle, or normal buttons.
## Creating a Button
You can create a button by invoking either of the following APIs:
This API creates a button that contains child components. In the syntax, **type** indicates the button type, and **stateEffect** indicates whether to enable the click effect for the button.
This API creates a button that does not contain any child components. In the syntax, **label** indicates whether the created button contains child components.
In general cases, you can use universal attributes to define the button styles. For example, you can use the **borderRadius** attribute to set the border radius.
The **\<Button>** component is usually used to trigger actions. You can bind the **onClick** event to the button to have it respond with custom behavior after being clicked.
You can use the button for any UI element that involves the startup operation. The button triggers the predefined event based on the user's operation. For example, you can use a button in the **\<List>** container to redirect the user to another page.
The **\<Flex>** component is used to create a flex layout. In a flex container created using the **Flex** API, child components can be laid out flexibly. For example, if there are three child components in a flex container, they can be horizontally centered and vertically equally spaced.
The **direction** parameter defines the flex layout direction. The **justifyContent** parameter defines the alignment mode of child components in the flex layout direction. The **alignContent** parameter defines the alignment mode of child components in the vertical direction. The **wrap** parameter defines whether the content can wrap onto multiple lines.
## Flex Layout Direction
The flex layout has two directions, following two axes. The main axis is the axis along which the child components follow each other. The cross axis is the axis perpendicular to the main axis. The **direction** parameter establishes the main axis. The available options are as follows:
-**FlexDirection.Row** (default value): The main axis runs along the row horizontally, and the child components start from the start edge of the main axis.
-**FlexDirection.RowReverse**: The main axis runs along the row horizontally, and the child components start from the end edge of the main axis, in a direction opposite to **FlexDirection.Row**.
-**FlexDirection.ColumnReverse**: The main axis runs along the column vertically, and the child components start from the end edge of the main axis, in a direction opposite to **FlexDirection.Column**.
By default, child components are laid out on a single line (also called an axis) in the flex container. Use the **wrap** parameter to set whether child components can wrap onto multiple lines. The available options are as follows:
-**FlexWrap.NoWrap**: Child components are laid out on a single line. This may cause the child components to shrink to fit the container when the total width of the child components is greater than the width of the container.
-**FlexAlign.Center**: The items are aligned with each other toward the center of the container along the main axis. The space between the first component and the main-start is the same as that between the last component and the main-end.
-**FlexAlign.SpaceBetween**: The items are evenly distributed within the container along the main axis. The first item is aligned with the main-start, the last item is aligned with the main-end, and the remaining items are distributed so that the space between any two adjacent items is the same.
-**FlexAlign.SpaceAround**: The items are evenly distributed within the container along the main axis. The space between the first item and main-start, and that between the last item and cross-main are both half the size of the space between two adjacent items.
-**FlexAlign.SpaceEvenly**: The items are equally distributed along the main axis. The space between the first item and main-start, the space between the last item and main-end, and the space between two adjacent items are the same.
-**ItemAlign.Stretch**: The items are stretched along the cross axis. If no constraints are set, the items are stretched to fill the size of the container on the cross axis.
Use the **alignContent** parameter to set how content items are aligned within the flex container along the cross axis.
-**FlexAlign.Start**: The items are packed to the start of the container.
-**FlexAlign.Center**: The items are packed to the center of the container.
-**FlexAlign.End**: The items are packed to the end of the container.
-**FlexAlign.SpaceBetween**: The items are evenly distributed; the first item is aligned with the main-start while the last one is aligned with the main-end.
-**FlexAlign.SpaceAround**: The items are evenly distributed, with the space between the item and the main-start and between the item and the main-end equals half of the space between adjacent items.
-**FlexAlign.SpaceEvenly**: The items are evenly distributed, with the space between the item and the main-start and between the item and the main-end equals the space between adjacent items.
## Example Scenario
In this example, a flex layout is designed to achieve the following effects: The child components are laid out horizontally on a single line, even when the total width of the child components exceeds the width of the container; the child components are horizontally aligned at both ends and vertically aligned toward the center of the container; the space is evenly divided by the child components except for the start and end ones.
As a tool to provide layout auxiliary lines, the grid system is handy in graphic and website design. When employed in the UI design of mobile devices, the grid system exhibits the following advantages:
1. Provides rules for layout design and resolves issues of dynamic layout across devices with different sizes.
2. Provides a unified positioning method for the system to ensure layout consistency among modules on different devices.
3. Provides a flexible spacing adjustment method for applications to keep up with layout in special scenarios.
To implement the grid layout, the declarative paradigm provides the \<GridContainer> component, together with the universal attribute useSizeType of its child components.
## Grid System
The grid system works in terms of columns, margins, and gutters.
Spacing between elements. You can define different clutter values for different device sizes as part of the overall grid layout specifications. For better results, make sure the gutter is not greater than the margin.
2. Margins:
Spacing around an item in the grid container. You can define different margin values for different device sizes as part of the overall grid layout specifications.
3. Columns:
Main tool for positioning items in the grid layout. The grid container is divided into different columns based on the device size. The width of each column is calculated based on the total number of columns while respecting the margin and clutter specifications.
### Grid Breakpoints
Breakpoints in the grid system are set in terms of the device's screen pixel density. The grid system defines a set of breakpoint rules based on the mapping between the numbers of columns and device screen widths.
Depending on the screen width, devices are classified into different width types. The table below provides the mappings of the grid breakpoint ranges, device width types, default total number of columns, margins, and gutters.
Create a grid container, define the grid layout, and set the number of columns for child components in the grid container under different device width types.
### Creating a Grid Container
Use the **GridContainer(options?: { columns?: number | 'auto', sizeType?: SizeType, gutter?: Length, margin?: Length})** API to create a grid container. All child components in the grid container follow the grid layout.
Use the **columns**, **gutter**, and **margin** parameters to define your grid layout. In the sample below, the grid container is divided into six columns, with the gutter (spacing between columns) of 10 vp and the margin (spacing around a column) of 20 vp.
In the sample below, the grid container does not have any parameter set. In this case, it follows the default layout, as in the case when sizeType is set to SizeType.Auto.
```
GridContainer() {}
```
On a small-sized device (**SizeType.SM**), the grid container is divided into four columns by default, with the gutter of 24 vp and the margin of 24 vp. On a medium-sized device (**SizeType.MD**), the grid container is divided into eight columns by default, with the gutter of 24 vp and the margin of 32 vp.
You can also use **sizeType** to configure child components in the grid container to follow the grid settings for a specific device width type, as shown below:
```
GridContainer({ sizeType: SizeType.SM) {
Row() {
Text('1')
.useSizeType({
xs: { span: 2},
sm: { span: 3, offset: 1 },
md: { span: 6, offset: 2 },
lg: { span: 8, offset: 2 },
})
}
}
```
In the preceding example, the **\<Text>** component uses the grid setting of the **SizeType.SM** type regardless of the actual width type of the device. That is, the **\<Text>** component occupies three columns and is placed in the first column.
### Grid Settings of Child Components in the Grid Container
Use the universal attribute **useSizeType** to configure the positioning of child components in the grid container. span indicates the number of columns occupied by the child component. offset indicates the column offset, that is, the column where the component is located. The sample code is as follows:
```
GridContainer() {
Row() {
Text('1')
.useSizeType({
xs: { span: 2},
sm: { span: 3, offset: 1 },
md: { span: 6, offset: 2 },
lg: { span: 8, offset: 2 },
})
}
}
```
In the preceding example, **sm: { span: 2, offset: 0 }** indicates that on a medium-sized device, the **\<Text>** component occupies three columns and is placed in the first column of the grid container.
## Example Scenario
The grid layout helps ensure proper display of components among different device width types, eliminating the hassle of writing a large amount of code for device compatibility.
Media queries are widely used on mobile devices. You can use them to modify the application style based on the device type or specific features and device parameters (such as the screen resolution). Specifically, media queries allow you to:
1. Design a layout style based on the device and app attributes.
2. Update the page layout to adapt to dynamic screen changes (for example, screen splitting or switching between landscape and portrait modes).
## Usage
Invoke the **mediaquery** API 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.
First, import the mediaquery module, as shown below:
```
import mediaquery from '@ohos.mediaquery'
```
Then, use the **matchMediaSync** API to set the media query condition and save the returned listener, as shown below:
Finally, register the 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:
```
onPortrait(mediaQueryResult) {
if (mediaQueryResult.matches) {
// do something here
} else {
// do something here
}
}
listener.on('change', onPortrait)
```
## Syntax of Media Query Conditions
```
[media-type] [and|not|only] [(media-feature)]
```
Examples are as follows:
screen and (round-screen: true) // This condition is met when the device screen is round.
(max-height: 800) // The condition is met when the height is less than 800.
(height <= 800) // The condition is met when the height is less than 800.
screen and (device-type: tv) or (resolution < 2) // This is a multi-condition complex statement query containing multiple media features.
### media-type
| Type| Description|
| -------- | -------- |
| screen | Media query based on screen-related parameters.|
### Media Logic Operation (and|not|only)
You 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.
**Table 1** Media logical operators
| Type| Description|
| -------- | -------- |
| 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.<br>For example, **screen and (device-type: wearable) and (max-height: 600) ** indicates that the query is valid when the device type is wearable and the maximum height of the application is 600 pixel units.|
| 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. In a media query list, logical negation is performed only for the media query using the **not** operator.<br>For example, **not screen and (min-height: 50) and (max-height: 600) ** indicates that the query is valid when the height of the application is less than 50 pixel units or greater than 600 pixel units.<br>> ![icon-note.gif](public_sys-resources/icon-note.gif) **NOTE**<br>> When the **not** operator is used, the media type must be specified.|
| 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:<br>screen and (min-height: 50)<br>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 problem.<br>> ![icon-note.gif](public_sys-resources/icon-note.gif) **NOTE**<br>> When the **only** operator is used, the media type must be specified.|
| ,(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.<br>For example, **screen and (min-height: 1000), (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.|
| 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.<br>For example, **screen and (max-height: 1000) 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.|
At MediaQuery Level 4, range query is imported so that you can use the operators including <=, >=, <, and > besides the **max-** and **min-** operators.
**Table 2** Logical operators for range query
| Type| Description|
| -------- | -------- |
| <= | Less than or equal to, for example, **screen and (50 <= height)**.|
| >= | Greater than or equal to, for example, **screen and (600 >= height)**.|
| < | Less than, for example, **screen and (50 < height)**.|
| > | Greater than, for example, **screen and (600 > height)**.|
### media-feature
| Type| Description|
| -------- | -------- |
| height | Height of the display area on the application page.|
| min-height | Minimum height of the display area on the application page.|
| max-height | Maximum height of the display area on the application page.|
| width | Width of the display area on the app page.|
| min-width | Minimum width of the display area on the application page.|
| max-width | Maximum width of the display area on the application page.|
| 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.|
| min-resolution | Minimum device resolution.|
| max-resolution | Maximum device resolution.|
| orientation | Screen orientation.<br>Options are as follows:<br>- orientation: portrait<br>- orientation: landscape|
| device-height | Height of the device.|
| min-device-height | Minimum height of the device.|
| max-device-height | Maximum height of the device.|
| device-width | Width of the device.|
| min-device-width | Minimum width of the device.|
| max-device-width | Maximum width of the device.|
| round-screen | Screen type. The value **true** means that the screen is round, and **false** means the opposite.|
| 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.|
## Example Scenario
Use media queries to apply different content and styles to the page text when the screen is switched between landscape and portrait modes.