使用Fluidrow和column的闪亮应用存在溢出问题

SNT*_*SNT 2 css r shiny

我在闪亮的应用程序中使用流畅的行和列布局。当我减小屏幕尺寸时,两列中的元素会重叠。如果它们是两个不同的列,并且使用流体行,则内容不应重叠。下面是代码。我有两列,宽度分别为4和8。它们在正常的屏幕尺寸下似乎工作正常,但是一旦我最小化窗口,它们就会重叠。

library(shiny)
library(shinyjs)

ui <- navbarPage(
  "Bootstrap scrollspy on multiple tabs",
  id = "navbar",
  header = div(
    useShinyjs(),
    extendShinyjs("www/app-shinyjs.js", functions = c("updateScrollspy")),
    includeCSS("www/app.css"),
    includeScript("https://cdnjs.cloudflare.com/ajax/libs/jquery-scrollTo/1.4.3/jquery.scrollTo.min.js")
  ),

  # tab 1 contains 4 sections and a scrollspy on the left with text
  tabPanel(
    "tab1",
    div(id = "tab1-content",
        fluidRow(
          column(
            4,
            div(
              id = "tab1-scrollspy",
              class = "potential-scrollspy",
              tags$ul(
                class = "nav nav-pills nav-stacked",
                tags$li(tags$a(href = "#section1-1", "Section 1-1")),
                tags$li(tags$a(href = "#section1-2", "Section 1-2")),
                tags$li(tags$a(href = "#section1-3", "Section 1-3")),
                tags$li(tags$a(href = "#section1-4", "Section 1-4"))
              )
            )
          ),
          column(
            8,
            div(id = "section1-1",
                class = "scrollspy-section",
                p('Section 1-1')
            ),
            div(id = "section1-2",
                class = "scrollspy-section",
                p('Section 1-2')
            ),
            div(id = "section1-3",
                class = "scrollspy-section",
                p('Section 1-3')
            ),
            div(id = "section1-4",
                class = "scrollspy-section",
                p('Section 1-4')
            )              
          )
        )
    )
  ),

  # tab 2 contains 3 sections and a scrollspy on the right without text
  tabPanel(
    "tab2",
    div(id = "tab2-content",
        fluidRow(
          column(
            8,
            div(id = "section2-1",
                class = "scrollspy-section",
                p('Section 2-1')
            ),
            div(id = "section2-2",
                class = "scrollspy-section",
                p('Section 2-2')
            ),
            div(id = "section2-3",
                class = "scrollspy-section",
                p('Section 2-3')
            )
          ),
          column(
            4,
            div(
              id = "tab2-scrollspy",
              class = "potential-scrollspy",
              `data-offset` = 50,
              tags$ul(
                class = "nav nav-pills nav-stacked",
                tags$li(tags$a(href = "#section2-1")),
                tags$li(tags$a(href = "#section2-2")),
                tags$li(tags$a(href = "#section2-3"))
              )
            )
          )
        )
    )
  )
)

server <- function(input, output, session) {
  # when changing tabs, update the scrollspy control
  observeEvent(input$navbar, {
    js$updateScrollspy(input$navbar)
  })
}

shinyApp(ui = ui, server = server)
Run Code Online (Sandbox Code Playgroud)

屏幕尺寸缩小: 在此处输入图片说明

library(shiny)
library(shinyjs)

ui <- navbarPage(
  "Bootstrap scrollspy on multiple tabs",
  id = "navbar",
  header = div(
    useShinyjs(),
    extendShinyjs("www/app-shinyjs.js", functions = c("updateScrollspy")),
    includeCSS("www/app.css"),
    includeScript("https://cdnjs.cloudflare.com/ajax/libs/jquery-scrollTo/1.4.3/jquery.scrollTo.min.js")
  ),

  # tab 1 contains 4 sections and a scrollspy on the left with text
  tabPanel(
    "tab1",
    div(id = "tab1-content",
        fluidRow(
          column(
            4,
            div(
              id = "tab1-scrollspy",
              class = "potential-scrollspy",
              tags$ul(
                class = "nav nav-pills nav-stacked",
                tags$li(tags$a(href = "#section1-1", "Section 1-1")),
                tags$li(tags$a(href = "#section1-2", "Section 1-2")),
                tags$li(tags$a(href = "#section1-3", "Section 1-3")),
                tags$li(tags$a(href = "#section1-4", "Section 1-4"))
              )
            )
          ),
          column(
            8,
            div(id = "section1-1",
                class = "scrollspy-section",
                p('Section 1-1')
            ),
            div(id = "section1-2",
                class = "scrollspy-section",
                p('Section 1-2')
            ),
            div(id = "section1-3",
                class = "scrollspy-section",
                p('Section 1-3')
            ),
            div(id = "section1-4",
                class = "scrollspy-section",
                p('Section 1-4')
            )              
          )
        )
    )
  ),

  # tab 2 contains 3 sections and a scrollspy on the right without text
  tabPanel(
    "tab2",
    div(id = "tab2-content",
        fluidRow(
          column(
            8,
            div(id = "section2-1",
                class = "scrollspy-section",
                p('Section 2-1')
            ),
            div(id = "section2-2",
                class = "scrollspy-section",
                p('Section 2-2')
            ),
            div(id = "section2-3",
                class = "scrollspy-section",
                p('Section 2-3')
            )
          ),
          column(
            4,
            div(
              id = "tab2-scrollspy",
              class = "potential-scrollspy",
              `data-offset` = 50,
              tags$ul(
                class = "nav nav-pills nav-stacked",
                tags$li(tags$a(href = "#section2-1")),
                tags$li(tags$a(href = "#section2-2")),
                tags$li(tags$a(href = "#section2-3"))
              )
            )
          )
        )
    )
  )
)

