How can I prevent body scrollbar and shifting when twitter bootstrap modal dialog is loaded?

前端 未结 11 1255
灰色年华
灰色年华 2020-12-23 16:42

When I open the twitter bootstrap modal dialog, the backdrop causes a scrollbar and shift the content.

To avoid the scrollbar I use this css:

.modal         


        
相关标签:
11条回答
  • 2020-12-23 17:11

    The following inclusion to my .css file fixed my centered content page from moving or resizing when the popup modal shows.

    I did not need any Javascript, just the css code below. This fixed it for content with or without a vertical or horizontal scrollbar.

    .modal
    {
        overflow-y: auto !important;
    }
    
    .modal-open {
        overflow: auto !important;
        overflow-x: hidden !important;
        padding-right: 15px !important;
    }
    

    I'm using bootstrap 3.3.7.

    0 讨论(0)
  • 2020-12-23 17:13

    Marko,

    I just had the same problem. It appears that Bootstrap 3.0.0 adds a class to <body>, modal-open, when the modal first shows. This class adds margin-right: 15px to the body to account for a scrollbar, which is there on longer pages. This is great, except for shorter pages when a scrollbar isn't on the body. In the no scrollbar case, the margin-right causes the body to shift left on modal open.

    I was able to solve this by adding some short Javascript and a little CSS:

    CSS:

    /* override bootstrap 3 class to remove scrollbar from modal backdrop
       when not necessary */
    .modal {
      overflow-y: auto;
    }
    /* custom class to override .modal-open */
    .modal-noscrollbar {
        margin-right: 0 !important;
    }
    

    JS:

    (function($) {
    
    $(document)
        .on( 'hidden.bs.modal', '.modal', function() {
            $(document.body).removeClass( 'modal-noscrollbar' );
        })
        .on( 'show.bs.modal', '.modal', function() {
            // Bootstrap adds margin-right: 15px to the body to account for a
            // scrollbar, but this causes a "shift" when the document isn't tall
            // enough to need a scrollbar; therefore, we disable the margin-right
            // when it isn't needed.
            if ( $(window).height() >= $(document).height() ) {
                $(document.body).addClass( 'modal-noscrollbar' );
            }
        });
    
    })(window.jQuery);
    

    These combined permit the margin-right scrollbar fix to work for long pages, yet is disabled for shorter pages (when document height <= window height). I hope this helps!


    Bootstrap 3.0.1+ (tested up to 3.1.1) is a different story. Try the following:

    CSS:

    /* override bootstrap 3 class to remove scrollbar from modal backdrop
       when not necessary */
    .modal {
      overflow-y: auto;
    }
    /* custom class to add space for scrollbar */
    .modal-scrollbar {
        margin-right: 15px;
    }
    

    JS:

    (function($) {
    
    $(document)
        .on( 'hidden.bs.modal', '.modal', function() {
            $(document.body).removeClass( 'modal-scrollbar' );
        })
        .on( 'show.bs.modal', '.modal', function() {
            // Bootstrap's .modal-open class hides any scrollbar on the body,
            // so if there IS a scrollbar on the body at modal open time, then
            // add a right margin to take its place.
            if ( $(window).height() < $(document).height() ) {
                $(document.body).addClass( 'modal-scrollbar' );
            }
        });
    
    })(window.jQuery);
    

    EDIT:

    In light of Mac eliminating scrollbars from inhabiting window render width, here's a more portable solution (3.0.1+) if you don't mind some feature detection. Reference: http://davidwalsh.name/detect-scrollbar-width

    CSS:

    .scrollbar-measure {
        height: 100px;
        overflow: scroll;
        position: absolute;
        top: -9999px;
    }
    

    JS:

    window.jQuery(function() {
      // detect browser scroll bar width
      var scrollDiv = $('<div class="scrollbar-measure"></div>')
            .appendTo(document.body)[0],
          scrollBarWidth = scrollDiv.offsetWidth - scrollDiv.clientWidth;
    
      $(document)
        .on('hidden.bs.modal', '.modal', function(evt) {
          // use margin-right 0 for IE8
          $(document.body).css('margin-right', '');
        })
        .on('show.bs.modal', '.modal', function() {
          // When modal is shown, scrollbar on body disappears.  In order not
          // to experience a "shifting" effect, replace the scrollbar width
          // with a right-margin on the body.
          if ($(window).height() < $(document).height()) {
            $(document.body).css('margin-right', scrollBarWidth + 'px');
          }
        });
    });
    
    0 讨论(0)
  • 2020-12-23 17:13

    the best way is:

    • to add to BODY overflow-y: scroll
    • and remove 4 functions from bootstrap.js: checkScrollbar, setScrollbar, resetScrollbar, and measureScrollbar.
    0 讨论(0)
  • 2020-12-23 17:13

    Try this simple javascript:

    $j(document).ready(function() {
         if ($(document).height() <= $(window).height()) {
             $('body').css('margin-right','0','!important');
          }      
     });
    
    0 讨论(0)
  • 2020-12-23 17:21

    I had the same issue with the scroll bar disappearing, and the body shifting to the left when opening a bootstrap modal.

    I've found out an easy fix:

    .modal
    {
        overflow-y: auto !important;
    }
    
    .modal-open
    {
       overflow:auto !important;
       overflow-x:hidden !important;
       padding-right: 0 !important;
    }
    

    Good luck to all!

    0 讨论(0)
  • 2020-12-23 17:21

    I added this to my CSS and seemed to work when adding a 'fixed' overlay to view

    .modal-open {
        margin-right: 15px;
    }
    
    0 讨论(0)
提交回复
热议问题