Dcc.dropdown doesn't load options when inside dbc.column

I’m using dash-bootstrap-components (v1.4.1) Card component to display some labels (text) and dash-core-components (v2.0.0) Dropdowns. When I use html components for the layout of the card, the dropdown loads the values in df.CountyName.unique() at startup, as intended.

card_main = dbc.Card(
    [
        dbc.CardBody(
            [
                html.H4("Select a location to browse", className="card-title"),
                # html.H6("Lesson 1:", className="card-subtitle"),
                html.Div([
                    html.P("County", className="card-text"),
                    dcc.Dropdown(options=df.CountyName.unique(), id='county_chosen',
                                 # options=[{'label': i, "value": i} for i in df.CountyName.unique()],
                                 value='', clearable=False, style={"color": "#000000"}),
                ]),
                html.P(
                    "Now choose the town you would like to browse.",
                    className="card-text mt-2",
                ),
                dcc.Dropdown(options={}, id='town_chosen', clearable=False, style={"color": "#000000"})
                #              options=[{'label': 'town', 'value': 'town'}])
                # dbc.Button("Press me", color="primary"),
                # dbc.CardLink("GirlsWhoCode", href="https://girlswhocode.com/", target="_blank"),
            ]
        ),
    ],
    color="dark",   # https://bootswatch.com/default/ for more card colors
    inverse=True,   # change color of text (black or white)
    outline=False,  # True = remove the block colors from the background and header
)

When I use dash-bootstrap-components (v1.4.1) Row and Col for the layout, the dropdown doesn’t load the values, even though I can see that df.CountyName.unique() returns the expected values when in the debugger.

card_main = dbc.Card(
    [
        dbc.CardBody(
            [
                html.H5("Select a location to browse", className="card-title"),
                # html.H6("Lesson 1:", className="card-subtitle"),
                html.Div(
                    [
                        dbc.Row([
                            dbc.Col(dbc.Label("County", html_for="county_chosen", className="mt-1 ps-4"), width=1),
                            dbc.Col(dcc.Dropdown(id='county_chosen', options=df.CountyName.unique()), width=2)
                            ]
                        ),
                        dbc.Row([
                            dbc.Col(dbc.Label("Town", html_for="town_chosen", className="mt-1 ps-4"), width=1),
                            dbc.Col(dcc.Dropdown(id='town_chosen', options={}), width=7)
                            ]
                        )
                    ]
                ),
            ]
        ),
    ],
    color="dark",   # https://bootswatch.com/default/ for more card colors
    inverse=True,   # change color of text (black or white)
    outline=False,  # True = remove the block colors from the background and header
)