server <- function(input, output, session) {
  # when changing tabs, update the scrollspy control
  observeEvent(input$navbar, {
    js$updateScrollspy(input$navbar)
  })
}

shinyApp(ui = ui, server = server)
Run Code Online (Sandbox Code Playgroud)
// initialize common scrollspy control
shinyjs.init = function() {
  $('body').scrollspy({ target: '.active-scrollspy' });
}

// update the active scrollspy control and refresh so that it will function
shinyjs.updateScrollspy = function(tab) {
  // make all scrollspy controls inactive
  $('active-scrollspy').removeClass('active-scrollspy');
  // get the content in the current tab
  var $tabContent = $('#' + tab + '-content');
  if ($tabContent.length) {
    // find the scrollspy control in the current tab
    var $scrollspy = $tabContent.find('.potential-scrollspy');
    if ($scrollspy.length) {
      // mark the scrollspy in the current tab as active
      $scrollspy.addClass('active-scrollspy');
      // figure out the offset for this scrollspy
      var offset = 0;
      if ($scrollspy.data('offset')) {
        offset = $scrollspy.data('offset');
      }
      // update the scrollspy object
      $('body').data('bs.scrollspy').options.offset = offset;
      $('body').scrollspy('refresh');
      // unbind click events and re-bind clicks to animate scrolling
      $scrollspy.unbind('click.scrollto');
      $scrollspy.bind('click.scrollto', 'ul li a', function(event) {
        event.preventDefault();
        $.scrollTo(event.target.hash, 500, {
          offset: -offset
        });
      });
    }
  }
}
Run Code Online (Sandbox Code Playgroud)

K. *_*hde 5

This is intended.

What you experience here is a feature of Bootstrap, the responsive breakpoint. In its edge case: There is a minimum width for which all containers will span over the whole page. This is done mainly for websites to become mobile friendly, since i.e. a column that spans over a third of the device gets very narrow and can become really hard to read. And therefore it is intended, that "columns" get disbanded at a certain point.

If you really dont want this to happen, you have two options.

Either, knowing that this happens with bootstrap, you refrain from using columns and specify the div width youself, such that it is fixed no matter what.

Or you try to counter act the bootstrap css by including another style sheet. You can look through the bootstrap.css for media queries that are responsible for the breaks. And then copy the styles and apply them to the very small screen sizes. I took the liberty to create a css that would be sufficient for your cases, posted below:

bs-no-break.css

