Popup windows without JavaScript

The other day I had this crazy idea. Popup/modal windows used in modern web design require JavaScript to be enabled in order to function. I wondered if you could get it working without JavaScript. It turns out you can.

How it works

You know what a target link is? You click on a link, and it’ll jump to a specific point on a page. You give the target an id, and you link to it like so:

<a href="#target">Link to #target</a>
<div id="target"></div>

There is a CSS pseudoclass called :target that allows a targeted element to be styled differently. A typical use would be to highlight the section that you just jumped to. It’s simple enough to style it:

div:target {
  /* styles go here */

Here’s something super simple in action:

This will work on pretty much any modern browser, by the way. Chrome, Safari, Firefox, Opera, and Internet Explorer all support it. The caveat is that it depends on the :target pseudo-class, so it won’t work on Internet Explorer 8 or lower. But would you be running that anyway?

Anyway, back to creating a popup window. Instead of having a visible container that changes styles on the jump, I’m defining the container as an overlay. So the first thing to do is create a container, which I’m giving a class of overlay.

<div class="overlay">

This isn’t the popup itself, but rather the backdrop for the popup. So before we create the popup itself, let’s define the overlay. (This is pretty standard stuff, and will prevent the user from clicking onto the page behind the popup.)

.overlay {
  position: absolute;
  top: 0;
  bottom: 0;
  left: 0;
  right: 0;
  background: rgba(0,0,0,0.5);
  transition: opacity 200ms;
  visibility: hidden;
  opacity: 0;

You’ll notice the last two styles are changing the overlay’s visibility and opacity. We could just use display: none instead, but then the CSS wouldn’t animate our transition. This way, the overlay (and popup, once we create it) will fade smoothly into view, instead of suddenly popping into view.

So now we’re ready to create our popup. Its markup will be placed inside our overlay, like so:

<div class="overlay">
  <div class="popup">

The styles for the popup don’t have to be anything special. I’m treating mine like a dialog box, so it’s not very large. Since this is a simple test, I’m not doing anything for multiple screen sizes, although if this were a real world scenario, I would recommend making it responsive.

.popup {
  margin: 75px auto;
  padding: 20px;
  background: #fff;
  border: 1px solid #666;
  width: 300px;
  box-shadow: 0 0 50px rgba(0,0,0,0.5);
  position: relative;

So how do we get the popup to display? First, we need a link to open it. So let’s make one:

<a href="#popup1">Click Me</a>

Now we need to match up what the link is calling, #popup1, with our overlay. So we’ll add the id to the overlay div:

<div id="popup1" class="overlay">
  <div class="popup">

It won’t work yet, because we haven’t added the style to show the overlay. Let’s do that now.

.overlay:target {
  visibility: visible;
  opacity: 1;

All we’re doing is changing those visibility styles so that the overlay is now visible. Everything else is already defined, and now we can click on our link to show our popup. Doing so will actually change the url, since it’s a target link, just like any “jump to section” link.

So how do we close the popup? Simple. We just need to move the target away from our overlay div, so we’ll make a link inside the popup with an href of “#”.

<a href="#">×</a>

&times; will make a times-symbol-style x, so we can style it to look just like a window-close x.

.close {
  position: absolute;
  width: 20px;
  height: 20px;
  top: 20px;
  right: 20px;
  opacity: 0.8;
  transition: all 200ms;
  font-size: 24px;
  font-weight: bold;
  text-decoration: none;
  color: #666;

And there we go, a working dialog box, complete with close button. All we have to do now is put content inside it. Of course, this isn’t something I’d expect anyone to actually implement; after all, it’s pretty standard to expect JavaScript to be enabled on modern websites. It was just a proof of concept, and I’m pretty happy to discover that it works.

I think that second popup in my code is especially cool. The popup’s close link isn’t in the popup; rather, it’s set outside the popup, styled as a secondary overlay. The resulting effect is being able to click anywhere outside the popup to close it

15 responses

  1. I enjoyed your article!

  2. Great web design and article thx!

  3. and how am I supposed to popy/caste this like I throw all my sites together, hmm? ;-))

  4. pageold Avatar

    hi.. thank you for your tutorial. it works extremely good! anyway, do u have any idea how to make when the pop up appeared, it is just appear on that particular scrolled page, not refreshing the page.. any idea? thanks :)

  5. Tom Messerschmidt Avatar
    Tom Messerschmidt

    Hey, really nice tutorial. This is very useful! :D

  6. Hi pageold,

    You can use animation with keyframe. so that you can control whatever you want.

  7. Hi! Great tutorial, but my specific situation requires even more lean approach – I can use inline CSS only! So, no pseudo-elements whatsoever. Is there a way to do this or “Popup windows without JavaScript, mark II” without any pseudo-elements? Thanks!

  8. Enrique Arróniz Avatar
    Enrique Arróniz

    Very nice article. ¿Could you please explain me how to launch the modal without a button link?

    1. Navigate to the target. For example, if your page is “demo.html” and your popup trigger is , then navigating to “demo.html#target” would trigger the popup.

    2. Enrique Arróniz Avatar
      Enrique Arróniz

      Thank you very much! I will test it and tell you how it went.

  9. Great approach, its always good to use as less JS as possible. I’ll implement this in my latest project, one thing i would suggest is using dislpay: none->block instead of visibility: hidden->visible as i consider this better practice for hiding stuff completely :)

    1. That may be, but you can’t transition the display property. You can transition visibility and opacity. :)

  10. Ah ok, thanks for the explanation, makes total sense if you want to animate. Another Improvement would be setting the overlay position:fixed and assign overflow:auto, so it really fits the whole viewport instead of sometimes cut of in the middle of the page, if the Popup is longer than the page, eg on Smartphones.

  11. coleen Avatar

    Great article! Works like a charm!

  12. This is quite brilliant! Thank you.

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.