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()
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.
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.
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.
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()
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.
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: