make a shiny app w3c compliant

Hi all,
I've written and optimized a Shiny app, and now I'm struggling with the IT section of the organization where I work to have it published on their servers.
Currently, they are claiming that the app is not W3C compliant, which is true, according to the W3C validator.

The errors I'm trying to solve, with no success, are:

  • <form class="well" role="complementary"> Bad value “complementary” for attribute “role” on element “form”.

  • <label class="control-label" id="foo-label" for="foo"> The value of the “for” attribute of the “label” element must be the ID of a non-hidden form control.

Such errors can be seen also in very minimal shiny apps, like:

# Reprex adapted from https://shiny.rstudio.com/gallery/tabsets.html
library(shiny)

# Define UI for random distribution app ----
ui <- fluidPage(
  
  # App title ----
  titlePanel("Tabsets"),
  
  # Sidebar layout with input and output definitions ----
  sidebarLayout(
    
    # Sidebar panel for inputs ----
    sidebarPanel(
      
      # Input: Select the random distribution type ----
      radioButtons("dist", "Distribution type:",
                   c("Normal" = "norm",
                     "Uniform" = "unif",
                     "Log-normal" = "lnorm",
                     "Exponential" = "exp")),
      
      # br() element to introduce extra vertical spacing ----
      br(),
      
      # Input: Slider for the number of observations to generate ----
      sliderInput("n",
                  "Number of observations:",
                  value = 500,
                  min = 1,
                  max = 1000)
      
    ),
    
    # Main panel for displaying outputs ----
    mainPanel(
      
      # Output: Tabset w/ plot, summary, and table ----
      tabsetPanel(type = "tabs",
                  tabPanel("Plot", plotOutput("plot")),
                  tabPanel("Summary", verbatimTextOutput("summary")),
                  tabPanel("Table", tableOutput("table"))
      )
      
    )
  )
)

# Define server logic for random distribution app ----
server <- function(input, output) {
  
  # Reactive expression to generate the requested distribution ----
  d <- reactive({
    dist <- switch(input$dist,
                   norm = rnorm,
                   unif = runif,
                   lnorm = rlnorm,
                   exp = rexp,
                   rnorm)
    
    dist(input$n)
  })
  
  # Generate a plot of the data ----
  output$plot <- renderPlot({
    dist <- input$dist
    n <- input$n
    
    hist(d(),
         main = paste("r", dist, "(", n, ")", sep = ""),
         col = "#75AADB", border = "white")
  })
}

# Create Shiny app ----
shinyApp(ui, server)

The second error seems to be related, somehow, to radiobuttons only, whereas the first one seems to afflict all the shiny apps I've found on the web and tested with the W3C validator so far.
For completeness, I report also the HTML code generated by the shiny app in the reprex:

<!DOCTYPE html>
<html>
<head>
  <meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
  <script type="application/shiny-singletons"></script>
  <script type="application/html-dependencies">jquery[3.6.0];shiny-css[1.7.1];shiny-javascript[1.7.1];ionrangeslider-javascript[2.3.1];strftime[0.9.2];ionrangeslider-css[2.3.1];bootstrap[3.4.1]</script>
<script src="shared/jquery.min.js"></script>
<link href="shared/shiny.min.css" rel="stylesheet" />
<script src="shared/shiny.min.js"></script>
<script src="shared/ionrangeslider/js/ion.rangeSlider.min.js"></script>
<script src="shared/strftime/strftime-min.js"></script>
<link href="shared/ionrangeslider/css/ion.rangeSlider.css" rel="stylesheet" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<link href="shared/bootstrap/css/bootstrap.min.css" rel="stylesheet" />
<link href="shared/bootstrap/accessibility/css/bootstrap-accessibility.min.css" rel="stylesheet" />
<script src="shared/bootstrap/js/bootstrap.min.js"></script>
<script src="shared/bootstrap/accessibility/js/bootstrap-accessibility.min.js"></script>  <title>Tabsets</title>
</head>
<body>
  <div class="container-fluid">
    <h2>Tabsets</h2>
    <div class="row">
      <div class="col-sm-4">
        <form class="well" role="complementary">
          <div id="dist" class="form-group shiny-input-radiogroup shiny-input-container" role="radiogroup" aria-labelledby="dist-label">
            <label class="control-label" id="dist-label" for="dist">Distribution type:</label>
            <div class="shiny-options-group">
              <div class="radio">
                <label>
                  <input type="radio" name="dist" value="norm" checked="checked"/>
                  <span>Normal</span>
                </label>
              </div>
              <div class="radio">
                <label>
                  <input type="radio" name="dist" value="unif"/>
                  <span>Uniform</span>
                </label>
              </div>
              <div class="radio">
                <label>
                  <input type="radio" name="dist" value="lnorm"/>
                  <span>Log-normal</span>
                </label>
              </div>
              <div class="radio">
                <label>
                  <input type="radio" name="dist" value="exp"/>
                  <span>Exponential</span>
                </label>
              </div>
            </div>
          </div>
          <br/>
          <div class="form-group shiny-input-container">
            <label class="control-label" id="n-label" for="n">Number of observations:</label>
            <input class="js-range-slider" id="n" data-skin="shiny" data-min="1" data-max="1000" data-from="500" data-step="1" data-grid="true" data-grid-num="9.99" data-grid-snap="false" data-prettify-separator="," data-prettify-enabled="true" data-keyboard="true" data-data-type="number"/>
          </div>
        </form>
      </div>
      <div class="col-sm-8" role="main">
        <div class="tabbable">
          <ul class="nav nav-tabs" data-tabsetid="9747">
            <li class="active">
              <a href="#tab-9747-1" data-toggle="tab" data-bs-toggle="tab" data-value="Plot">Plot</a>
            </li>
            <li>
              <a href="#tab-9747-2" data-toggle="tab" data-bs-toggle="tab" data-value="Summary">Summary</a>
            </li>
            <li>
              <a href="#tab-9747-3" data-toggle="tab" data-bs-toggle="tab" data-value="Table">Table</a>
            </li>
          </ul>
          <div class="tab-content" data-tabsetid="9747">
            <div class="tab-pane active" data-value="Plot" id="tab-9747-1">
              <div id="plot" class="shiny-plot-output" style="width:100%;height:400px;"></div>
            </div>
            <div class="tab-pane" data-value="Summary" id="tab-9747-2">
              <pre class="shiny-text-output noplaceholder" id="summary"></pre>
            </div>
            <div class="tab-pane" data-value="Table" id="tab-9747-3">
              <div id="table" class="shiny-html-output"></div>
            </div>
          </div>
        </div>
      </div>
    </div>
  </div>
</body>
</html>

Do you have any suggestions?
Thanks!

For future readers: Here the SO crosspost can be found.

This topic was automatically closed 54 days after the last reply. New replies are no longer allowed.

If you have a query related to it or one of the replies, start a new topic and refer back with a link.