st.grid
Insert a responsive grid container.
Inserts a grid for repeated cards, metric walls, galleries, and dashboard panels. Direct children become cells and reflow with the available width. Use st.columns for a known side-by-side split and st.container(horizontal=True) for natural-width toolbars.
To add elements to the returned container, use the with notation (preferred) or call commands on the returned object. Group multiple elements or span tracks with grid.cell().
st.empty() as a direct child reserves a cell. Later writes replace that cell and do not insert a new one. A heading inside the grid also takes a cell, so keep section headings outside the grid.
| Function signature[source] | |
|---|---|
st.grid(columns="auto", *, min_column_width="auto", wrap=True, gap="small", vertical_alignment="top", border=False, row_height="content", width="stretch", height="content", key=None, dense=False) | |
| Parameters | |
columns ("auto" or int) | Number of equal-width columns. This can be one of the following:
|
min_column_width ("auto" or int) | The minimum width of each column before the grid wraps to fewer columns. This can be one of the following:
Cell border and padding sit inside this width. With wrap=True, the grid drops a column before cells would be narrower than this width; once one column remains, it uses the container width and may be narrower. With wrap=False, cells shrink to this width and the grid then scrolls horizontally. |
wrap (bool) | Whether the number of columns can decrease as the container gets narrower. This can be one of the following:
Setting wrap=False with columns="auto" raises an exception, because there is no declared column count to keep. |
gap ("xxsmall", "xsmall", "small", "medium", "large", "xlarge", "xxlarge", int, tuple, list, or None) | The size of the gap between cells. Pass one value to use the same gap between rows and columns, or a 2-tuple or 2-list (row_gap, column_gap) to set them separately. Each value can be one of the following:
The rem unit is relative to the theme.baseFontSize configuration option. |
vertical_alignment ("top", "center", or "bottom") | Vertical alignment of content inside the cell. The cell frame still fills the row. This can be one of the following:
|
border (bool) | Whether to show a border around each cell. If this is False (default), no border is shown. If this is True, a border is shown around each cell. |
row_height ("content" or int) | The height of each row. This can be one of the following:
|
width ("stretch" or int) | The width of the grid. This can be one of the following:
|
height ("content", "stretch", or int) | The height of the grid. This can be one of the following:
|
key (str, int, or None) | An optional string or integer to give this element a stable identity. If this is None (default), the element's identity will be determined based on the values of the other parameters. Additionally, if key is provided, it will be used as a CSS class name prefixed with st-key-. |
dense (bool) | Whether later cells can backfill holes left by spanning cells. If this is False (default), cells keep source order. If this is True, later cells can appear visually ahead of earlier ones. That can hurt accessibility, because keyboard and screen-reader order stay in source order. |
| Returns | |
(GridContainer) | A container that supports with notation or method calls. It also has a cell() method for grouping elements and spanning columns or rows. |
Examples
Example 1: Metric cards
import streamlit as st metrics = [ ("Revenue", "$1.2M", "+8%"), ("Pipeline", "$4.8M", "+12%"), ("Conversion", "12.4%", "+1.1%"), ("Retention", "96%", "-0.4%"), ] grid = st.grid(4) for label, value, delta in metrics: grid.metric(label, value, delta, border=True)
Example 2: Full-width cell
import streamlit as st grid = st.grid("auto", min_column_width=220) with grid.cell(column_span="all"): st.markdown("**Featured**") grid.markdown("Card")
Example 3: Fixed column count (no wrap)
import streamlit as st from numpy.random import default_rng as rng df = rng(0).standard_normal((20, 3)) grid = st.grid(3, wrap=False, border=True) grid.line_chart(df, height=220) grid.bar_chart(df, height=220) grid.dataframe(df, height=220)
GridContainer.cell
Create the next auto-placed grid cell.
With no arguments this groups multiple elements into one cell. column_span and row_span occupy more tracks. The returned object works with with notation or method chaining.
| Function signature[source] | |
|---|---|
GridContainer.cell(*, column_span=1, row_span=1) | |
| Parameters | |
column_span (int or "all") | The number of columns the cell spans. This can be one of the following:
|
row_span (int) | The number of rows the cell spans. Defaults to 1. Must be a positive integer. With row_height="content", the rows it covers grow to fit this cell. With a pixel row_height, the cell covers that many row tracks plus the gaps between them. |
| Returns | |
(DeltaGenerator) | A container object that supports with notation or method calls. |
Examples
Group a metric and caption in one cell, and span a featured card.
import streamlit as st grid = st.grid(4) with grid.cell(): st.metric("Revenue", "$1.2M", "+8%", border=True) st.caption("Trailing 30 days") with grid.cell(column_span="all"): st.markdown("**Featured**")
Still have questions?
Our forums are full of helpful information and Streamlit experts.