@media (max-width: 768px) {
  .col-sm-1, .col-sm-2, .col-sm-3, .col-sm-4, .col-sm-5, .col-sm-6, .col-sm-7, .col-sm-8, .col-sm-9, .col-sm-10, .col-sm-11, .col-sm-12 {
    float: left;
  }
  .col-sm-12 {
    width: 100%;
  }
  .col-sm-11 {
    width: 91.66666667%;
  }
  .col-sm-10 {
    width: 83.33333333%;
  }
  .col-sm-9 {
    width: 75%;
  }
  .col-sm-8 {
    width: 66.66666667%;
  }
  .col-sm-7 {
    width: 58.33333333%;
  }
  .col-sm-6 {
    width: 50%;
  }
  .col-sm-5 {
    width: 41.66666667%;
  }
  .col-sm-4 {
    width: 33.33333333%;
  }
  .col-sm-3 {
    width: 25%;
  }
  .col-sm-2 {
    width: 16.66666667%;
  }
  .col-sm-1 {
    width: 8.33333333%;
  }
  .col-sm-pull-12 {
    right: 100%;
  }
  .col-sm-pull-11 {
    right: 91.66666667%;
  }
  .col-sm-pull-10 {
    right: 83.33333333%;
  }
  .col-sm-pull-9 {
    right: 75%;
  }
  .col-sm-pull-8 {
    right: 66.66666667%;
  }
  .col-sm-pull-7 {
    right: 58.33333333%;
  }
  .col-sm-pull-6 {
    right: 50%;
  }
  .col-sm-pull-5 {
    right: 41.66666667%;
  }
  .col-sm-pull-4 {
    right: 33.33333333%;
  }
  .col-sm-pull-3 {
    right: 25%;
  }
  .col-sm-pull-2 {
    right: 16.66666667%;
  }
  .col-sm-pull-1 {
    right: 8.33333333%;
  }
  .col-sm-pull-0 {
    right: auto;
  }
  .col-sm-push-12 {
    left: 100%;
  }
  .col-sm-push-11 {
    left: 91.66666667%;
  }
  .col-sm-push-10 {
    left: 83.33333333%;
  }
  .col-sm-push-9 {
    left: 75%;
  }
  .col-sm-push-8 {
    left: 66.66666667%;
  }
  .col-sm-push-7 {
    left: 58.33333333%;
  }
  .col-sm-push-6 {
    left: 50%;
  }
  .col-sm-push-5 {
    left: 41.66666667%;
  }
  .col-sm-push-4 {
    left: 33.33333333%;
  }
  .col-sm-push-3 {
    left: 25%;
  }
  .col-sm-push-2 {
    left: 16.66666667%;
  }
  .col-sm-push-1 {
    left: 8.33333333%;
  }
  .col-sm-push-0 {
    left: auto;
  }
  .col-sm-offset-12 {
    margin-left: 100%;
  }
  .col-sm-offset-11 {
    margin-left: 91.66666667%;
  }
  .col-sm-offset-10 {
    margin-left: 83.33333333%;
  }
  .col-sm-offset-9 {
    margin-left: 75%;
  }
  .col-sm-offset-8 {
    margin-left: 66.66666667%;
  }
  .col-sm-offset-7 {
    margin-left: 58.33333333%;
  }
  .col-sm-offset-6 {
    margin-left: 50%;
  }
  .col-sm-offset-5 {
    margin-left: 41.66666667%;
  }
  .col-sm-offset-4 {
    margin-left: 33.33333333%;
  }
  .col-sm-offset-3 {
    margin-left: 25%;
  }
  .col-sm-offset-2 {
    margin-left: 16.66666667%;
  }
  .col-sm-offset-1 {
    margin-left: 8.33333333%;
  }
  .col-sm-offset-0 {
    margin-left: 0;
  }
  .navbar-right .dropdown-menu {
    right: 0;
    left: auto;
  }
  .navbar-right .dropdown-menu-left {
    right: auto;
    left: 0;
  }
  .navbar {
    border-radius: 4px;
  }
  .navbar-header {
    float: left;
  }
  .navbar-collapse {
    width: auto;
    border-top: 0;
    -webkit-box-shadow: none;
            box-shadow: none;
  }
  .navbar-collapse.collapse {
    display: block !important;
    height: auto !important;
    padding-bottom: 0;
    overflow: visible !important;
  }
  .navbar-collapse.in {
    overflow-y: visible;
  }
  .navbar-fixed-top .navbar-collapse,
  .navbar-static-top .navbar-collapse,
  .navbar-fixed-bottom .navbar-collapse {
    padding-right: 0;
    padding-left: 0;
  }
  .container > .navbar-header,
  .container-fluid > .navbar-header,
  .container > .navbar-collapse,
  .container-fluid > .navbar-collapse {
    margin-right: 0;
    margin-left: 0;
  }
  .navbar-static-top {
    border-radius: 0;
  }
  .navbar-fixed-top,
  .navbar-fixed-bottom {
    border-radius: 0;
  }
  .navbar > .container .navbar-brand,
  .navbar > .container-fluid .navbar-brand {
    margin-left: -15px;
  }
  .navbar-toggle {
    display: none;
  }
  .navbar-nav {
    float: left;
    margin: 0;
  }
  .navbar-nav > li {
    float: left;
  }
  .navbar-nav > li > a {
    padding-top: 15px;
    padding-bottom: 15px;
  }
  .navbar-left {
    float: left !important;
  }
  .navbar-right {
    float: right !important;
    margin-right: -15px;
  }
  .navbar-right ~ .navbar-right {
    margin-right: 0;
  }
}
Run Code Online (Sandbox Code Playgroud)