Skip to main content
By default, components in Blocks are arranged vertically. But you have full control over how components are positioned using layout elements. Under the hood, Gradio uses the flexbox model from web development.

Rows

Use gr.Row() to arrange components horizontally:
import gradio as gr

with gr.Blocks() as demo:
    with gr.Row():
        btn1 = gr.Button("Button 1")
        btn2 = gr.Button("Button 2")

demo.launch()
Both buttons will appear side by side on the same horizontal line.

Equal height

You can make all elements in a row have the same height:
with gr.Blocks() as demo:
    with gr.Row(equal_height=True):
        textbox = gr.Textbox()
        btn = gr.Button("Button 2")

demo.launch()

Controlling width with scale and min_width

Every component has two parameters that control its width within a row:

The scale parameter

The scale parameter determines how components expand to fill available space:
  • scale=0: Component does not expand, takes only the space it needs
  • scale=1 or higher: Component expands proportionally to its scale value
with gr.Blocks() as demo:
    with gr.Row():
        btn0 = gr.Button("Button 0", scale=0)  # No expansion
        btn1 = gr.Button("Button 1", scale=1)  # Expands 1x
        btn2 = gr.Button("Button 2", scale=2)  # Expands 2x (twice as wide as btn1)

demo.launch()
In this example, btn2 will be twice as wide as btn1, while btn0 stays at its minimum size.

The min_width parameter

The min_width parameter sets the minimum width (in pixels) that a component will take. If there isn’t enough space to satisfy all min_width values, the row will wrap:
with gr.Blocks() as demo:
    with gr.Row():
        btn1 = gr.Button("Button 1", min_width=300)
        btn2 = gr.Button("Button 2", min_width=300)

demo.launch()
Learn more about Rows in the Row documentation.

Columns and nesting

Components within a gr.Column() are stacked vertically. Since vertical stacking is the default, columns are most useful when nested inside rows:
import gradio as gr

with gr.Blocks() as demo:
    with gr.Row():
        with gr.Column():
            text1 = gr.Textbox(label="Input 1")
            text2 = gr.Textbox(label="Input 2")
        with gr.Column():
            image = gr.Image()
            button = gr.Button("Process")

demo.launch()
In this layout:
  • The first column contains two textboxes stacked vertically
  • The second column contains an image and a button stacked vertically
  • Both columns sit side by side in the row

Controlling column width

Just like components in rows, columns support the scale parameter:
with gr.Blocks() as demo:
    with gr.Row():
        with gr.Column(scale=1):
            text1 = gr.Textbox(label="Input 1")
            text2 = gr.Textbox(label="Input 2")
        with gr.Column(scale=2):
            image = gr.Image()
            button = gr.Button("Process")

demo.launch()
The second column will be twice as wide as the first.
Learn more about Columns in the Column documentation.

Fill browser height and width

Full width

To make your app take the full width of the browser (removing side padding), use fill_width=True:
import gradio as gr

with gr.Blocks(fill_width=True) as demo:
    # Your components here
    pass

demo.launch()

Full height

To make top-level components expand to fill the browser height:
import gradio as gr

with gr.Blocks(fill_height=True) as demo:
    gr.Chatbot(scale=1)  # Expands to fill available space
    gr.Textbox(scale=0)  # Takes only the space it needs

demo.launch()
Components need scale >= 1 to expand vertically when fill_height=True is enabled.

Dimensions

Some components support explicit height and width parameters. These accept either:
  • A number: Interpreted as pixels
  • A string: Allows any CSS unit (px, em, rem, vh, vw, etc.)
import gradio as gr

with gr.Blocks() as demo:
    # Using viewport width units
    im = gr.ImageEditor(width="50vw")
    
    # Using pixels
    text = gr.Textbox(height=200)

demo.launch()

Tabs

Create tabbed interfaces with gr.Tab(). Each tab selectively shows or hides its contents:
import gradio as gr

def flip_text(text):
    return text[::-1]

def flip_image(image):
    return image.rotate(180)

