Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Footer Position in Shiny

I would like to adjust the footer position in a shiny app. When the page content is shorter than the viewport, the footer should be at the bottom of the viewport. When the page content is longer than the viewport, the footer should be below the content. This post suggests how to usually implement it in CSS. This and similar solutions are commonly straightforward to use when writing the page's HTML code by hand.

There are discussions on footer positions in shiny and some of them manage to move the footer to the bottom. However, they fail to keep the footer from overlapping with the bottom of the page's main content, which requires shortening the main content's container.

Consider the following minimal working example:

library(shiny)

ui <- navbarPage(title = "Some Example", id = "example",
    tabPanel(title = "Something", value = "something",
        textOutput("some_text")
    ),
    footer = "The footer."
)

server <- function(input, output, session) {
    output$some_text <- renderText(stringi::stri_rand_lipsum(5))
}

shinyApp(ui = ui, server = server)
like image 813
Chr Avatar asked May 30 '21 17:05

Chr


1 Answers

It is possible to have a footer like you describe, but it is not straightforward to implement. There does not seem to be a built-in function to position the footer, let alone in the way you would like.

So, we need to write some custom CSS. To do so, we need to be able to target the footer. When we look at the HTML produced by the example, we can see that the content specified by the argument footer is simply wrapped in a <div> tag with class row.

      <div class="container-fluid">
        <div class="tab-content" data-tabsetid="6611">
          <div class="tab-pane active" data-value="something" id="tab-6611-1">
            <div id="some_text" class="shiny-text-output"></div>
          </div>
        </div>
        <div class="row">The footer.</div>
      </div>
    </body>
    </html>

In any reasonably sized shiny app, there will be multiple <div>s with this class, which makes it difficult to write CSS which reliably targets just the footer. A workaround is the following:

    ui <- tagList(navbarPage(
      title = "Some Example",
      id = "example",
      tabPanel(
        title = "Something",
        value = "something",
        textOutput("some_text")
      )),
      tags$footer("The footer.", class = "footer")
    )

Now all that is left to do is adding CSS that positions the footer. I use the example found on the Bootstrap website. A way to integrate this into shiny is like so:

    ui <- tagList(
      tags$head(
        tags$style(HTML(
          "html {
             position: relative;
             min-height: 100%;
           }
           body {
             margin-bottom: 60px; /* Margin bottom by footer height */
           }
           .footer {
             position: absolute;
             bottom: 0;
             width: 100%;
             height: 60px; /* Set the fixed height of the footer here */
             background-color: #f5f5f5;
           }"))),
      navbarPage(
      title = "Some Example",
      id = "example",
      tabPanel(
        title = "Something",
        value = "something",
        textOutput("some_text")
      )),
      tags$footer("The footer.", class = "footer")
    )

Replacing the UI in the example with the UI above will produce the desired footer that sticks to the bottom of the viewport when the content is short, but is below the content when the content is longer than the viewport.

like image 163
Tim Avatar answered Oct 19 '22 18:10

Tim