1

I am writing an R Shiny app and use CSS to format the buttons on the header and footer of the page. I am running into a sticky situation with the Upload button, where no matter how I configure, it will always be placed slightly higher than the rest of the buttons.

Screenshot

Could someone have a look at the CSS portion and point me in the right direction?

Code has been formatted to be ready to run.

#SETUP-----------------------
library(shiny)
library(shinyjs)
select<-dplyr::select


#UI-------------------
ui<-fluidPage(useShinyjs(),
              tags$head(
                #Page headers formatting
                tags$style(HTML('
                            body{
                                  font-family:Arial,sans-serif;
                            }
                            .header{
                                  background-color:#f5f5f5;
                                  padding:10px 20px;
                                  border-bottom:1px solid #ddd;
                                  display:flex;
                                  align-items:center;
                            }
                            .header h3{
                                  margin:0;
                                  margin-right:15px;
                                  font-weight:bold;
                                  color:#000000;
                            }
                            .header .nav-link{
                                  margin-right:15px;
                                  cursor:pointer;
                                  font-size:15px;
                                  color:#000000;
                                  text-decoration:none;
                            }
                            .header .nav-link:hover{
                                  text-decoration:underline;
                            }
                            .container-main{
                                  max-width:1400px;
                                  margin:0 auto;
                                  padding:0 15px;
                            }
                            
                            #import_data_upper.shiny-input-container,
                            #import_data_lower.shiny-input-container,
                            #nav_dropdown_upper_ui .shiny-input-container,
                            #nav_dropdown_lower_ui .shiny-input-container,
                            .selectize-input,
                            .input-group-btn .btn{
                                  margin:0;
                                  height:30px !important;
                                  min-height:30px !important;
                                  font-size:15px !important;
                                  line-height:1.5 !important;
                                  vertical-align:middle;
                            }

                            #import_data_upper.shiny-input-container,
                            #import_data_lower.shiny-input-container,
                            #nav_dropdown_upper_ui .shiny-input-container,
                            #nav_dropdown_lower_ui .shiny-input-container{
                                  display:inline-block;
                                  min-width:300px;
                            }

                            .selectize-input{
                                  padding:4px 10px !important;
                            }
                            
                            #import_data_upper .input-group-btn + input[type="text"],
                            #import_data_lower .input-group-btn + input[type="text"]{
                                  display:none;
                            }
                            
                            #import_data_upper .input-group,
                            #import_data_lower .input-group{
                                  width:auto;
                                  height:30px;
                            }
                          '
                )),
              ),
              div(class="header",
                  h3("Header",style="font-size:15px;font-weight:bold;"),
                  actionLink("nav_home","Home",class="nav-link"),
                  actionLink("nav_conduct","Start",class="nav-link"),
                  div(style="margin-left:auto; display: flex; align-items: center; gap: 10px;",
                      uiOutput("nav_dropdown_upper_ui"),
                      downloadButton("export_data_upper","Export Data",class="btn-sm"),
                      fileInput("import_data_upper",label=NULL,buttonLabel="Import Data",accept=".csv")
                  )
              ),
              #Responsive to screen width
              div(class="container-main",
                  mainPanel(width=12,
                            br(),
                            uiOutput("page_content"),
                            hr(),
                            br(),
                            hidden(
                              div(id="nav_buttons",style="display:flex;justify-content:center;align-items:center;gap:10px;margin-top:20px;",
                                  actionButton("prev_button","Previous",class="btn-sm"),
                                  actionButton("next_button","Next",class="btn-sm"),
                                  uiOutput("nav_dropdown_lower_ui"),
                                  downloadButton("export_data_lower","Export Data",class="btn-sm"),
                                  fileInput("import_data_lower",label=NULL,buttonLabel="Import Data",accept=".csv")
                              )
                            )
                  )
              )
)

#SERVER-----
server<-function(input,output,session){
  current_page<-reactiveVal(0)
  data_storage<-reactiveValues()
  
  #Navigation Observers
  observeEvent(input$nav_home,{
    current_page(0)
  })
  
  observeEvent(input$nav_conduct,{
    current_page(0)
  })
  
  
  #Page choices for dropdown
  page_choices<-reactive({
    choices<-list("Navigate to..."=0)
    return(choices)
  })
  
  #Render UI for dropdowns
  output$nav_dropdown_upper_ui<-renderUI({
    selectInput("nav_dropdown_upper",label=NULL,
                choices=page_choices(),
                selected=current_page(),width="250px")
  })
  
  output$nav_dropdown_lower_ui<-renderUI({
    selectInput("nav_dropdown_lower",label=NULL,
                choices=page_choices(),
                selected=current_page(),width="250px")
  })
  
  #Handle Dropdown Navigation
  handle_dropdown_nav<-function(val){
    req(val)
    page_val<-as.numeric(val)
    if(page_val>0&&page_val!=isolate(current_page())){
      current_page(page_val)
    }
  }
  
  observeEvent(input$nav_dropdown_upper,{handle_dropdown_nav(input$nav_dropdown_upper)},ignoreNULL=TRUE,ignoreInit=TRUE)
  observeEvent(input$nav_dropdown_lower,{handle_dropdown_nav(input$nav_dropdown_lower)},ignoreNULL=TRUE,ignoreInit=TRUE)
  
  #Import Observers
  observeEvent(input$import_data_upper,{
    handle_import(input$import_data_upper)
  })
  
  observeEvent(input$import_data_lower,{
    handle_import(input$import_data_lower)
  })
  
  #Button Visibility Logic
  observe({
    show("nav_buttons")
    disable("prev_button")
    disable("next_button")
  })
}

shinyApp(ui=ui,server=server)
1
  • 4
    Would you be able to replicate the issue on a codepen instead? it would be hard for others to help you with your question since it will take much effort to replicate the problem if they aren't using a R Shiny environment. Otherwise you might just be able to debug it on your own by right clicking the fileInput element and inspecting it on the browser dev tools. Commented 11 hours ago

1 Answer 1

2

Below the upload-container, there is space reserved for a progress bar ruining your alignment. You can either add this CSS

.form-group.shiny-input-container{margin-bottom: -40px;}

and force the alignment, risking that the progress bar will overlap force


Or set progress bar height to 0px if hidden, and 20px if visible

.progress.shiny-file-input-progress {height: 0px;  margin-bottom: -15px;} 
.progress.shiny-file-input-progress[style*="visibility: visible"] {height: 20px}

Before upload before After upload after Not sure, if you want to keep the progress bar. If not, then you can just permanently set .progress height to 0px (omit the second line above).


Note: Uploading crashes the server, because there is no download-handler defined; this is why it appears grey.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.