Streamlit normally displays widgets from top to bottom. When two controls belong together—such as “From” and “To” unit selectors—st.columns puts them side by side. Unlike st.sidebar, columns sit inline with the rest of the app. section 3.6.1
Put two selectors side by side
Use `from_col, to_col = st.columns(2)` to create two equally wide columns. Then place a widget in each: `from_unit = from_col.selectbox("From", units)` and `to_unit = to_col.selectbox("To", units, index=1)`. The second selector initially chooses a different unit. For several elements in one column, `with from_col:` is another placement option. section 3.6.1
Columns can have different widths. In a task list, `st.columns([0.8, 0.2])` gives task text most of the row and reserves a narrower space for its Delete button. Creating the same button in every row also requires unique widget keys; columns alone do not prevent duplicate-widget errors. section 4.2.1
for idx, task in enumerate(task_list):
task_col, delete_col = st.columns([0.8, 0.2])
task_col.checkbox(task.name, task.is_done)
if delete_col.button("Delete", key=f"delete_{idx}"):
pass
See the task-row loop with 80/20 columns and a distinct Delete-button key for each row. section 4.2.1
