Fixed header position in bootstrap 3 modal

2019-01-17 07:01发布

问题:

I want to use a fixed header in my Bootstrap modal, however if I set .modal-header as position:fixed it scrolls along with the moda content. How do I create a trully fixed header in BS modal?

回答1:

Instead of trying to make the header fixed, just fix the height of the body and make it scrollable. That way the header (and footer) will always be visible.

You can easily do this using the CSS3 vh unit together with calc. Both vh as calc have pretty good browser support (IE9+).

The vh unit is relative to the viewport (= browser window) height. 1 vh is 1% of the height and 100vh means 100% of the viewport height.

We just need to substract the height of the modal's header, footer and margins. It's going to be difficult it that dynamic. If those sizes are fixed, we just add all the heights.

Set either the height or max-height to calc(100vh - header+footer px).

.modal-body {
    max-height: calc(100vh - 210px);
    overflow-y: auto;
}

See the jsfiddle



回答2:

Here's a simple trick. Let me assume that i have to fix the div with class "fixedHeader"

Simple Jquery Way:

$('.modal').scroll(function() {
     var a=$('.modal').scrollTop();
     $('.fixedHeader').css('top',a+'px');
});

CSS

.fixedHeader {
    position:fixed;
}

Whatever i have answered above is for normal bootstrap using jquery.But if someone is using angular bootstrap for the modal then

Angular

$timeout(function() {
    angular.element('.modal').scroll(function() {
        var a = angular.element('.modal').scrollTop();
        angular.element('.fixedHeader').css('top', a + 'px');
    });
}, 10);
/*Put the above in modalinstance controller*/
/*timeout is necessary as you want to run the function after the modal is loaded or sometimes it may be unable to find the class '.modal' */

CSS

.fixedHeader {
    position:fixed;
}

Make sure you have jquery dependency installed in both cases.



回答3:

My solution may seem a little silly, but it details the steps I took to solve this problem for my use case.

I tried something like ritz078's answer, but what I found was that it did not work well on iOS when scrolling, since Safari likes to do things its own way.

So, my solution was to duplicate the bit of code I wanted to affix and place that duplicate code outside of the modal altogether in its own hidden wrapper:

<div class="fixed-header">
    <div class="modal-header">
        <button type="button" class="close" data-dismiss="modal" aria-hidden="true">&times;</button>
        <h4 class="modal-title">Modal title</h4>
    </div>
</div>

Then I used JS to 1) make the duplicate code visible after I scroll through the modal a bit, 2) close the duplicate code whenever I click out of the modal, and 3) restore functionality to the duplicate modal's close button:

$('#myModal').on('scroll', function() {
    var threshold = 60;

    if ($('#myModal').scrollTop() > threshold) {
        $('.fixed-header').addClass('affixed');
    }
    else {
        $('.fixed-header').removeClass('affixed');
    }
});

$('#myModal').on('hide.bs.modal', function (e) {
    $('.fixed-header').removeClass('affixed');
});

$('.fixed-header button').click(function() {
    $('#myModal').modal('hide');
});

The challenge here is matching the modal's styling (particularly its width and margins), but this solution lets you scroll the modal freely on iOS without looking funky, which was my goal.

JSFiddle (forked from Jasny's answer to show how it's different in scope from his answer)



回答4:

As per my comment, this was actually an improvement in Bootstrap 3. Allowing long content and having the whole modal scroll, not just the 'content' of the modal.

You can override it with something like this, but it's not as nice functionality.

.modal {
  overflow: hidden;
}

.modal-body {
  height: 300px;
  overflow: auto;
}

Demo



回答5:

In javascript add a class to modal:

windowClass: 'framework-modal'

In css adjust o modal-body:

.framework-modal .modal-body {
    max-height: 600px;
    overflow: auto;
}


回答6:

In Body content

CSS:

body{
    overflow:hidden;
}