Search code examples
cssrshinyshinydashboard

How to adjust a Shiny Dashboard's size to fit different screen sizes?


I have a shiny app with this basic layout that I wrote on my desktop computer where it fits the screen perfectly. However, when running the app on my notebook it'll only show the top left boxes- so the app is way to big for the screen. Upon pressing Ctrl - it will obviously become smaller but still about a quarter of the bottom row is cut off and pressing Ctrl - again the app only fills half the screen. Now I want to provide this app as a feedback tool for my study participants and it's safe to assume they will access it from different sized screens aswell. So I was wondering if there was any way to automatically adjust the box sizes to the size of the screen, no matter its size. I came up with the idea that maybe the mistake was setting the box heights to a fixed value (i.e. height = 300), but my attempt of changing it to 30% revealed that that's not a thing you can do. I read over some CSS-related questions on this site aswell but didn't find anything that worked here either (I know very little CSS though, so I might have missed something there). Does anyone have an idea how to fix that issue?

library(shiny)
library(shinydashboard)

body <-  dashboardBody( tags$head(tags$style(HTML('
.box {margin-top: 2px;margin-left: 0px; margin-right: 0px; margin-bottom:2px;padding:-10px}
div {padding: 0 !important;}'
))),
fluidRow(
  box(      title = "Mediennutzung", background = "green", solidHeader = TRUE, height=300
            
  ),
  box(background = "green", title= "Verteilung", height = 300
  )
),

fluidRow(
  box(
    title = "Schlaf", width = 4, solidHeader = TRUE, status = "success",
    height= 350
  ),
  box(
    title = "Vergleich mit anderen", width = 5, solidHeader = TRUE, status = "success"
    , height= 350
  ),
  box(
    title = "Wohlbefinden", width = 3, solidHeader = TRUE, status = "success",
    "Ergebnis DASS und PMH, Einordnung, Vergleich mit der Stichprobe", height= 350
  )
),

fluidRow(
  box(
    width = 4, background = "green", title = "Warum ist das wichtig?",
     height= 135
  ),
  box(
    title = "Warum ist das wichtig?", width = 5, background = "green",
     height= 135
  ),
  box(
    title = "Warum ist das wichtig?",width = 3, background = "green",
     height= 135
  )
),

fluidRow(
  box(
    width = 4, background = "green", title= "Zusammenhang zur Mediennutzung",
    "Schlaf mag oder mag nicht mit der Mediennutzung zusammenhngen", height= 125
  ),
  box(
    title = "Zusammenhang zur Mediennutzung", width = 5, background = "green",
    "Mal gucken", height= 125
  ),
  box(
    title = "Zusammenhang zur Mediennutzung",width = 3, background = "green",
    "TBC", height= 125
  )
)
)




# here the actual app starts
ui <- dashboardPage(
  dashboardHeader(title = "Deine Ergebnisse"),
  dashboardSidebar(textInput(inputId = "Code", label= HTML("<b>Willkommen auf unserer Auswertungsseite! Bitte gib hier deinen persönlichen Code ein.</b><br><em>(Gross- oder Kleinschreibung ist egal) </em>"), placeholder= "z.B. 01ABAB01"),
                   actionButton (inputId = "Button", label = "Meine Ergebnisse anzeigen"),
                   box(width = 12, background= "blue", HTML(
                     "TEXT"))
  ),
  body)


server <- function(input, output) {}

shinyApp(ui=ui, server=server)

Solution

  • This solution might help you. I'm not very well versed in CSS so I don't think it is the most elegant way but it works. Try nesting your shinydashboard::box()'s in a div() with class that changes the size based on screensize.

    div(class = "col-sm-12 col-md-12 col-lg-4",
        shinydashboard::box(width = 12,
                            title = "Left or Upper Box",
                            p("This box will be 4 wide on large screen, and 12 wide on medium and small screens")
        )
    ),
    div(class = "col-sm-12 col-md-12 col-lg-8",
        shinydashboard::box(width = 12,
                            title = "Right or Lower Box",
                            p("This box will be 8 wide on large screen, and 12 wide on medium and small screens")
        )
    ),
    
    

    The downside of this approach is that there is extra padding either side of the boxes. There will be a way to remove this with some better CSS I bet. NOTE that the widths within the boxes themselves should be 12 so that they fill the div() at all widths.