How to create a custom resizable modal with scrollable and fixed content
Modal windows (aka modals) are everywhere in websites and web applications. They are the basic concept behind the so called pop-ups.
Modals are quite easy to develop and implement, but they come with an annoying problem: vertical resizing.
Use case
Let’s suppose that you want to develop a simple modal that has 2 types of content:
- fixed content (e.g. a title and a close button)
- scrollable content (e.g. a long text)
In addition, the modal has to be vertically resizable.
As stated in this interesting article, the task is not so easy as you could initially think.
Basic structure
Every modal generally has a basic HTML structure like the following:
As you can see, main-container
is the basically the page content and then we have two div
s:
modal-overlay
is an optionaldiv
that is used to add a kind of background layer between the page content and the modal;modal-container
is thediv
used for displaying the modal.
So, a specific event (e.g. user clicks on a button or user stays in the page for more than 15 secs) will add to the modal-overlay
and to the modal-container
a CSS class with properties that show the two div
s.
The Overlay
As said before, modal-overlay
is optional because maybe you don’t want to add an extra layer between main-content
and modal-container
.
Supposing that you want to add a semi-transparent background when a not-full-screen modal is opened, generally using a modal-overlay
is a good idea.
To have that kind of modal-overlay
, you could use some CSS properties similar to the following ones:
The modal-overlay
by default has display
property set to none
. The value will change to block
when a specific event occurs (e.g. when you want to open the modal) and the modal-overlay-visible
class is added to the modal.
The Modal
Implementing a basic modal is not so difficult:
And the result is ok.
But what happens:
- if the content exceeds the height of the modal and/or
- if the browser window is resized?
Yes, right guess! Something awful…
Luckily CSS has a good property called overflow-y
that you can set to auto
to prevent the previous behaviour.
Good, we are making some progress!
The modal is starting to look nice, but you’ll notice two things:
- all the modal content is scrollable, the close button too…
- you have the default scrollbar (that changes according to different OS)
The Solution
Considering that you want a fixed content for the title and the close button, you’ll need to create a substructure inside your modal-container
.
Now modal-container-content
will have 2 internal div
s:
modal-container-content-no-scroll
- thediv
dedicated for fixed content;modal-container-content-scroll
- thediv
dedicated for scrollable content.
Then, add the right CSS properties (and yes, also let’s add some styling for the close button):
Nice! ✨ Almost there…
One last retouch about the vertical scrollbar… I bet you don’t like default things. So, let’s give your new modal a completely different and fancy scrollbar:
Et voilà! 🎉
You can find all the code here in my repo. And here you can find a React example.
Obviously the general CSS style is not optimized, but my intent here is to help you not lose much time in finding the right HTML-CSS combination for having a good Y-axis resizable modal, without setting width and height in px.