UPDATE: The information about links in Pens here is outdated. We aren’t doing anything special to target="_blank" links anymore, they should just work. Note that if you don’t use target="_blank" on a link, and link to something not on CodePen, the link will simply fail due to our sandboxing and cross-origin security.

Oh, the humble link:

<a href="http://css-tricks.com">a link</a>

Until just recently, links inside previews (like when you’re working in the Editor) simply open within the preview area. That’s normal, but sometimes you want to link to something in a new tab/window, in which case you’d do:

<a href="http://css-tricks.com" target="_blank">a link</a>

Unfortunately that would not work in CodePen. We use iframe sandboxing which is a fantastic security measure for iframes, but it blocks that behavior. We even went so far as to strip that attribute from links so at least they would open within the iframe and you won’t think something was broken.

Now we have a new system! If you create a link with target="_blank" (or _top or _parent), we will attempt to open that URL for the user clicking that link in a new window.

We do that by sending a message via postMessage back up to the CodePen application and having it open the link. Unfortunately that means it’s not a real click event anymore and we can’t open the link in a new tab. The link will open in a new window. But at least it works!


You might get a popup blocking warning like this:


Which of course you’ll have to allow if you want the link to work.

Don’t like this behavior?

For one thing, you don’t have to use target="_blank" on links. We just thought we’d try to replicate real-life behavior as best as possible. We don’t take adding in special code to Pens lightly, so don’t worry about us getting crazily intrusive.

If you want to continue to use target="_blank" but remove our behavior, you can remove our named event handler like so:

var links = document.querySelectorAll('a');

for (var i = 0; i < links.length; i++) {
  links[i].removeEventListener('click', __linkClick);

If you wanted to also stop your links from doin’ stuff, you could preventDefault on them. All together:

var links = document.querySelectorAll('a');

for (var i = 0; i < links.length; i++) {

  links[i].removeEventListener('click', __linkClick);
  links[i].addEventListener('click', function(e) {

Also to know…

This doesn’t work on anonymous Pens. Only Pens created by real users. However an anonymous user looking at a Pen created by a real user gets the new link behavior.

Also, this relies on stuff like querySelectorAll, addEventListener, and postMessage, so we’re looking at IE 8+.

We’ll leave when to use the target attribute up to you, as everybody and their mother has an opinion on that.

Other Bonuses

Since our Boomerang update, the preview iframes have real src’s now. Meaning like:

<iframe src="http://real-link.com"></iframe>

That src can change just like the outside browser window URL can change. You don’t see anything change, but it basically behaves as if it does. So for instance if you click a link with a href of #home, the active URL in that preview iframe will be http://real-link.com#home

Point is, stuff like CSS :target works now. And if you click a hash link in Firefox, it doesn’t freak out and turn the whole preview white like it used to.