Footer Position in Shiny
Asked Answered
I

2

8

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)
Icelandic answered 30/5, 2021 at 17:16 Comment(0)
O
7

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.

Oas answered 1/6, 2021 at 23:8 Comment(1)
Thanks. That is a lovely answer and exactly what I was looking for. The bounty is still blocked for another 12 hours. I will award it when it is available.Icelandic
L
0

I am not proficient in html, is this how the footer needs to look?

library(shiny)

ui <- navbarPage(title = "Some Example", id = "example",
                 tabPanel(title = "Something", value = "something",
                          textOutput("some_text"),
                          ##add a footer with 2 empty lines and the info to display
                          tags$footer(HTML('
                          <br>
                          <br>
                          <p>Author: Your Name<br>
                          <a href="mailto:[email protected]">[email protected]</a></p>'))
                 )
                 
)

server <- function(input, output, session) {
    output$some_text <- renderText(stringi::stri_rand_lipsum(15)) #change this number (15) to view how the footer reacts
}

shinyApp(ui = ui, server = server)

Or perhaps:

library(shiny)

ui <- navbarPage(title = "Some Example", id = "example",
                 tabPanel(title = "Something", value = "something",
                          textOutput("some_text"),
                          
                 
#add some empty lines to avoid overlap at the bottom    
tags$div(HTML('   <br>
                  <br>
                  <br>
                  <br>
                  <br>
                  <div class="footer">
                    <p>Author: Your Name<br>
                    <a href="mailto:[email protected]">[email protected]</a></p>
                  </div>')),
                  tags$style('
                  .footer {
                   position: fixed;
                   left: 0;
                   bottom: 0;
                   width: 100%;
                   background-color: lightgrey;
                   color: white;
                   text-align: right;}')),

tabPanel(title = "no_footer", value = "something",
         textOutput("some_text2")))

                 
                 


server <- function(input, output, session) {
    output$some_text <- renderText(stringi::stri_rand_lipsum(15)) #change this number (15) to view how the footer reacts
    output$some_text2 <- renderText(stringi::stri_rand_lipsum(5))
}

shinyApp(ui = ui, server = server)
Lashondra answered 1/6, 2021 at 22:25 Comment(1)
Thanks for the suggestions. However, neither of them implements what I was looking for. The first one does not flush the footer to the bottom of the viewport and the second one does not place the footer below the content in case the page content is longer than the viewport.Icelandic

© 2022 - 2024 — McMap. All rights reserved.