0

I would like to align widgets inside two HBoxes horizontally.

import ipywidgets as widgets

but1 = widgets.RadioButtons(options=["foo", "bar"])
but2 = widgets.RadioButtons(options=["verylongstringherethisislong", "bar"])

check1 = widgets.Checkbox(description="asdf")
check2 = widgets.Checkbox(description="verylongstringherethisislong")

box_layout = widgets.Layout(
    align_items='flex-start',
    width='1300px',  
    justify_content='flex-start'  
)

widgets.VBox(
    children=[
        widgets.HBox(children=[but1, but1, but2, but2], layout=box_layout),
        widgets.HBox([check2, check2, check1, check1], layout=box_layout)
    ]
)

My current code doesn't do the job: enter image description here

1 Answer 1

1

Update: Using Grid Layout

This update to make four columns of RadioButtons with Checkboxes aligned below each column uses a Grid Layout after comments by OP that the fine-tuning necessary with using the margins doesn't seem clean as expected.
Still, the key change of setting indent=False for the Checkbox widgets is important, see the details below the original reply for more.

import ipywidgets as widgets

but1 = widgets.RadioButtons(options=["foo", "bar"])
but1pt5 = widgets.RadioButtons(options=["foo", "bar"])
but2 = widgets.RadioButtons(options=["verylongstringherethisislong", "bar"])
but2pt5 = widgets.RadioButtons(options=["verylongstringherethisislong", "bar"])

check1 = widgets.Checkbox(description="asdf", indent=False)
check2 = widgets.Checkbox(description="verylongstringherethisislong", indent=False)
check3 = widgets.Checkbox(description="verylongstringherethisislong", indent=False)
check4 = widgets.Checkbox(description="asdf", indent=False)

# Create GridBox layout
grid_layout = widgets.Layout(
    display='grid',
    grid_template_columns='auto auto auto auto',
    grid_gap='10px 10px',
    width='1300px',
    justify_content='flex-start'
)

# Create GridBox
grid_box = widgets.GridBox(
    children=[
        but1, but1pt5, but2, but2pt5,
        check2, check3, check4, check1
    ],
    layout=grid_layout
)

display(grid_box)

RESULT WITH GRID LAYOUT

enter image description here



Original reply keeping closer to OP's code

This gets close on my system:

import ipywidgets as widgets

but1 = widgets.RadioButtons(options=["foo", "bar"])
but1pt5 = widgets.RadioButtons(options=["foo", "bar"], layout=widgets.Layout(margin='0 0 0 5px') )
but2 = widgets.RadioButtons(options=["verylongstringherethisislong", "bar"], layout=widgets.Layout(margin='0 0 0 4px')  )
but2pt5 = widgets.RadioButtons(options=["verylongstringherethisislong", "bar"], layout=widgets.Layout(margin='0 0 0 4px') )


check1 = widgets.Checkbox(description="asdf", indent=False)
check2 = widgets.Checkbox(description="verylongstringherethisislong", indent=False)
check3 = widgets.Checkbox(description="verylongstringherethisislong", indent=False)
check4 = widgets.Checkbox(description="asdf", indent=False)

box_layout = widgets.Layout(
    align_items='flex-start',
    width='1300px',
    justify_content='flex-start'
)

vbox = widgets.VBox(
    children=[
        widgets.HBox(children=[but1, but1pt5, but2, but2pt5], layout=box_layout),
        widgets.HBox(children=[check2, check3, check1, check4], layout=box_layout)
    ]
)

display(vbox)

RESULT USING ORIGINAL CODE

enter image description here

Keep in mind some adjustment may still be in order. I doubt these are the real labels, and so you may need to also adjust more. Plus, your system may handle the spacing a little different so some adjustment may be necessary. Hopefully the details I provide below will help in that fine tuning.

UPDATE: speaking of adjustments it was pointed out that you can also use percents for controlling the padding setting. In this case, this is what I found works for substituting in for the lines with the pixel settings for padding:

but1pt5 = widgets.RadioButtons(options=["foo", "bar"], layout=widgets.Layout(margin='0 0 0 0.4%') )
but2 = widgets.RadioButtons(options=["verylongstringherethisislong", "bar"], layout=widgets.Layout(margin='0 0 0 0.3%')  )
but2pt5 = widgets.RadioButtons(options=["verylongstringherethisislong", "bar"], layout=widgets.Layout(margin='0 0 0 0.2%') )

That seems rather arbitrary, yet it was what I saw produced reasonable results in this situation. I add it because maybe it is resistant to changes in window size, unlike I suspect the pixel settings. Indeed that ability is why the percent setting was suggested here and there the use of the 50% makes sense because it is centering a checkbox in that case. Unlike here where the values seem very arbitrary.

Details:

The key change in my code relative yours, is setting indent=False for the Checkbox widgets. 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.
In your case, just adding that setting indent=False for the Checkbox widgets gets you 90% of the way there relative your original code.

However, it still isn't aligned even though it is much less dramatic with the indent nixed.
So next I added ,layout=widgets.Layout(margin='0 0 0 1px') to the Checkbox widget for the Checkbox appearing on the left side of your columns and that addition of a left margin CSS property of some pixel value via the layout parameter helped that one in the second column look better aligned. However, I realized the others wouldn't be as easy, and so I switched to adding the left margin to the radio buttons. Doing that I realized, I need to separate these out so that each column has a very similarly setup widget, but an actual different widget that I can adjust independently. So that is why there are more than you had. I could pare down the checkboxes and second set of radio buttons back gain since I moved the margin handling to the radio buttons and the two radio buttons with the long label are the same, but I left them for now since you may need to fine tune. In the end, with your code the margins for the radio buttons just needed values of a few pixels to bring them in line with the unindented checkboxes.

Sign up to request clarification or add additional context in comments.

3 Comments

I believe there still must be cleaner way to do the alignment, perhaps a grid/box and some CSS I don't understand, but you got me close enough. Thanks
That was originally my thought, too. But once I found that turning off the indent got us so close, I just adjusted and stayed close to your original code. I may revisit it at some point.
Just a GridBox with a Grid Layout is sufficient, combined with the indent=False use. No need for the complex fine-tuning via margins or padding settings. And no need for CSS. I added an updated version at the top of the post with this approach since it is cleaner.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.