Overlays with fixed positioning

— An article about: - CSS

position: fixed; is a much older feature of CSS than CSS grid. Many patterns of modern web applications can be implemented with it, though. It is especially handy when something needs to get overlaid on top of the viewport, without changing where it sits in the HTML.

A different kind of position: absolute

Like position: absolute;, position: fixed; removes the element it is applied to from the flow, collapsing the space it was due to take in the layout. It then positions it according to a combination of top/bottom & left/right offsets. The difference lies in according to what the element will be positioned. position: absolute uses the nearest ancestor whose position is not static. position: fixed uses the viewport, which is what makes it so handy to overlay things. On top of that, as the element is positioned according to the viewport, it’ll stay in position as users scroll the content underneath it.

Dialog

First thought when it comes to overlaying something is probably displaying a dialog for users to complete a small action. Let’s move the overlay to the center with:

.o-overlay--dialog {
    top: 50%;
    left: 50%;
    tansform: translate(-50%, -50%);
}

As we just specified two of the positioning offsets, the width and height will grow unconstrained, though. Super long words or a large amount of content might make things end up out of the viewport if we just leave it as is. To avoid that, let’s constrain the width and height a bit.

.o-overlay--dialog {
    /* ... */
    max-width: 100%;
    max-height: 100%;
    overflow: auto;
}

Voila! A dialog that can appear anywhere in the HTML and still be displayed at the center of the viewport, on top of the content.

Cover

Sometimes, you might want to grab users full attention and cover everything. Without unloading the content that’s already there. Setting each offset to 0 will do just that (provided the element doesn’t have any margin).

.o-overlay--cover {
    top: 0;
    right: 0;
    bottom: 0;
    left: 0;
    margin: 0;
    overflow: auto;
}

Combining the two previous patterns, we can quickly get a modal window, which will prevent users from clicking/tapping the underlying content.

Side panels

If you lose one of the offsets of the cover, you get side panels ready to contain a menu, additional side information or complex form controls. Depending on the content again, you’ll want to restrict the height or width to make sure the content doesn’t just spread over everything. For a left panel, this becomes:

.o-overlay--panelLeft {
  top: 0;
  left: 0;
  bottom: 0;
  overflow: auto;

  max-width: 40%;
}

Small notifications

Add a bit of margin (or more offset) to a panel displayed from the top and you get a nice container for a quick notification. This would enable a form component to completely control the markup of its success message, while displaying where needed to attract some attention.

.o-overlay-toastTop {
  top: 1em;
  left: 1em;
  right: 1em;
}

Playing with offsets, margins, and widths, you can get a wide variety of layouts. Vertical toolbars on the side of the viewport, chat windows popping from the bottom come to mind as other examples. These were just a few examples of how fixed positioning can help with some patterns found regularly in modern applications. While they surely could be implemented some other way, position: fixed; has this advantage of displaying things in a different place without touching the markup. A big plus when it comes to keeping things encapsulated. The markup for the modal window used by your custom form component can sit right inside that component, next to the <input> it enhances, rather than having to be appended some way to the <body>. As most techniques, it’s not a silver bullet, but it definitely comes handy. Let me know what you think of it!