pythoncsspy-shiny

How to target Shiny's inputs with CSS selectors?


I want to CSS style my Shiny for Python input fields, but it somehow doesn't work. I can however style the card headers. Does anyone know, what I am doing wrong? Or can the ui.input* elements not be styled directly?

from shiny import App, render, ui, reactive
from pathlib import Path


app_ui = ui.page_fillable(
    ui.panel_title(
        ui.row(
        ui.column(12, ui.h1("title1")),
        )
    ),
    ui.layout_sidebar(
        ui.sidebar(
            ui.input_text("input_text1", "input_text1", value=""),
            ui.input_selectize("input_selectize1", "input_selectize1", choices=["1", "2"]),
            ui.input_numeric("input_numeric1", "input_numeric1", value=4),
            ui.input_switch("input_switch1", "input_switch1", value=False),
            ui.input_action_button("input_action_button1", "input_action_button1"),
            width="350px"
        ),
        ui.layout_columns(
            ui.card(
                ui.card_header("card_header1"),
                ui.output_data_frame("card1"),
                full_screen=True
            ),
            col_widths=12
        )
    ),
    ui.tags.style(
    ".card-header { color:white; background:#2A2A2A !important; }",
    ".input-text { color:red; height:0px; }",
    ".input-numeric { color:red; height:0px; }")
)


def server(input, output, session):

    @reactive.event(input.input_action_button1)
    def reactive_function1():
        pass

    @output
    @render.data_frame
    def card1():
        return reactive_function1()

src_dir = Path(__file__).parent / "src"
app = App(app_ui, server, static_assets=src_dir)

Solution

  • You can target an input by its type, e.g. input[type = 'text'] for the ui.input_text() (see also <input>: The HTML Input element within the MDN Docs). The ui.input_selectize(), however, works a bit different, here you could use .selectize-input.

    An example would be this:

    from shiny import App, render, ui, reactive
    from pathlib import Path
    
    app_ui = ui.page_fillable(
        ui.panel_title(
            ui.row(
            ui.column(12, ui.h1("title1")),
            )
        ),
        ui.layout_sidebar(
            ui.sidebar(
                ui.input_text("input_text1", "input_text1", value=""),
                ui.input_selectize("input_selectize1", "input_selectize1", choices=["1", "2"]),
                ui.input_numeric("input_numeric1", "input_numeric1", value=4),
                ui.input_switch("input_switch1", "input_switch1", value=False),
                ui.input_action_button("input_action_button1", "input_action_button1"),
                width="350px"
            ),
            ui.layout_columns(
                ui.card(
                    ui.card_header("card_header1"),
                    ui.output_data_frame("card1"),
                    full_screen=True
                ),
                col_widths=12
            )
        ),
        ui.tags.style(
        ".card-header { color:white; background:#2A2A2A !important; }",
        "input[type = 'text'] { background-color:red; height:0px; }",
        "input[type = 'number'] { background-color:green; }",
        ".selectize-input { background-color:yellow !important; height:0px; }")
    )
    
    
    def server(input, output, session):
    
        @reactive.event(input.input_action_button1)
        def reactive_function1():
            pass
    
        @output
        @render.data_frame
        def card1():
            return reactive_function1()
    
    src_dir = Path(__file__).parent / "src"
    app = App(app_ui, server, static_assets=src_dir)
    

    enter image description here