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.
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)



