Engineering
established 10 years ago

The current site with it's ugly markup and abysmal CSS has outlived it's usefulness. More and more people are trying, unsuccessfully, to use the site from mobile devices. So, before I embark on adding any new features, I've decided it's time to move the site over to something that will work equally well on mobile devices as on desktop PCs.

"Dammit, Jim, I'm a programmer, not a designer."

I started looking at a few so called Responsive CSS Frameworks. I chose Twitter Bootstrap v.3.1 because it seems to already address the vast majority of patterns I use on the site. I initially thought, as so many people seem to, that it's going to make the site look too "generic" since all sites that use bootstrap seem to have a similar appearance. But after taking a closer look, I realized that it was going to, once I finished the conversion, save me so much time and make developing the UI portion of any new features so much easier.

Unfortunately, this did mean I would have to rework quite a few interactive features. I make heavy use of jQuery UI dialogs which would have to be rebuilt as Bootstrap Modals. You can argue that it's not a good UX pattern, but I do in places do stacked dialogs. To my chagrin the bootstrap documentation has this to say:

Overlapping modals not supported

Be sure not to open a modal while another is still visible. Showing more than one modal at a time requires custom code.

There were a few questions about this topic on Stackoverflow such as this one. Hacking bootstrap, or any third party project, is generally a bad idea unless you can get them to accept a patch. I really didn't feel like going through another round of getting patches approved so I embarked on trying to come up with a way to implement stacking modals external to Bootstrap.

Thanks to answers in that Stackoverflow thread, the solution is pretty straight forward. Using the hidden.bs.modal and shown.bs.modal event callbacks we can keep track of the number of modals opened at a time. Given these are modals and not dialogs, only one modal should be active at a time. The rest should be disabled.

I create a counter on the body tag for lack of a better place. Each time a modal is shown I increment the counter and then decrement it again when the modal is closed.

Using this counter, I can quickly calculate a z-index for the modal and it's corresponding backdrop that will be higher than any other modal and backdrop on the page. This satisfies the 'disable everything else' requirement.

Setting the z-index of the modal is no problem, but finding the corresponding backdrop div requires doing a search for tags with class .modal-backdrop. To make sure I'm setting the z-index only on the most recent one, I set the z-index and also add a .fv-modal-stack class to it. Then when subsequent modals are opened, I look for all backdrops that do not have a class of fv-modal-stack.

The advantage of doing it this way is that I don't have to patch Bootstrap each time I upgrade. I suspect eventually they will add support for stacked modals and this hack can be avoided.

Here's a working demo. View the source to see the code.

    You must be a member of this group to post comments.

    Please see the top of the page to join.

    Link Details