The card layout is the only thing different in the app (it’s the same app with 2 different cards I can switch between.

Seems like a bug…

Ultimately I want to have multiple labels and dropdowns in the same row, but haven’t figured out how to do that with straight HTML.

Sorry, I don’t know how to add the code so that it shows up properly formatted. I didn’t see an FAQ or other instructions. Can someone show me how so I can do it right next time?

Hello @kklasman !

Firstly so our work will be more easy, to format the code put it in Preformated block:

1 Like

Done. Thanks!

2 Likes

Nevermind. In case anyone else runs into this, I’ll include the details of the problem and a fix, both with working samples.

This line made the text nearly invisible (to my eyes).

inverse=True,   # change color of text (black or white)

I should have realized that the dropdown was being loaded as it appears to have the number of lines I expected, but the text was incredibly faint.

Removing it solved the problem.

There is still a difference in behavior between the 2 cards that I didn’t understand. In the full working sample below, both cards have the same problem line:

inverse=True, # change color of text (black or white)

In the html card (card_good), the dropdown text is still readable. This is probably due to the inline style={“color”: “#000000”} on the dropdown component.

in the dbc.Col card (card_bad), the dropdown text is very faint.

It seems that I inverse=True should only be applied to the column with the label text. Or simply add the same style to the dropdown.

Here’s the version with the issue:

import pandas as pd
from dash import Dash, html, dcc

import dash_bootstrap_components as dbc
app = Dash(__name__, external_stylesheets=[dbc.themes.SPACELAB, dbc.icons.FONT_AWESOME])

data = {'CountyName': ['Knox', 'York', 'Waldo', 'Knox', 'York', 'Waldo'], 'TownName': ['Camdem', 'Kennebunk', 'Rockport', 'Camden', 'Caribou', 'Makinac']}
df = pd.DataFrame(data)

card_good = dbc.Card(
    [
        dbc.CardBody(
            [
                html.H4("Select a location to browse", className="card-title"),
                html.Div(children=[html.Label('County: ', className='me-2'),
                                   'foo bar',
                    dcc.Dropdown(options=df.CountyName.unique(), id='county_chosen',
                                 value='', clearable=False, style={"color": "#000000"}),
                ]),
                html.P(
                    "Now choose the town you would like to browse.",
                    className="card-text mt-2",
                ),
                dcc.Dropdown(options={}, id='town_chosen', clearable=False, style={"color": "#000000"})
             ]
        ),
    ],
    color="dark",   # https://bootswatch.com/default/ for more card colors
    inverse=True,   # change color of text (black or white)
    outline=False,  # True = remove the block colors from the background and header
)

card_bad = dbc.Card(
    [
        dbc.CardBody(
            [
                html.H5("Select a location to browse", className="card-title"),
                html.Div(
                    [
                        dbc.Row([
                            dbc.Col(dbc.Label("County", html_for="county_chosen", className="mt-1 ps-4"), width=1),
                            dbc.Col(dcc.Dropdown(id='county_chosen', options=df.CountyName.unique()), width=2)
                            ]
                        ),
                        dbc.Row([
                            dbc.Col(dbc.Label("Town", html_for="town_chosen", className="mt-1 ps-4"), width=1),
                            dbc.Col(dcc.Dropdown(id='town_chosen', options={}), width=7)
                            ]
                        )
                    ]
                ),
            ]
        ),
    ],
    color="dark",   # https://bootswatch.com/default/ for more card colors
    inverse=True,   # change color of text (black or white)
    outline=False,  # True = remove the block colors from the background and header
)

card_data = dbc.Card(
    [
        dbc.CardBody(
            [
                html.H4('This card contains data', className='card-title'),
                dbc.CardImg(src="/assets/20200926-12.jpg", top=True, bottom=False,
                            title="Image by Kevin Klasman", alt='Select a location to browse'),

            ]
        )
    ])


app.layout = html.Div(
    [
        dbc.Row([dbc.Col(card_good, className="mx-2")]),
        dbc.Row([dbc.Col(card_bad, className="m-2")]),
    ])

if __name__ == "__main__":
    app.run_server(debug=True)

Here’s the working solution:

import pandas as pd
from dash import Dash, html, dcc

import dash_bootstrap_components as dbc
app = Dash(__name__, external_stylesheets=[dbc.themes.SPACELAB, dbc.icons.FONT_AWESOME])

data = {'CountyName': ['Knox', 'York', 'Waldo', 'Knox', 'York', 'Waldo'], 'TownName': ['Camdem', 'Kennebunk', 'Rockport', 'Camden', 'Caribou', 'Makinac']}
df = pd.DataFrame(data)

card_good = dbc.Card(
    [
        dbc.CardBody(
            [
                html.H4("Select a location to browse", className="card-title"),
                html.Div(children=[html.Label('County: ', className='me-2'),
                                   'foo bar',
                    dcc.Dropdown(options=df.CountyName.unique(), id='county_chosen',
                                 value='', clearable=False, style={"color": "#000000"}),
                ]),
                html.P(
                    "Now choose the town you would like to browse.",
                    className="card-text mt-2",
                ),
                dcc.Dropdown(options={}, id='town_chosen', clearable=False, style={"color": "#000000"})
             ]
        ),
    ],
    color="dark",   # https://bootswatch.com/default/ for more card colors
    inverse=True,   # change color of text (black or white)
    outline=False,  # True = remove the block colors from the background and header
)

card_bad = dbc.Card(
    [
        dbc.CardBody(
            [
                html.H5("Select a location to browse", className="card-title"),
                html.Div(
                    [
                        dbc.Row([
                            dbc.Col(dbc.Label("County", html_for="county_chosen", className="mt-1 ps-4"), width=1),
                            dbc.Col(dcc.Dropdown(id='county_chosen', options=df.CountyName.unique(), style={"color": "#000000"}), width=2)
                            ]
                        ),
                        dbc.Row([
                            dbc.Col(dbc.Label("Town", html_for="town_chosen", className="mt-1 ps-4"), width=1),
                            dbc.Col(dcc.Dropdown(id='town_chosen', options={}), width=7)
                            ]
                        )
                    ]
                ),
            ]
        ),
    ],
    color="dark",   # https://bootswatch.com/default/ for more card colors
    inverse=True,   # change color of text (black or white)
    outline=False,  # True = remove the block colors from the background and header
)

card_data = dbc.Card(
    [
        dbc.CardBody(
            [
                html.H4('This card contains data', className='card-title'),
                dbc.CardImg(src="/assets/20200926-12.jpg", top=True, bottom=False,
                            title="Image by Kevin Klasman", alt='Select a location to browse'),

            ]
        )
    ])


app.layout = html.Div(
    [
        dbc.Row([dbc.Col(card_good, className="mx-2")]),
        dbc.Row([dbc.Col(card_bad, className="m-2")]),
    ])

if __name__ == "__main__":
    app.run_server(debug=True)
1 Like

Good work!

I will try to bring some light into this. This often happens when you mix 2 component libraries. I experienced similiar nonsense behaviour when I mixed Dash Mantine Components with Dash Bootstrap Components. Some components retrieve their properties from parent components and if you mix two components libraries they might not expect some kind of argument because the one or another library just don’t do that stuff. For example children components typicaly check parents components width to set their own. In your case I believe from some reason dcc.Dropdown is retrieving color of text in dropdown from it’s parent container - your Card. Since dcc do not have inverse parameters it do not expect to find different font color there.

To avoid this I suggest to choose just one component library that suits you the best (if you want rich component libraries there are basically just 2 options - Bootstrap and Mantine) or at least just prefer components from one of them so you mix them as little as possible (I know that some components are available only in some specific libraries)

In this case try to replace dcc.Dropdown with dbc.Select and try if the behaviour will be the same or different :slight_smile:

https://dash-bootstrap-components.opensource.faculty.ai/docs/components/input/

As a bonus each component library preserve some unified style so mixing component libraries results in weird matches or a lot of customization of components styles on your side.

3 Likes