Skip to content
This repository

Refine responsive modal variations #2130

Closed
thomaswinterstetter opened this Issue February 21, 2012 · 84 comments
Thomas Winterstetter

As it says. Thanks for all your love, guys!

Dan Stroot

I was going to put in something on this very topic but suggest the modal should render at the TOP of a iPhone. I have a long page (when responsively resized for the iPhone) and the modal is rendering at the very bottom so you have to scroll way down to find it. Should render at the top on responsive smaller screens no?

Thomas Winterstetter

Mark, you"ll figure out the smartest solution. Thanks!

Dan Stroot

I found that if I had the "fade" option on it rendered the modal at the bottom of my iPhone (bad) but if I turned off the "fade" option it renders at the top (good) so I'm happy - I just won't use fade.

Thomas Winterstetter

I replicate what @dstroot reports and think it is neither top or bottom the modal should render BUT, if that's technically feasible, where the link for the modal is located on the document. That would be in the center of the visible screen, like on desktop, so no scrolling to top or bottom will be necessary.

Trung Pham

Has anyone tried the modal on an android phone. It looks completely broken with the top and the bottom getting cut off from the screen.

Mark Otto mdo referenced this issue March 25, 2012
Closed

Responsive Modal #2736

ShaneSheppard

Is a fix on the way in 2.0.3?

Derek
asoap commented March 28, 2012

I'm using 2.0.2 and was having this issue with the iphone. I sorta hacked it together to force it to work.

I forced the backdrop to fill the background by directly setting the height of the black background.

