It used to be that modal dialogs were an annoying user experience problem on the web. Actually, who am I kidding, they still are. But, they don't have to be.

Often times I find I can allow a user to opt-in to some content related to the web page, or walk them through an Ajax backed web form within a modal dialog in a way that lowers the barrier of engagement with the page. I've done this in several recent projects and have been very happy with the results. And, from what I have seen, so are my users.

However, modal dialogs are particularly challenging when they are long, and require the user to scroll. This situation is happening more and more as I see web pages increasingly accessed from devices with small screen sizes.

The Broken Long Dialog

The first problem with long dialogs is scrolling. You can see the scrolling problem manifest in the broken demo. (You can see the html, css, and JavaScript source files for the broken demo as a gist on Github.)

Most users will be lost on the page after scrolling and closing the dialog, since they are dropped off in an unfamiliar position after the dialog closes. This is very likely to happen on devices with small screens. Those few users who are able to realize what has happened will be annoyed at having to scroll back up to where they were before the dialog opened. Try the demo on your smartphone to see what I mean.

Secondly, if the user scrolls to the bottom of the page (the call to action button at the bottom of the demo), and then opens the dialog, it will cause the viewport to extend much longer than intended. This is annoying and could even result in a layout that looks "broken".

User Friendly Modal Dialog (Part 1)

To fix the first problem we use JavaScript to cache the scroll position of the viewport when the user opens the dialog so we can return to the same position when it is closed.

We can mostly solve the second problem, the extended viewport, by hiding the main content of the page. This can be done by using JavaScript to set the inline style of the main page content to visibility:hidden. By using the visibility CSS property instead of display:none the entire container is hidden from view, but the layout is preserved. In other words it is still taking up as much space on the page as if it were still visible.

I call this the "positioned" dialog since it depends on the position: absolute CSS property. Check out the positioned demo to see it in action. The source code is available for html, css, and JavaScript.

User Friendly Modal Dialog (Part 2)

But, of course, we can do better. You'll notice that if you open the dialog from the call to action at the bottom of the page in the positioned demo, you can scroll back up to the top of the page while the dialog is still open. I see this a lot, especially on the mobile web, but in my world, it's broken.

What I like better is to do what I call a card swap. Imagine each content block as a card in a deck; the main content and the dialog. Only one card is shown at a time, while the other is hidden. I call this the "card deck" dialog. Check out the deck demo to see it in action.

The JavaScript for the card deck still caches the scroll position of the main content card so we can return the user to the exact scroll position they were at before they opened the dialog. However, since the script uses display: none to hide the main content instead of visibility: hidden, the viewport is only as tall as it needs to be to contain the dialog. This is possible because we no longer need position: absolute for the dialog when using this method.

Again, the source code for the deck demo is available for html, css, and JavaScript.

To Summarize

Use a combination of Ajax and modal dialogs to lower the barrier to engagement on a web page, but make sure those long modal dialogs are not disorienting the user.

I've seen modal dialogs that put a scroll bar inside the dialog container, but I think they look like... Well, they don't look very nice.