with gr.Blocks() as demo:
    gr.Markdown("# Flip Text or Image")
    
    with gr.Tab("Flip Text"):
        text_input = gr.Textbox()
        text_output = gr.Textbox()
        text_button = gr.Button("Flip")
        text_button.click(flip_text, inputs=text_input, outputs=text_output)
    
    with gr.Tab("Flip Image"):
        image_input = gr.Image()
        image_output = gr.Image()
        image_button = gr.Button("Flip")
        image_button.click(flip_image, inputs=image_input, outputs=image_output)

demo.launch()
Consecutive gr.Tab() contexts are automatically grouped together. Only one tab can be selected at a time, and only that tab’s components are visible.
Learn more in the Tab documentation.

Accordions

Accordions provide collapsible sections that can be toggled open or closed:
import gradio as gr

with gr.Blocks() as demo:
    with gr.Accordion("Advanced Options", open=False):
        temperature = gr.Slider(0, 1, value=0.7, label="Temperature")
        top_p = gr.Slider(0, 1, value=0.9, label="Top P")
        max_tokens = gr.Slider(1, 2048, value=256, label="Max Tokens")

demo.launch()
The open parameter controls whether the accordion starts expanded or collapsed.
Learn more in the Accordion documentation.
The sidebar creates a collapsible panel on the left side of the screen:
import gradio as gr

with gr.Blocks() as demo:
    with gr.Sidebar():
        gr.Markdown("## Settings")
        model = gr.Dropdown(["GPT-4", "GPT-3.5"], label="Model")
        temperature = gr.Slider(0, 1, value=0.7, label="Temperature")
    
    # Main content
    gr.Markdown("# Chat Application")
    chatbot = gr.Chatbot()
    msg = gr.Textbox()

demo.launch()
Learn more in the Sidebar documentation.

Multi-step walkthroughs

For guided workflows, use the Walkthrough component with Step components:
import gradio as gr

with gr.Blocks() as demo:
    walkthrough = gr.Walkthrough(value="step1")
    
    with gr.Step(id="step1", parent=walkthrough):
        gr.Markdown("## Step 1: Enter your information")
        name = gr.Textbox(label="Name")
        gr.Button("Next").click(
            lambda: "step2",
            outputs=walkthrough
        )
    
    with gr.Step(id="step2", parent=walkthrough):
        gr.Markdown("## Step 2: Review and submit")
        gr.Button("Back").click(
            lambda: "step1",
            outputs=walkthrough
        )
        gr.Button("Submit")

demo.launch()
The Walkthrough component has a visual style tailored for step-by-step workflows. You control progression by setting the appropriate step ID.
Learn more in the Walkthrough documentation.

Visibility

Both components and layout elements have a visible parameter that can be set initially and updated dynamically:
import gradio as gr

def toggle_textbox(choice):
    if choice == "Yes":
        return gr.Textbox(visible=True)
    else:
        return gr.Textbox(visible=False)

with gr.Blocks() as demo:
    radio = gr.Radio(["Yes", "No"], label="Show textbox?")
    textbox = gr.Textbox(label="Hidden by default", visible=False)
    
    radio.change(toggle_textbox, radio, textbox)

demo.launch()
Setting gr.Column(visible=False) on a column hides all components inside it.

Defining and rendering components separately

Sometimes you need to define a component before you render it in the UI. For example, when using gr.Examples, you need to pass the input component to it, but might want to render the examples first:
import gradio as gr

# Define the component outside the Blocks context
input_textbox = gr.Textbox()

with gr.Blocks() as demo:
    # Show examples first
    gr.Examples(["hello", "bonjour", "merhaba"], input_textbox)
    
    # Render the textbox later
    input_textbox.render()

demo.launch()
The .render() method places the component wherever you call it.

Unrendering and moving components

You can also move a component by unrendering it and rendering it elsewhere:
import gradio as gr

with gr.Blocks() as demo:
    with gr.Row():
        with gr.Column():
            gr.Markdown("Column 1")
            textbox = gr.Textbox()
        with gr.Column():
            gr.Markdown("Column 2")
            textbox.unrender()  # Remove from Column 1
        with gr.Column():
            gr.Markdown("Column 3")
            textbox.render()  # Add to Column 3

demo.launch()
The textbox will appear in the third column.

Next steps

Now that you know how to control layout, you can: