I have the following script
from ipywidgets import Checkbox, Text, HBox, VBox, Layout, HTML
from IPython.display import display
checkbox = Checkbox(layout=Layout(width='8%', align_self='center'))
text_field = Text(layout=Layout(width='20%'))
header_row = HBox([
HTML(value="<b>Checkbox</b>", layout=Layout(width='8%', text_align='center')),
HTML(value="<b>Text Field</b>", layout=Layout(width='20%', text_align='center'))
])
row = HBox([checkbox, text_field], layout=Layout(align_items='center'))
ui = VBox([header_row, row])
display(ui)
I would expect this to return a column like structure, with a checkbox next to a text box. However, the result looks like this:
Why is my checkbox being pushed to the right? How can we adjust our script so that it is displayed correctly?
The core answer is I believed spelled out in the 'Details' section at the bottom of my answer to 'Align ipywidgets inside two HBoxes python' here.
The key issue:
By default, ipywidgets indents the checkboxes for better alignment with their descriptions. However, here you don't want this as it is causing a major issue with the alignment in your case. Fortunately, the setting
indent=False
ensures that the checkboxes are not indented and are aligned with the left edge of their containers.
I think you want, instead for the checkbox
line of code:
checkbox = Checkbox(layout=Layout(width='8%', align_self='center'), indent=False)
With that adjustment to your code, you'll see the following:
What though if you still want the Checkbox widget more-or-less centered below the 'Checkbox' text?
Improve with a little padding, if you want:
from ipywidgets import Checkbox, Text, HBox, VBox, Layout, HTML
from IPython.display import display
checkbox = Checkbox(layout=Layout(padding='0px 0px 0px 27px',width='8%', align_self='center'), indent=False)
text_field = Text(layout=Layout(width='20%'))
header_row = HBox([
HTML(value="<b>Checkbox</b>", layout=Layout(width='8%', text_align='center')),
HTML(value="<b>Text Field</b>", layout=Layout(width='20%', text_align='center'))
])
row = HBox([checkbox, text_field], layout=Layout(align_items='center'))
ui = VBox([header_row, row])
display(ui)
Key change there was the addition of padding='0px 0px 0px 27px'
. The pixels you need may vary slightly.
This how the output looks to me with that padding added:
In the referenced answer, the OP asked about a grid layout there and so I'll also add a starting point one for this example here in case that looks more in line with your preferences:
from ipywidgets import Checkbox, Text, GridBox, HTML, Layout
from IPython.display import display
# Create the checkbox and text field
checkbox = Checkbox(layout=Layout(padding='0px 0px 0px 29px',width='100%', align_self='center'), indent=False)
text_field = Text(layout=Layout(width='100%'))
# Create headers
header_checkbox = HTML(value="<b>Checkbox</b>", layout=Layout(text_align='center'))
header_text_field = HTML(value="<b>Text Field</b>", layout=Layout(text_align='center'))
# Create a grid layout
ui = GridBox(
children=[header_checkbox, header_text_field, checkbox, text_field],
layout=Layout(
grid_template_columns='8% 20%',
grid_template_rows='auto auto',
grid_gap='10px 10px',
justify_items='center',
align_items='center'
)
)
# Display the final UI
display(ui)
That code in my hands results like this:
Again, the specifics of the padding may need adjusting, and probably designating it with a percent is better as it is less arbitrary and will be better adapted to any window size, see below.
UPDATE: Use of padding='0px 0px 0px 50%'
a GridBox with a Grid Layout option
A better option pointed out the OP for controlling the padding is to use a percent instead of a set pixel amount because presumably that will work no matter the size of the window. I found this worked well with the code for the GridBox with a Grid Layout option as shown below; however, I didn't find the correct combination where it works for the gridlayout, yet.
from ipywidgets import Checkbox, Text, GridBox, HTML, Layout
from IPython.display import display
# Create the checkbox and text field
checkbox = Checkbox(layout=Layout(padding='0px 0px 0px 50%',width='100%', align_self='center'), indent=False)
text_field = Text(layout=Layout(width='100%'))
# Create headers
header_checkbox = HTML(value="<b>Checkbox</b>", layout=Layout(text_align='center'))
header_text_field = HTML(value="<b>Text Field</b>", layout=Layout(text_align='center'))
# Create a grid layout
ui = GridBox(
children=[header_checkbox, header_text_field, checkbox, text_field],
layout=Layout(
grid_template_columns='8% 20%',
grid_template_rows='auto auto',
grid_gap='10px 10px',
justify_items='center',
align_items='center'
)
)
# Display the final UI
display(ui)