how to deal with variable width of Buttons in ipywidgets

Question:

I have the need to display a bunch of buttons.
the description of every button corresponds to every word of a text.

In order to give a text appearance I want to make button width accoding to the length of the word inside.
So I create a variable that gives me the width px according to the number of letters.

I dont know why but it does not work well. It works for some words and for other doesnt.

some ideas?
(see in the screenshot how the word “the” does not have enough space in and only … is dísplay.

The ultimate goal is of course have a text looking normally as a text where I can click words.

Thanks.

mylist=['loren','ipsum','whapmmtever','loren','ipsum','otra','the','palabra','concept']

list_btns=[]
for i,word in enumerate(mylist):
    # here I try to define the width of the button as depending on the length of the word:
    wordwidth= str(len(word)*12) + 'px'
    wd_raw_save_button = widgets.Button(description=word,
                                        disabled=False,
                                        button_style='success',
                                        tooltip='check the word',
                                        icon='',
                                        layout = Layout(width = wordwidth, margin='0px 0px 0px 0px'))

    list_btns.append(wd_raw_save_button)



showcase=HBox(list_btns)
showcase

how it looks like in jupyter

Actually after running voila to visualise the result I get this:

enter image description here

this does not give an impression of real text, i.e. same spacing between words which is the ultimate goal.
I am guessing, but I am not sure, that the reason might be that the characters are of different width, and I will have to calculate the width character by character. But this does not explain that the word “the” does not fit inside the button.
Second explanation is that the underlying CSS assumes a certain minimum border which goes “over” the word itself. In any case I dont know how to control/influence it.

Asked By: JFerro

||

Answers:

There’s limited control for the CSS for widgets. There seems to be a cutoff around 40px where text will get truncated. I used a simple max comparison to get hopefully close to what you are looking for:

from ipywidgets import *
mylist=['loren','ipsum','whapmmtever','loren','ipsum','otra','the','palabra','concept', 'a'] * 2

list_btns=[]
for i,word in enumerate(mylist):
    # here I try to define the width of the button as depending on the length of the word:
    wordwidth= max(len(word) * 12, 40)
    wordwidth = str(wordwidth) + 'px'
    wd_raw_save_button = widgets.Button(description=word,
                                        disabled=False,
                                        button_style='success',
                                        tooltip='check the word',
                                        icon='',
                                        layout = Layout(width = wordwidth, margin='0px 0px 0px 0px')
                                       )

    list_btns.append(wd_raw_save_button)



showcase=HBox(list_btns, layout= Layout(width='100%'))
showcase

enter image description here

Answered By: ac24

First:

display(ipywidgets.HTML("<style>.narrow_button { padding: 0px 2px; border: 1px solid black  }</style>"))

Pay attention that this line is inside the exact same cell where you display the ipywidgets. The second line of code that is needed, comes after you defined your ipywidget. Now you have to assign this styling to each widget. Inside the loop, use:

wd_raw_save_button.add_class('narrow_button')

Then my buttons look like this: enter image description here

Produced by your modified example:

from ipywidgets import *
import ipywidgets
mylist=['loren','ipsum','whapmmtever','loren','ipsum','otra','the','palabra','concept']
display(ipywidgets.HTML("<style>.narrow_button { padding: 0px 2px; border: 1px solid black  }</style>"))
list_btns=[]
for i,word in enumerate(mylist):
    # here I try to define the width of the button as depending on the length of the word:
    wordwidth= str(len(word)*12) + 'px'
    wd_raw_save_button = widgets.Button(description=word,
                                        disabled=False,
                                        button_style='success',
                                        tooltip='check the word',
                                        icon='',
                                        layout = Layout(width = 'auto', margin='0px 0px 0px 0px'))
    wd_raw_save_button.add_class("narrow_button")
    list_btns.append(wd_raw_save_button)



showcase=HBox(list_btns)
showcase
Answered By: David Streuli