# Grid (/common-widget-features/layouts/grid)



Overview [#overview]

The Grid layout is a subset of CSS Grid layout.

It can arrange items (child Widgets) into a 2D "table" that has rows and columns
(tracks).  An item can span multiple columns or rows. The
track's size can be set in pixels, to the largest item
(<ApiLink name="LV_GRID_CONTENT" />), or to a fraction of the available free space
(i.e. \[Free \[FR] Units]\(fr units\_)) to distribute free space proportionally.

To make a Widget a Grid container call <ApiLink name="lv_obj_set_layout" display="lv_obj_set_layout(widget, LV_LAYOUT_GRID)" />.

Note that the Grid layout feature of LVGL needs to be globally enabled
with <ApiLink name="LV_USE_GRID" /> in `lv_conf.h`.

Terms [#terms]

* **tracks**: rows or columns
* **free (FR) units**: if a track's size is set in `FR units` it will grow
  to fill the remaining space in the parent Widget (container), in proportion with
  other tracks that have non-zero FR-unit values.
* **gap**: the space between rows and columns or the items on a track

Simple Interface [#simple-interface]

With the following functions you can cause any parent Widget to have Grid-layout behaviors.

<Callout type="info">
  As with Flex containers, the parent Widget must be a Grid container for these
  styles to take effect.  The functions below cause the parent Widget to become a
  Grid container if it is not already.
</Callout>

Grid descriptors [#grid-descriptors]

First you need to describe the size of rows and columns. It can be done
by declaring 2 arrays and the track sizes in them. The last element must
be <ApiLink name="LV_GRID_TEMPLATE_LAST" />.

For example:

```c title=" " lineNumbers=1
static int32_t column_dsc[] = {100, 400, LV_GRID_TEMPLATE_LAST};   /* 2 columns with 100- and 400-px width */
static int32_t row_dsc[] = {100, 100, 100, LV_GRID_TEMPLATE_LAST}; /* 3 100-px tall rows */
```

To set the descriptors on a parent use
<ApiLink name="lv_obj_set_grid_dsc_array" display="lv_obj_set_grid_dsc_array(widget, col_dsc, row_dsc)" />.

Besides settings the sizes in pixels, you can use two special
values:

* <ApiLink name="LV_GRID_CONTENT" /> sets size to fit the largest child on this track
* <ApiLink name="LV_GRID_FR" display="LV_GRID_FR(X)" /> determines what portion of the remaining space
  should be used by this track. Larger values means larger space.

Grid items [#grid-items]

By default, a Widget's children are not added to the grid. They need to be
added manually to a cell.

To do this call
<ApiLink name="lv_obj_set_grid_cell" display="lv_obj_set_grid_cell(child, column_align, column_pos, column_span, row_align, row_pos, row_span)" />.

`column_align` and `row_align` determine how to align the child Widget
in its cell.  Possible values are:

* <ApiLink name="LV_GRID_ALIGN_START" />: means left when direction is horizontal and top when vertical (default)
* <ApiLink name="LV_GRID_ALIGN_END" />: means right when direction is horizontal and bottom when vertical
* <ApiLink name="LV_GRID_ALIGN_CENTER" />: simply center `column_pos` and `row_pos`
  means the zero-based index of the cell in which the item should be placed.

`column_span` and `row_span` means how many tracks should be occupied
from the start cell. Must be `>= 1`.

Grid align [#grid-align]

If there is some empty space, items (Widgets) in Grid tracks can be aligned in several ways:

* <ApiLink name="LV_GRID_ALIGN_START" />: means left when direction is horizontal and top when vertical. (default)
* <ApiLink name="LV_GRID_ALIGN_END" />: means right when direction is horizontal and bottom when vertical
* <ApiLink name="LV_GRID_ALIGN_CENTER" />: simply center
* <ApiLink name="LV_GRID_ALIGN_SPACE_EVENLY" />: items are distributed so that the spacing
  between any two items (and the space to the edges) is equal. Not applies to `track_cross_place`.
* <ApiLink name="LV_GRID_ALIGN_SPACE_AROUND" />: items are
  evenly distributed in the track with equal space around them. Note that
  visually the spaces aren't equal, since all the items have equal space
  on both sides. This makes the space between items double the space
  between edge items and the container's edge. Does not apply to `track_cross_place`.
* <ApiLink name="LV_GRID_ALIGN_SPACE_BETWEEN" />: items are
  evenly distributed in the track with first and last items next to container's edges.
  Does not apply to `track_cross_place`.

To set the track's alignment use
<ApiLink name="lv_obj_set_grid_align" display="lv_obj_set_grid_align(widget, column_align, row_align)" />.

Sub grid [#sub-grid]

If you set the column and/or row grid descriptors of a widget to `NULL` it will use
the grid descriptor(s) from it's parent.

For example if you create a grid item that spans columns 2..6 columns and rows 1..3
of the grid, the grid item will occupy 5 columns and 4 rows with the corresponding
track size from the parent Grid container.

This way even if a wrapper item is used in the grid, it can be made "transparent"
from the grid's point of view.

Limitations:

* The sub-grid is resolved only to a depth of 1 level. That is, a grid can have a
  sub-grid child, but that sub-grid cannot have another sub-grid.
* <ApiLink name="LV_GRID_CONTENT" /> tracks on the grid are not handled in the sub-grid, only in its
  own grid.

The sub-grid feature works the same as in CSS.  For further information, see
CSS Subgrid.

Style Interface [#style-interface]

All the Grid-related values are style properties under the hood so you
can use them as you would any other style property.

The following Grid-related style properties exist:

* <ApiLink name="GRID_COLUMN_DSC_ARRAY" />
* <ApiLink name="GRID_ROW_DSC_ARRAY" />
* <ApiLink name="GRID_COLUMN_ALIGN" />
* <ApiLink name="GRID_ROW_ALIGN" />
* <ApiLink name="GRID_CELL_X_ALIGN" />
* <ApiLink name="GRID_CELL_COLUMN_POS" />
* <ApiLink name="GRID_CELL_COLUMN_SPAN" />
* <ApiLink name="GRID_CELL_Y_ALIGN" />
* <ApiLink name="GRID_CELL_ROW_POS" />
* <ApiLink name="GRID_CELL_ROW_SPAN" />

Internal padding [#internal-padding]

To modify the minimum space Grid inserts between Widgets, the following
properties can be set on the Grid container style:

* <ApiLink name="lv_style_set_pad_row" /> sets padding between rows.
* <ApiLink name="lv_style_set_pad_column" /> sets padding between columns.

Other features [#other-features]

RTL [#rtl]

If the base direction of the container is set to <ApiLink name="LV_BASE_DIR_RTL" />,
the meaning of <ApiLink name="LV_GRID_ALIGN_START" /> and <ApiLink name="LV_GRID_ALIGN_END" /> is
swapped. I.e. `START` will mean right-most.

The columns will be placed from right to left.

Edge cases and notes [#edge-cases-and-notes]

* Min/max as content or percent: Child Widgets can set min/max width/height to
  <ApiLink name="LV_SIZE_CONTENT" /> or <ApiLink name="LV_PCT" display="LV_PCT(x)" />. These constraints are respected
  when computing <ApiLink name="LV_GRID_CONTENT" /> tracks (tracks sized to their largest
  child) and when distributing space to FR-unit tracks.

<Callout type="info" title="Further Reading">
  - Learn more about CSS Grid layout.
  - Learn more about CSS Subgrid layout.
</Callout>

Examples [#examples]

A simple grid [#a-simple-grid]

<LvglExample name="lv_example_grid_1" path="layouts/grid/lv_example_grid_1" />

Demonstrate cell placement and span [#demonstrate-cell-placement-and-span]

<LvglExample name="lv_example_grid_2" path="layouts/grid/lv_example_grid_2" />

Demonstrate grid's -free unit- [#demonstrate-grids--free-unit-]

<LvglExample name="lv_example_grid_3" path="layouts/grid/lv_example_grid_3" />

Demonstrate track placement [#demonstrate-track-placement]

<LvglExample name="lv_example_grid_4" path="layouts/grid/lv_example_grid_4" />

Demonstrate column and row gap [#demonstrate-column-and-row-gap]

<LvglExample name="lv_example_grid_5" path="layouts/grid/lv_example_grid_5" />

Demonstrate RTL direction on grid [#demonstrate-rtl-direction-on-grid]

<LvglExample name="lv_example_grid_6" path="layouts/grid/lv_example_grid_6" />

API [#api]
