Why does target="_blank" have an underscore in front? (2024)

2025-02-2114:07278190kyrylo.org

Ever wondered why you need the underscore in target="_blank" to open a link in a new tab?

Ever wondered why you need the underscore in target="_blank" to open a link in a new tab?

Before HTML5, developers used <frameset> for SPA-like functionality, dividing the window into multiple frames, each with its own unique ID. For example, the left frame might be id="sidebar", and the right frame could be id="content".

When clicking a link, the browser needed to know which frame to load the content into. That’s where the target attribute came in. Clicking a link in the sidebar, for example, would load the content in the content frame:

<a href="/pricing" target="content"></a>

Now, if you had a frame named “blank” and used <a href="/" target="blank">, the content would load in that frame. But if no such frame existed, the browser would create a new tab and assign it the “blank” name. Clicking the same link again wouldn’t open another tab.

So why the underscore in target="_blank"?

It’s simple - developers needed a way to explicitly tell the browser to open the link in a new tab, free of frame semantics. The underscore signifies a special value rather than a frame name.

P.S. Don’t use <frameset>. It’s deprecated in HTML5.


Read the original article

Comments

  • By paulirish 2025-02-2416:572 reply

    I went digging in W3C archives to find relevant discussions. There are 4 reserved target names: _blank, _parent, _self, _top.

    - 1995 Sept https://web.archive.org/web/19990202141025/http://home.mcom.... Netscape Navigator 2.0a2 release notes including rollout of TARGET.

    - 1995 Sept https://lists.w3.org/Archives/Public/www-html/1995Sep/0034.h... First definition of them; spec text provided by "the Netscape Navigator marketing guy".

    - 1997 Jan https://www.w3.org/TR/2018/SPSD-html32-20180315/ HTML 3.2 published without frame target names specced.

    - 1997 Aug https://lists.w3.org/Archives/Public/www-html/1997Aug/0010.h... Roles of these target names clarified

    - 1997 Dec https://www.w3.org/TR/html401/types.html#h-6.16 HTML 4.0 published with target names.

    I can't find any discussion about the choice of character. My guess is that discussion was internal to Netscape as they shipped _then_ specced link target names.

    • By thesuitonym 2025-02-2421:392 reply

      There probably was no discussion about it. Back then you didn't have tens of managers looking to add their input to a project, so if you came up with something, you could just demo it, and unless someone had a very specific reason to reject it, nobody would.

      I'm not saying this is the answer, but it very well could be that whoever wrote the function that handles this decided on an underscore and nobody ever even questioned it.

      • By janalsncm 2025-02-2423:471 reply

        There was a recent post about asking for “no”, in other words defaulting to yes unless there’s an objection before a deadline. I like that model.

        • By smallnix 2025-02-2423:59

          I am making extensive use of deadlined passive approval for decision I consider non-contentious. For everything else I set up meetings. I don't believe in async review of contentious decisions.

      • By dowager_dan99 2025-02-2423:411 reply

        and really this should be the path: define a new convention, then standardized after - if it's needed (spoiler: probably not going to need it). This is definitely not perfect; it's incredibly painful to retrofit standards, but I'm not convinced it's less work than creating a bunch of standards no one needs.

        • By IgorPartola 2025-02-251:201 reply

          Please don’t. In theory this works for some things. But when you have multiple implementations of the browser doing different things given the same code it is a nightmare. A solid well defined spec is necessary in that case.

          • By braiamp 2025-02-252:38

            In which case, the need for the spec should be obvious from the onset. Nobody though that html would be used the way it was used today. But we now know the same things as they knew back then, meaning that we do not know nothing, we don't know what will be used and need interoperability. Also, specs means nothing if each implementation can and will do whatever they want (ie. Chrome vs Firefox vs Edge)

    • By brightball 2025-02-250:10

      Years ago I discovered that Yahoo Fantasy Football would open links to each player profile in its own window/tab, even if I clicked on the same player over and over. I dug in and found that they were using target="playername-idnum".

      I've used it everywhere ever since when most people would just use _blank. If you're like me and ever go down and article, clicking all of the links to open in new tabs to look at later then you're welcome...I saved you a few wasted tabs when you clicked on the same link more than once.

  • By ldjb 2025-02-2410:355 reply

    I was expecting this post to explain why it's an underscore specifically, as opposed to a dollar sign, an asterisk, a caret, a tilde or some other special character.

    I can only assume it's a holdover of languages like C where the standard library has some reserved names that start with an underscore.

    https://devblogs.microsoft.com/oldnewthing/20230109-00/?p=10...

    • By lelandfe 2025-02-2415:194 reply

      As another borrowed convention, JS developers of yore (and likely some today still) used an _ prefix to denote “private” function/methods. Quotes as it’s just a convention - today JS supports # for actual private members in class syntax.

      • By zeroq 2025-02-2415:582 reply

        This is a direct descendant of ActionScript. It introduced the convention of Instance._getter and Instance.__private.

        • By magicalist 2025-02-2418:403 reply

          That looks like ActionScript 2, so the javascript convention was actually well in place by then. I can't speak confidently about the late 90s, but I wouldn't be surprised if it predated Actionscript 1 as well.

          But doesn't it all trace back to C conventions anyways?

          • By zeroq 2025-02-2515:021 reply

            Not at all.

            AS1 was plain ES3.

            movieclip._x or movieclip._alpha (as in position and alpha blending) were accessed by properties with underscore to denote that you were using accessors (getters/setters).

            Internally properties like Object.prototype.__proto__ had two underscores to denote they were private.

            In AS2 you had:

              class Foo extends Bar implements Xyz {
                private foo
                public function set x (value : Number) : void { ... }
                public function get x () : Number { }
            
            AS2 was based on long forgotten ES4 specification [0]. Under the hood it was still, what we would call today, transpiled to ES3 bytecode, as it run basically on the same VM as AS1.

            It's crazy to think it took us 10 years to reinvent the wheel with TypeScript.

            AS3 was a complete rework, more akin to Java.

            [0] https://evertpot.com/ecmascript-4-the-missing-version/

            • By cxr 2025-02-2614:21

              None of what you say here that is true moves the needle on what you say that isn't true.

              Programmers using underscore to denote identifiers for internal use was well-established and in use long before ActionScript even appeared. To claim that it's a "direct descendant" of ActionScript is arbitrary, anachronistic, and odd.

        • By DidYaWipe 2025-02-2417:11

          What about Lingo?

      • By xd1936 2025-02-2420:411 reply

        Another weird case: In Google's server-side JS environment Apps Script, function names that end with _ are treated as private functions that cannot be called directly by the user or enumerated.

        1. https://developers.google.com/apps-script/guides/html/commun...

        • By BurningFrog 2025-02-2423:561 reply

          In the Python world I was in, trailing underscores is used to work around the ban on reserved words. The language grabs some of the best names for itself!

          So a variable that really ought to be named `class` you name `class_`.

      • By phist_mcgee 2025-02-2420:451 reply

        I use underscore to prevent shadowing of variables names. Not sure where I picked up that habit though.

        • By lelandfe 2025-02-2421:141 reply

          I've seen that before.

          A related conventional use of underscores in JS variable names is when "discarding" values in positional settings, like destructuring arrays.

          E.g. `const [_, a, b] = triple`

          In general, underscores in JS seem to be used to help call out what to ignore or what is less important.

          • By fennecbutt 2025-02-2421:302 reply

            You've been able to `const [, a, b] = tuple;` for a wee while now FYI.

            But yeah for every other time most linters will accept _ as "ignore this".

            • By phist_mcgee 2025-02-2421:41

              I had no idea that was a thing!

              Thanks for teaching me something today.

            • By lelandfe 2025-02-2421:46

              Oh yeah, I always forget about that.

    • By layer8 2025-02-2415:272 reply

      I wouldn’t say it’s a “holdover”, it continues to be a common convention for marking internal or reserved use.

      • By paradox460 2025-02-2419:00

        Some modern languages even turn _ flagged variables/parameters into black holes

      • By anoldperson 2025-02-2421:40

        I do it every day, so I see it from your perspective.

        I'm willing to bet there are kids who do not though. Given how many crazy colours my IDE shows everything in, I could definitely believe there are people that go, 'Why bother, aren't those private members blue anyway?', or some such similar train of thought.

        Of course if your IDE is little more than notepad, then such things are still important. For me, that's the Arduino IDE. I have to admit I really like writing micro controller code in it, it's a bit like writing code 30 years ago (both the good and bad parts).

    • By kazinator 2025-02-2418:571 reply

      Making it a dollar sign would cause countless bugs for people who generate HTML using templating languages whose variables are indicated by dollar sign. From time to time, someone would add target="$blank" to a templates, forgetting that the $ must be escaped to be literal.

      They might have to resort to predefining a reserved variable called blank, whose value is "$blank". :)

      Similar reasoning applies to most other special characters.

      Given how HTML gets generated by preprocessors which use special characters in this manner or that, its best not to come up with new schemes within HTML itself involving special characters.

      Carving out a reserved space within an existing namespace is safe.

      • By robocat 2025-02-2422:111 reply

        Your reason is unlikely to be a cause.

        The _ comes from the W3C in 1995 well before JavaScript was commonly used for templating HTML.

        Scripting has used $ for variables for a long time: I think the most relevant history line for $variable is PHP comes from Perl comes from shell scripts. I also remember finding $ ugly on Vax.

        There were a huge variety of templating syntaxes for server side and HTML generation was virtually all server side in the 1900s.

        Server side languages were very rarely JavaScript before Node in 2009.

        JavaScript wasn't used much for HTML generation before Ajax. There were soon after many many client side templating syntaxes.

        I'm guessing only Brendan Eich could say why $ was accepted for JavaScript variable names.

        Timelines are hard because the foundations were compressed within a decade: JavaScript 1995, PHP 1996, DHTML 1997, Ajax early 2000s, jQuery 2006.

        Syntaxes tend to be extremely path dependent, and every developer cribs from everything they use.

        • By kazinator 2025-02-250:13

          Shell script here documents can generate HTML:

            cat <<!
            <div>
              ...
              <a href="$url" target="_blank" ...
            ...
            !
          
          A form of CGI existed as far back as 1993 on the NCSA web server.

  • By bilekas 2025-02-2411:428 reply

    So basically It’s an “_blank” because it is.. Author’s description is, “because if it wasn’t _blank.. it wouldn’t open a new tab.” Reminds me of some university professors I had.

    • By neom 2025-02-2414:592 reply

      When I built "webapps" in the 90s, they were a collection of frames. You could just do everything as one page, but there were some neat things you could do by dividing the page up into frames + internet connections were not very good so if you had something you needed to update a lot, it was easier to make it it's own .html and server it in an iframe.

      Because you could "NameAFrameAnyThingYouWanTED" they made some magic targets, _blank window to open a blank window (we have tabs, then we did not), _self to open in the same frame or window, _parent to open in the parent frame, _top to break out of frames entirely (this is how you would bypass the ad some free .coms would inject into your site)

      When I read the html spec in the 90s all it says was you can name a frame anything except don't use _ as _ is reserved for special frame types.

      • By sokols 2025-02-2415:171 reply

        This is exactly what I understood from the article. Your explanation didn't add anything extra.

        • By lazide 2025-02-2415:251 reply

          I actually used the 1.0 version of Netscape Navigator, and did some web development on it back in the day.

          Originally, _blank, _new, etc. weren’t special. A target ref to a name which wasn’t used would open a new window. If it was already used, it would take you to that open window.

          People started using _whatever because just ‘blank’ would almost always cause a collision. Eventually it got standardized that it would always open a new blank window.

          • By tredre3 2025-02-2416:32

            If what you say is accurate then it should have been in the article. Because, as is, GP is correct that it doesn't answer the question!

      • By pests 2025-02-253:33

        >(this is how you would bypass the ad some free .coms would inject into your site)

        In anglefire and maybe geocities we would serve the document with a .txt extension and it would also skip the ads but browsers, with their liberal acceptance policy, would render normally.

    • By layer8 2025-02-2416:121 reply

      Not quite. Any name would open a new window unless a frame with that name already exists. This includes the case of the name “blank”. In other words, the first time clicking on a link targeting a name would open a new frame (window) with that name, but the second time would load the content into the existing frame, replacing the previous content. In that scheme, there is no way to open an additional new frame each time. The reserved name “_blank” was then defined to have that semantics.

      • By bilekas 2025-02-2416:161 reply

        So again as I understand, it's simply because a standard was decided ?

        > The (reserved) name “_blank” was then defined to have that semantic.

        I guess I was hoping for some interesting quirk with older browsers or something.

        • By layer8 2025-02-2416:19

          It was to avoid the situation of someone naming a frame “blank” without being aware of it having special semantics, or (I’m not completely clear on the history) avoiding breaking compatibility with existing use. That’s much more unlikely with a name like “_blank”. It’s common practice to separate out names with special semantics from general-use names in a syntactic way like that. There’s also “_self”, “_parent”, and “_top”. It’s an extensible scheme where HTML can add further names with special semantics in that reserved name space.

          I now agree that the article doesn’t make a particularly good job in explaining all of this.

    • By layer8 2025-02-2415:321 reply

      Maybe the article didn’t make it clear enough, but having special targets begin with an underscore has the purpose of avoiding name collisions with normal targets.

      The primary thing the article does is explain that there are normal targets in the first place, which is probably the main aspect people might otherwise be missing.

      • By mixmastamyk 2025-02-2415:58

        Yes, whenever you see such a convention it’s about expanding the namespace. i.e. avoiding the main namespace.

    • By mikeyinternews 2025-02-2416:08

      It would open in a new tab (or specifically, window) if there was no object named "blank" for it to target. The problem with that is subsequent links with the target "blank" would use this same new window. Links with the target "_blank" would each open in individual windows

    • By userbinator 2025-02-2414:55

      The general trend in search engine results seems to be optimising towards these superficial and unsatisfying answers too... and part of it is no doubt due to sites like this.

    • By reverendsteveii 2025-02-2418:01

      It is what it is because it's that. You can tell, you just have to look at how it is. If it's like that, then it is what it is. If it isn't what it is it would be something that it isn't but still be what it is. Luckily for us it's what it is, not what it isn't.

    • By systems_glitch 2025-02-2411:58

      "I dunno...is magic" (engineering Calculus II GTA, Virginia Tech, 2006)

    • By rendaw 2025-02-2414:341 reply

      And a lot of SO answers.

      • By Aachen 2025-02-2414:442 reply

        I was more thinking of javadoc, or other languages where people can automatically generate documentation from the code comments they wrote and 97 out of 100 comments is the function name written as a sentence ("reserveItem(): reserves an item")

        For anyone who writes these, please just leave it blank and revisit it later

        • By mdaniel 2025-02-2415:43

          My experience with this is it is almost always caused by some heavy-handed linter rule, e.g. "fail CI if methods don't have javadoc". Most of those "dumb" linters also almost never catch when a parameter has been renamed but its "@param" was left intact. Drives me crazy.

          see also https://en.wikipedia.org/wiki/Goodhart%27s_law

        • By russfink 2025-02-2414:52

          I second your motion.

HackerNews