function backdrop( callback ) {
var that = this
, animate = this.$element.hasClass('fade') ? 'fade' : ''

if (this.isShown && this.options.backdrop) {
  var doAnimate = $.support.transition && animate

  this.$backdrop = $('<div class="modal-backdrop ' + animate + '" />')
    .appendTo(document.body)

  // Edited here:  Set the height of the backdrop
  this.$backdrop.css( 'height', $(document).height() );

I also changed the show function. I overwrote some of the css properties with code, set the position to absolute and margin to 0. Then I manually calculated and set it's centered position.

, show: function () {
    var that = this

    if (this.isShown) return

    $('body').addClass('modal-open')

    this.isShown = true
    this.$element.trigger('show')

    // edit here to manually reposition
    this.$element.css('position', 'absolute');
    this.$element.css('margin', 0);
    var new_top = ($(window).height() / 2) - (this.$element.height() / 2) + $(window).scrollTop();
    this.$element.css('top', new_top);          
    var new_left = ($(window).width() / 2) - (this.$element.width() / 2);
    this.$element.css('left', new_left);

I don't know if this is the "proper" way or if it goes against any bootstrap philosophy. But it's doing the trick.

brightchimp

Hi,

Here's the start of a fix. It is only a start as I'm afraid it:
Does not work on android
Is not tested on blackberry
Is not tested on iOS <5

Android issue: If the modal height is greater than the screen, scrolling scrolls the background page, not the modal. The -webkit-overflow-scrolling: touch; line fixes this on iOS 5 but I don't think that is supported in iOS < 5.

My suspicion is that this only works on iOS 5+ so definitely not ready for inclusion but a possible starting point.

Props to @cferdinandi for -webkit-overflow-scrolling in issue #3230 (dupe?).

@media (max-width: 480px) {
  .modal {
    height: 500px; /* Set a default max height of the modal (adjusted later)*/
    position: fixed; /* Display modal in the centre of your screen */
    overflow-y: scroll; /*  Ensure that the modal is scroll-able */
    -webkit-overflow-scrolling: touch; /* Avoid having to use 2 finger scroll on iOS  */
  }
  .modal.fade.in{
    top: 5px; /* Use more screen real estate */
  }
  .modal-body{
    /* Increase the max height of the modal body to try & avoid both it,
     * and the modal container having scroll bars which results in odd behavior */ 
    max-height: 2400px; 
  }  
}

/* Now adjust the height so it handles various screen sizes & orientations */
/* You could make this as granular as you like, or have it more granular at common screen sizes
 * but it should start at the height we set on .modal (i.e. 500px) & work down */
@media (max-width: 480px) and (max-height: 500px){.modal{ height: 450px}}
@media (max-width: 480px) and (max-height: 450px){.modal{ height: 400px}}
@media (max-width: 480px) and (max-height: 400px){.modal{ height: 350px}}
@media (max-width: 480px) and (max-height: 350px){.modal{ height: 300px}}
@media (max-width: 480px) and (max-height: 300px){.modal{ height: 250px}}
@media (max-width: 480px) and (max-height: 250px){.modal{ height: 200px}}
@media (max-width: 480px) and (max-height: 200px){.modal{ height: 150px}}
Trevin
tmchow commented July 01, 2012

I was previously having trouble with a modal on a responsive site, but seemed to have solved it with just defining the modal right after the navigation. It now shows at the top where you'd expect it to. Have you tried that?

Chris Ferdinandi

@tmchow - Because modals are switched to relative positioning by default in Bootstrap, the issue is not so much that they don't show up at the top of the page, but that they show up at the top of the page even if you're near the bottom, which means the user may not realize there's a modal open. A user shouldn't have to scroll up to view an open modal - it should display wherever they are on the screen.

@brightchimp - any idea why that doesn't work in Android?

brightchimp

@cferdinandi

I'm not entirely sure why exactly but have just had a quick look to remind myself (slow & painful on my old phone).

The problem seems to be what -webkit-overflow-scrolling: touch was introduced to remedy (which Android does not support).

By giving the modal a fixed position, scrolling always scrolls the page in the background, not the contents of the modal. This is not an issue if you don't have much in your modal & it fits nicely on to one screen but if your content takes up more than one screen, anything beyond that is not accessible.

I am also noticing problems with clicking links & generally interacting with controls in the modal.

gudata
gudata commented July 05, 2012

Is it nice idea to make the modal respond to classes like .large .small etc?

Currently I need a modal which must be a little bit wider but I can't find "bootstrap way" to resize it.

bdd

:+1: Attempting to do an Android fix here.

piggyslasher

I can't test on anything other than Android Jelly bean at the moment...

but removing top: auto from .modal.fade.in from bootstrap.responsive.css and adding a margin-top:-25% into the main style sheet works for me.

.modal.fade.in {
margin-top: -25%;
top: 50%;
}

Tex8503

@piggyslasher - Your fix seems to work on iOS 5.1.1 as well.

Ionut Staicu
iamntz commented July 27, 2012

Hey guys. I had the same issue today and after I failed to make it work with CSS, I picked the hard way: JS!
So instead to reposition the whole modal box, I took another way: what if I just scroll the whole browser window?. So the show method became:

    , show: function () {
        var that = this
          , e = $.Event('show')
        that.oldWindowPosition = $(window).scrollTop(); // 
        $('body, html').scrollTop(0); //

And hide method became:

, hide: function (e) {
        e && e.preventDefault()

        var that = this
        $('body, html').scrollTop(that.oldWindowPosition) //

Lines that have // at the end are those that does the job.

piggyslasher
Ionut Staicu
iamntz commented July 27, 2012

@piggyslasher no, not really. The modal was displayed always on the top of the document. (latest stable iOS)

Adrian Stabiszewski

It might be interesting to consider a full screen modal on smartphone screens. Since the screen is so small already any additional borders and shadows are simply a waste of valuable space. If you position the modal as fixed it would also reduce the problems with modals not being visible.

Chris Ferdinandi

@grundid - That's a splendid recommendation. Shouldn't be too hard to implement, either.

Adrian Stabiszewski

My current version looks like this:

@media ( max-width : 580px) {
    .modal {
        bottom: 0;
        left: 0;
        position: fixed;
        right: 0;
        top: 0;
        width: auto;
        background-clip: padding-box;
        background-color: #FFFFFF;
        overflow: auto;
        z-index: 1050;
        margin: 0;
        border-radius: 0px;
        border: none;
    }
    .modal-footer {
        background-color: #F5F5F5;
        border-radius: 0 0 6px 6px;
        border-top: 1px solid #DDDDDD;
        bottom: 0;
        box-shadow: 0 1px 0 #FFFFFF inset;
        left: 0;
        margin-bottom: 0;
        padding: 14px 15px 15px;
        position: absolute;
        right: 0;
        text-align: right;
        max-height: 64px;
    }
}

I would like to have the footer always at the bottom, but the above version doesn't work quite well, if the content gets too large. Maybe you have an idea?

Nick Baugh

This snippet of jQuery should resolve issues #407, #1017, #1139, #2130, #3361, #3362, #4283 and all other bootstrap mobile modal window resizing issues for the most part!

Gist: Twitter Bootstrap modal responsive fix

// # Twitter Bootstrap modal responsive fix by @niftylettuce
//  * resolves #407, #1017, #1339, #2130, #3361, #3362, #4283
//   <https://github.com/twitter/bootstrap/issues/2130>
//  * built-in support for fullscreen Bootstrap Image Gallery
//    <https://github.com/blueimp/Bootstrap-Image-Gallery>

// **NOTE:** If you are using .modal-fullscreen, you will need
//  to add the following CSS to `bootstrap-image-gallery.css`:
//
//  @media (max-width: 480px) {
//    .modal-fullscreen {
//      left: 0 !important;
//      right: 0 !important;
//      margin-top: 0 !important;
//      margin-left: 0 !important;
//    }
//  }
//

var adjustModal = function($modal) {
  var top;
  if ($(window).width() <= 480) {
    if ($modal.hasClass('modal-fullscreen')) {
      if ($modal.height() >= $(window).height()) {
        top = $(window).scrollTop();
      } else {
        top = $(window).scrollTop() + ($(window).height() - $modal.height()) / 2;
      }
    } else if ($modal.height() >= $(window).height() - 10) {
      top = $(window).scrollTop() + 10;
    } else {
      top = $(window).scrollTop() + ($(window).height() - $modal.height()) / 2;
    }
  } else {
    top = '50%';
    if ($modal.hasClass('modal-fullscreen')) {
      $modal.stop().animate({
          marginTop  : -($modal.outerHeight() / 2)
        , marginLeft : -($modal.outerWidth() / 2)
        , top        : top
      }, "fast");
      return;
    }
  }
  $modal.stop().animate({ 'top': top }, "fast");
};

var show = function() {
  var $modal = $(this);
  adjustModal($modal);
};

var checkShow = function() {
  $('.modal').each(function() {
    var $modal = $(this);
    if ($modal.css('display') !== 'block') return;
    adjustModal($modal);
  });
};

var modalWindowResize = function() {
  $('.modal').not('.modal-gallery').on('show', show);
  $('.modal-gallery').on('displayed', show);
  checkShow();
};

$(modalWindowResize);
$(window).resize(modalWindowResize);
$(window).scroll(checkShow);
Deleted user

The content you are editing has changed. Reload the page and try again.

Thanks @niftylettuce ! Works great for me!

Sending Request…

Attach images by dragging & dropping or selecting them. Octocat-spinner-32 Uploading your images… Unfortunately, we don't support that file type. Try again with a PNG, GIF, or JPG. Yowza, that's a big file. Try again with an image file smaller than 10MB. This browser doesn't support image attachments. We recommend updating to the latest Internet Explorer, Google Chrome, or Firefox. Something went really wrong, and we can't process that image. Try again.

bdd
Joe Rawlings

Thanks @niftylettuce this solves most of our issues. However, it appears modals in landscape mode are still not properly displaying.

Nick Baugh

@jrawlings I believe it needs a slight patch to adjust for mobile orientation change, however if you load the page in landscape mode and then click the modal (on a mobile device or <= 480 resolution) then it should be ok.

Tim Bunch

@niftylettuce - You are a godsend!

Brad Robertson

I don't really see why this problem needs to be fixed with JS (ie @niftylettuce's fix). None of the model positioning, animations etc involve javascript, it's all css. I think the cleaner fix is to improve upon the responsive code (which is obviously broken) so that it actually works.

vyach

@bradrobertson could you post the fix you are talking about?

Brad Robertson

haha, i'm working on it, Only just started looking at bootstrap and realized the mobile side of things is a bit shaky for modals. Hopefully have a working solution soon.

Brad Robertson

at first glance, it's the top:auto in responsive that's messing everything up. I've had a bit of success using:

// Modals
.modal {
  position: fixed;
  top:   20px;
  left:  20px;
  right: 20px;
  bottom: 20px;
  width: auto;
  margin: 0;
  &.fade.in { top: 20px; }
}

In the responsive 767 css. I fixed the height/width to take up the whole screen, leave the body to scroll. I don't really understand the original code of &.fade.in { top: auto; }

Nick Baugh
Brad Robertson

ah good one. so position absolute it is, I still don't understand the top:auto, it completely throws the modal off the window

Brad Robertson

i guess it's a bit f'd if you're already scrolled down and open the modal... ya i'll humbly revert on this one then. Doesn't look like there's a way you can cleanly do it with css for mobile (until everyone supports fixed position and overflow: scroll)

Nick Baugh

I've added many new features to the code snippet fix, which can be found here in a new repository:

https://github.com/niftylettuce/twitter-bootstrap-jquery-plugins/tree/master/modal-responsive-fix

Please update to version 0.0.2 :feelsgood:.

Just FYI to other users, this can be referenced to #407 #1017 #1339 #2130 #3361 #3362 #4283

Nick Baugh

@markdotto hey, did you want to look at refining the plugin and possibly adding it to the documentation?

Nick Baugh

Just pushed a bunch of fixes again. Should be in good working order, needs optimized though!

Jon Stevens

@niftylettuce can you put a demo up somewhere?

Nick Baugh

@lookfirst yea i will soon, good idea

Mark Otto
Owner

@niftylettuce Definitely would like to see a demo :).

Jon Stevens

Sorry to bring bad news, but this fails in ways that I thought it would based on looking at the source and now playing with it.

  1. Make the screen small, open it up (and try to scroll).
    http://www.evernote.com/shard/s178/sh/ac3f99fa-7e38-421a-875d-f1e055e259f8/018ce63dfd7d6b48a34dc97910e46c55

  2. It doesn't have the nice BS fade in/slide down effect when it opens.

  3. You really need to get rid of position: fixed. This means pulling the modal out of the DOM and sticking it before the body.

  4. Need to see a demo of stacked modals.

My code fixes all of these issues.

Nick Baugh

@lookfirst here are re's

  1. it's like that in normal bootstrap when your screen height is that small for desktop view (should adjust for phone/tablet)
  2. i disabled animation, and the modal don't have .fade.in classes added so thats obvs why they aren't working
  3. position fixed isn't being used except for desktop
  4. stacked modals? why would you stack modals?

what code? can you link me please? thanks!

Jon Stevens
  1. Existing BS is broken.
  2. Enable it. =)
  3. Fixed is bad.
  4. I use stacked modals for things like this: http://www.evernote.com/shard/s178/sh/2e67b0b4-fe81-4b8c-a8cd-cb5aa56a5cea/ec470361c16a9484524d27242601e6fd
  5. #4403
Nick Baugh

@lookfirst i agree on 1-5, ill look into alert dialog/additional modals, thank you for quick feedback

Nick Baugh

@lookfirst modifying modal.js is better ofc, ill look into your solution

Jon Stevens

The solution I have on my website is done by just overriding all the relevant methods in modal.js. I actually used CoffeeScript for that. If you'd like me to send you my code, let me know.

Nick Baugh

@lookfirst yeah if you could, a gist or email works

Jon Stevens

Funny, some of the CS code was auto converted from JS. ;-)

Edgar

OK so that fixes it pretty well for me thank you @niftylettuce

Nick Baugh
Nick Baugh

@orchid1software @lookfirst @markdotto @bradrobertson okay, version 0.0.4 is much better and works like it should (i think?)

http://niftylettuce.github.com/twitter-bootstrap-jquery-plugins/

Nick Baugh

really ugly though, patching bootstrap-modal.js much better route to go, this was just a quick hack so i can get moving

Jon Stevens

This is a great improvement! The responsive movement is really smooth.

I'm still kinda so so on the scrolling within the modal itself. I think this presents a bad UX. The reason is that it isn't always obvious that you need to scroll since the scrollbar is hidden by default on macs now. Maybe force turn it on?

It is still missing the fade in slide down from the top. That one was hard to do.

The delay stuff in your code is kinda hacky. Has to be a better way.

Brad Robertson
Edgar

Just wanted to post this. It's what I have experienced with the fix from @niftylettuce
http://www.youtube.com/watch?v=EI-F46yRycY&feature=youtu.be hope it sheds some light. I'm going to explore it a bit more.

Nick Baugh
Edgar

I am actually using version 0.0.4. But here is what i found out after I played with it for another hour trying to see what the issue really. What I discovered was this. When I am on the phone and I click once on the button that triggers the modal window, there is a delay or something. But here is the kicker, after just clicking it once if I touch the screen very gently so as to scroll the whole window up to get back to the top of the page, if I do it very gently the modal will pop up. This only happens on the first touch. Only on the first touch it freezes up after that all is well. Very peculiar.

Edgar

I'm going to play with it some more and look at the code in your fix a bit more. Maybe its the way I am implementing it or something else that is messing with it. Can you tell me if my use is correct.
$.ajax({
url : my_url
type :'POST',
dataType:'JSON',
success :function (data) {
$(''modal_header').html(data.name);
$('.modal-body').html('');
$('#windowTitleDialog').modalResponsiveFix({});
$('#windowTitleDialog').touchScroll();
$('#windowTitleDialog').modal();
}
});

this is the basic code I know I am not caching my variables here, but its just to illustrate the way I am using it.
Maybe I am using the code improperly? Anyways I will investigate it some more and post back tomorrow unless you have some other opinion. BTW on Chrome for Android it really isnt working.

Nick Baugh

@orchid1software you are correct, the mobile bug happens for me as well, maybe someone else could have a go at refining this. also we need to add a meta tag in index.html for <meta name="viewport" content="width=device-width,user-scalable=no"> so we can test on mobile easier (we should also test without the viewport tag)

Nick Baugh

@orchid1software btw i had said to use v0.0.4 earlier b/c in the YouTube vid it said 0.0.3 on your screen

Nick Baugh

@orchid1software also thx for the vid and testing

Edgar

@niftylettuce OK I think I found a way to make it work http://www.youtube.com/watch?v=u1PDqNhrUjY&feature=youtu.be Basically you need to be sure ot use a button and not some other clickable item. I documented it here in this vide. Tested it several times and looks awesome. Really neede this to work thanks to Nifty lettuce. I know this is a temp fix but it works quite well as long as you use a button tag.

Deioo

For any other tags, use role="button" (e.g Modal link). Also removing the 'fade' class from the modal makes it kind of work on mobile devices. I say 'kind of' because the modal shows, but at a scale of 1/1 of the device, not the viewport.

Nick Baugh niftylettuce referenced this issue in blueimp/Bootstrap-Image-Gallery September 28, 2012
Closed

Integration with v0.0.3 of Modal Responsive Fix #35

Chris Love

What is the status of this bug? @markdotto is this something you guys are planning on improving? Please :)

dragonx

I had a bunch of mobile modal bugs sitting on the shelf for a couple months that I was dreading to look at. However, two quick fixes had the modals working satisfactorily for me:

  1. disable fade.
  2. add

    .modal-body { -webkit-overflow-scrolling:touch; }

Jordan Schroter

Bootstrap's modals also fell a bit short for my purposes as well so I took a crack at extending them. Here's a quick demo page that may be of interest: http://jschr.github.com/bootstrap-modal/

piggyslasher

@jschr - you've done it!

And its very very bootstrappy code. I hope this gets merged into the main bootstrap. Great work! Modal FULLY works across all devices. Hope @markdotto can merge this asap.

Trevin

I've tried this out on Safari on iOS 6 and @jschr's example doesn't fully work for me. When I try to scroll the modal window, it scrolls the pages behind the modal (you can see the page's scrollbar moving).

