21
votes

I'm learning shiny apps and have some basic questions about tweaking the layout, particularly style and font. I'd be grateful for pointers or explicit answers, thanks!

Consider a basic input-output app: the user inputs data in the sidebarPanel and it reactively outputs a result in the mainPanel.

enter image description here

  1. How could I format the output table in the mainPanel to look more like the sidebarPanel? say a rectangle of about the same size with a colored background (maybe another color) and the data appearing in a box of similar size.

  2. How can I control the font type, font size, and font size inside the panels?

As you can see from the code (c.f. runGist details a couple of lines below), I have been successful in customizing the size of the numericInput box in the sidebarPanel, but I have not been able to control the font styles (is my tag$style code misplaced?).

More importantly for aesthetic purposes, I couldn't work out how to format the mainPanel to make it look like the sidebarPanel. Mostly I modified examples from the shiny website, but obviously I missed out on some important things.

Edit 1: Following Scott Chamberlain's suggestion, I have copied the server.R and ui.R files on github:

library("shiny") 
runGist("gist.github.com/annoporci/7313856") 

Edit 2: Scott suggested using Chrome/Firefox "Inspect Element" (right click on body of html page, other browsers may have the same function). Below is a screenshot:

Inspect Element

enter image description here

Scott's suggestion to use the "Inspect Element" tool proved very fruitful.

Here is what I learned (if I'm not mistaken):

  • container-fluid and row-fluid control the overall container.
  • span12 controls the headerPanel
  • span4 controls the sidebarPanel
  • span8 controls the mainPanel
  • shiny-bound-input is for the input side
  • shiny-bound-output and shiny-html-output(both appear to be valid) are for the output side

Based on these findings, I placed the HTML styles in the mainPanel, because it seemed like an obvious place, but it appears to work also inside the sidebarPanel. It would be more intuitive (to me) to place it immediately inside the pageWithSidebar(), but that didn't work.

Here is the edited shiny:

runGist("https://gist.github.com/annoporci/7346772")

Here are the HTML styles:

  HTML('<style type="text/css">
    .row-fluid { width: 50%; }  
    .well { background-color: #99CCFF; }
    .shiny-html-output { font-size: 20px; line-height: 21px; }
  </style>')

I selected 50% for the overall container width, to keep it small.

I selected the same color for the sidebarPanel and mainPanel.

I selected a larger font for the output, which is not pretty here but makes sense in my real-life app. And besides I'm experimenting more than anything.

I selected a line-height of 21px rather than the default 20px just to tweak the height of the output box to be the same as the input box. Again, an experiment.

I also changed the display style in server.R, namely

output$myResults <- renderText({
  r <- myFunction(input$myinput)
  c("My Output:","<br><br>",r)
})

This is because I wanted to have the result displayed below the words "My Output". By trial and error, I discovered that I could squeeze strings in a vector c() with <br><br> as a separator to force a line break. I'd be shocked if this were the recommended approach, so please chime in if you know the correct way of doing this.

Follow-up Questions of lesser importance:

I'll see if I can find a way to have my output result appear in a white-colored box similar to the input number in the sidebarPanel. Any suggestions welcome.

Might it be feasible to gather all html modifications in the same, separate file to be stored together with server.R and ui.R ?

I'll select Scott's answer because he has helped discover enough to get my output just about the way I wanted it. But please do edit if you see errors or imprecisions in my description above.

3
You could put these two files in a gist, then we could easily test it out, like so gist.github.com/SChamberlain/7309662, Then we can do library(shiny); runGist("gist.github.com/SChamberlain/7309662")sckott
That worked very well, thanks Scott! library("shiny") runGist("gist.github.com/annoporci/7313856")PatrickT

3 Answers

7
votes

You can include arbitrary html, for example, within the call to sidebarpanel, you can do

HTML('<style type="text/css">
     .row-fluid .span4{width: 26%;}
     </style>')

this is just something copied from one of my Shiny apps

You could use inspector tools in the browser to figure out what css elements need to be changed.

If you use a wellPanel inside the mainPanel this modifies that wellPanel to be blue

HTML('<style type="text/css">
        .span8 .well { background-color: #00FFFF; }
        </style>'), 
4
votes

This is a really old post, but for posterity: you can just put css in your mainPanel() call. If you want a fixed-position plot in the mainPanel in a sidebar layout:

sidebarLayout(
     sidebarPanel(), 
     mainPanel(style="position:fixed;margin-left:32vw;",
          plotOutput("plot")
     )
)
3
votes

Another way to insert styling in Shiny is through its tag command. The result will be the same as inserting plain HTML:

tags$style(type="text/css", ".span8 .well { background-color: #00FFFF; }")

the result will be the same as inserting plain HTML code (in this example the result would be the same as the last code snippet by Scott)