Search code examples
htmlcssrshinydashboard

How to center a CSS element under another in Shiny


I'm designing a Shiny app, and have an absolute panel that I'd like to have a dashboard-esque look.

Essentially, I have a few text-descriptions of buttons that I'd like to appear in the dashboard, with the buttons appearing centered underneath the text descriptions. I've currently used the absolute position control in CSS to determine the placement within the panel. While this works for now, I don't think it is a particularly scaleable method.

I have attached some reproducible code, so that you have an idea of what I'm talking about.

Thanks so much for your help.

library(shiny)
library(shinyWidgets)

ui <- fluidPage(
  absolutePanel(
    id = "quick-glance", style="z-index:500; opacity: 0.90",
    class = "panel panel-default",
    draggable=TRUE,
    fixed=TRUE,
    width = 180,
    height = 75,
    top = 20, left = 50,

    textOutput("label1"), tags$head(tags$style("#label1{
                                               color: steelblue;
                                               font-weight: bold; 
                                               border: none;
                                               position: absolute; top: 5px; left: 30px;
                                               ")),
    actionBttn("bttn1",label = "$##",style = "bordered",color = "primary"),
    tags$head(tags$style("#bttn1{ position: absolute; bottom: 5px; left: 20px;}")),

    textOutput("label2"),tags$head(tags$style("#label2{
                                              color: steelblue;
                                              font-weight: bold; 
                                              border: none;
                                              position: absolute; top: 5px; left: 100px;
                                              ")),
    actionBttn("bttn2",label = "#",style = "bordered",color = "danger"),
    tags$head(tags$style("#bttn2{ position: absolute; bottom: 5px; left: 110px;}"))


    )
    )

server <- function(input, output, session) {
  output$bttn1 = renderPrint(input$bttn1)
  output$label1 = renderText("Text")

  output$label2 = renderText("Text Text")
  output$bttn2 = renderPrint(input$bttn2)

}

shinyApp(ui, server)

Solution

  • It's best to wrap the things you want grouped in a column(), which creates a div you can then center. Then, within each such div you can center the text and the button.

    library(shiny)
    library(shinyWidgets)
    
    ui <- fluidPage(
      absolutePanel(
        id = "quick-glance", style="z-index:500; opacity: 0.90",
        class = "panel panel-default",
        draggable=TRUE,
        fixed=TRUE,
        width = 180,
        height = 75,
        top = 20, left = 50,
        fluidRow(
          column(
            textOutput("label1"), 
            actionBttn("bttn1",label = "$##",style = "bordered",color = "primary"),
            width = 1
          ),
          column(
            textOutput("label2"), 
            actionBttn("bttn2",label = "#",style = "bordered",color = "danger"),
            width = 1
          )
        ),
        tags$head(tags$style(".col-sm-1 {width: 50%; margin: 0px;}
                              #label1, #bttn1, #label2, #bttn2 {margin: 0 auto; width: 100%; text-align: center}"))
      )
    )
    
    server <- function(input, output, session) {
      output$bttn1 = renderPrint(input$bttn1)
      output$label1 = renderText("Text")
    
      output$label2 = renderText("Text Text")
      output$bttn2 = renderPrint(input$bttn2)
    
    }
    
    shinyApp(ui, server)