Search code examples
rbuttonshinylayout

How to improve the ugly layout in R shiny


I want to display a list of buttons using the package shiny in R in a way similar to the java gridLayout:

Desired layout

After some trial and error I could produce this result. Unfortunately the buttons are not square and there is some space between rows, which I would like to avoid.

Could you suggest how to improve this layout?

My R code follows below:

library(shiny)

buttons <- list()

for (r in 1:3){
  for (c in 1:4){
    index <- c + r * 4 - 4
    
    buttons[[index]] <- absolutePanel(
      style='background-color:skyblue;',
      actionButton(style='background-color:#FFFFA0;',
                    paste0("but", as.character(index)),
                    index, width = 60, height = 60),
      top = 60 * r , left = 60 * c, width = 60, height = 60)
  }
}

# user interface
ui <- fixedPage(absolutePanel(buttons))

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

shinyApp(ui = ui, server = server)

Solution

  • One option to do exactly what you want is using css. To this, I added a class to the button and the add CSS code to achieve the desired output.

    library(shiny)
    
    buttons <- list()
    
    for (r in 1:3){
      for (c in 1:4){
        index <- c + r * 4 - 4
        
        buttons[[index]] <- absolutePanel(
          style='background-color:skyblue;',
          actionButton(class="square-button",
                       paste0("but", as.character(index)),
                       index, width = 80, height = 0),
          top = 80 * r , left = 80 * c, width = 80, height = 0)
      }
    }
    
    # user interface
    ui <- fixedPage(
      tags$link(rel = "stylesheet", href = "https://fonts.googleapis.com/css2?family=Comic+Neue&display=swap"),
      tags$style(
        HTML(
          ".square-button {
              margin: 0;
              padding: 0;
              width: 60px;
              height: 80px;
              line-height: 60px;
              text-align: center;
              font-size: 25px;
              font-weight: bold;
              display: inline-block;
              border: 1px; 
              border-style: solid;
              border-color: #969CA3;
              border-radius: 0px;
              background-color: skyblue;
              background-image: linear-gradient(white, #BFD4E9);
              font-family: 'Comic Neue', cursive; /* Apply comic font */
            }")),
      absolutePanel(buttons))
    
    # server function
    server <- function(input, output, session) {}
    
    shinyApp(ui = ui, server = server)
    

    enter image description here