0

I'm making a user interface in Shiny and am trying to make a bunch of stylized buttons. I suceeded in having them be the color I want, and the last thing I want is for the button to darken on hover, like the default buttons do.

I've made the following function for these buttons:

    dateButton <- function(id, label) {
    actionButton(inputId = id, label = label, style = "color: white;
    background-color: darkblue;
    border-radius:15%;
    border-color: white;
    .hover {
    box-shadow: inset 0 0 100px 100px rgba(255, 255, 255, 0.1);
    }")
    }

I'm sure the problem is .hover, I can't find how to format these list-like attributes. Any resources would also be appreciated.

Repr:

    library(shiny)
    dateButton <- function(id, label) {
    actionButton(inputId = id, label = label, style = "color: white;
    background-color: darkblue;
    border-radius:15%;
    border-color: white;
    .hover {
    box-shadow: inset 0 0 100px 100px rgba(255, 255, 255, 0.1);;}")

    ui <- fluidPage(
      dateButton("my_button", "B1"),
      actionButton("default_button", "B2")
    )

    server <- function(input, output, session) {
  
    }

    shinyApp(ui, server)
}

When ran, B2 does what I want on hover, while B1 doesn't.

Konrad Rudolph
  • 530,221
  • 131
  • 937
  • 1,214
M K
  • 3
  • 3

1 Answers1

2

It doesn't seem possible to add the :hover pseudo-class selector to an object's inline style attribute. Instead it would work most smoothly to either insert as a <head><style>... section or link to an external style sheet (more examples here). First of these options as shown below:

library(shiny)
dateButton <- function(id, label) {
  actionButton(
    inputId = id,
    label = label
  )
}

ui <- fluidPage(
  tags$head(tags$style(HTML("
                            #my_button {
                              background-color: darkblue;
                              color: white;
                              border-radius:15%;
                              border-color: white;
                            }
                            #my_button:hover {
                              box-shadow: inset 0 0 100px 100px rgba(255, 255, 255, 0.1);
                              font-weight: bold
                            }
                            "))),
  dateButton("my_button", "B1"),
  actionButton("default_button", "B2"))

server <- function(input, output, session) {
  
}

shinyApp(ui, server)

Edit - making a class to be shared across buttons

If you want to apply this to more buttons, add a class attribute in your constructor function call, and use css accordingly:

library(shiny)
dateButton <- function(id, label) {
  actionButton(
    inputId = id,
    class = "hover-button",
    label = label
  )
}

ui <- fluidPage(
  tags$head(tags$style(HTML("
                            .hover-button {
                              background-color: darkblue;
                              color: white;
                              border-radius:15%;
                              border-color: white;
                            }
                            .hover-button:hover {
                              box-shadow: inset 0 0 100px 100px rgba(255, 255, 255, 0.1);
                              font-weight: bold
                            }
                            "))),
  dateButton("my_button", "B1"),
  actionButton("default_button", "B2"))

server <- function(input, output, session) {
  
}

shinyApp(ui, server)
Andy Baxter
  • 5,833
  • 1
  • 8
  • 22
  • Thank you for your answer, this works. However, the reasoning for making a function is so multiple buttons with similar formatting could be created (concretely, five). Here, seems like I'd need to copy and paste the HTML for each button, changing the id. I'll look into linking to external CSS. Perhaps a custom class could also work? But I'm not sure it wouldn't overwrite other default-button-class properties. – M K Jan 17 '23 at 21:27
  • You can indeed do this with a class. Above I've added `class = "hover-button"` to your `dateButton` function which adds the css class to the html object. The changed css will then look for `.hover-button` class objects and apply the same formatting. Using style in this way doesn't override other default button classes, it just appends it to the list of classes and adds extra rules. All other rules still apply to the button, but overlapping elements are overridden by the new class style (such as `background-color` here). Hope that helps! – Andy Baxter Jan 17 '23 at 23:28
  • 1
    Great, that's exactly what I needed! I accepted this as the answer. – M K Jan 18 '23 at 12:44