Jordan Schroter

@tmchow Ya I haven't been able to figure why the background still scrolls on mobile safari even though I've explicitly set overflow: hidden and position: relative. It's currently a known issue that I'm working on.

piggyslasher

@jschr in that case, maybe using touchscroll.js might be worth a shot? or just porting over some code into your js. The scrolling issue on ios was fixed by @niftylettuce using touchscroll.js

Tristan van Bokkem

@mdo you really should look into @jschr's code. He pretty close nailed it!
Any thoughts?

Mark Otto mdo closed this February 07, 2013
Mark Otto
Owner

Basically just took care of this today in #6342. Fuck yeah, responsive mobile-first modals! (Still a decent amount to do to make it mo betta, but the basics are all there.)

Tristan van Bokkem

Thanks :)

luisjunco

I tried quite a few options suggested here and in other issues. None of them worked in older versions of Android and iOS (I'm testing on Android 2.3 and iOS 3.1) with the exception of the solution suggested by @iamntz

Btw, you don't need to override the original methods. Bootstrap exposes the events shown and hidden, so you can just have the following:

$(document).ready(function () {
$('.modal').on('shown', function () {
$(this).data('oldWindowPosition', $(window).scrollTop());
$('body, html').scrollTop(0);
});
$('.modal').on('hidden', function () {
var target = $(this).data('oldWindowPosition');
$('body, html').scrollTop(target);
});
});

Nick Baugh

@mdo @jschr nice work guys

Skylar Saveland skyl referenced this issue in angular-ui/bootstrap April 24, 2013
Closed

Dialog / Modal centering issues #171

MikeSmith12222

Hi guys,

I am just starting a new project and wondering: What is the status of using modals in responsive design? Is it safe to use them?

Matthew Evans

I'm also wondering this, there's not brilliant support in 2.3.x, I assume there will be some nice support in 3.0 ?

Chris Ferdinandi

For anyone still working through this issue, I ended up just writing my own modal script instead: http://cferdinandi.github.io/modals/

Where Bootstrap struggles with this is around the absolute positioning coupled with overflow content (and the sometimes it works/sometimes it doesn't scrolling of that content). The script I wrote uses fixed positioning instead. Modals are automatically positioned based on where the user is on the screen, and when they scroll, the modal moves, too. This allows you to use a modal that expands vertically to accomodate more content, getting around the "scrolling inside the modal sucks on mobile devices" issue.

Jon Stevens

@cferdinandi I don't see how this is any better than the @jschr code. No animations and the modal seems pinned to the top of the window instead of centering on the screen. I'm all for new implementations, but I'd hope they'd be an advancement over existing solutions.

Chris Ferdinandi

@lookfirst - Sorry, I haven't been paying close attention to this thread in a while, so I didn't take a look at @jschr's work. Apologies for the redundancy.

Stefan Wehrmeyer stefanw referenced this issue in stefanw/froide May 30, 2013
Closed

Mobile: Modal popup cannot be scrolled #54

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Something went wrong with that request. Please try again.