Top
Best
New

Posted by todsacerdoti 12/29/2025

You can make up HTML tags(maurycyz.com)
584 points | 190 comments
dannye 12/29/2025|
<tag-name> are NOT unrecognized tags!

I blogged about this: https://dashed-html.github.io

◄ <tagname> = always an HTMLUnknownElement until the WHATWG adds it as new Element.

◄ <tag-name> = (No JS!) UNDEFINED Custom Element, valid HTMLElement, great for layout and styling

◄ Upgraded with the JavaScript Custom Elements API it becomes a DEFINED Custom Element

---

► This is standard behaviour in all browsers. Chrome (2016) Safari (2017) FireFox (2018) Edge (2020)

► The W3C HTML Validator accepts all <tag-name> Custom Elements with a dash as HTMLElement. It does not accept <tagname> (no dash), those are HTMLUnknownElement

► The UA - UserAgent StyleSheet (Browsers default stylesheet) defines CSS [hidden] { display:none }. But Custom Elements do not inherit the default stylesheet; so you have to add that behaviour yourself in your stylesheet.

► <DIV> is display:block only in the UA StyleSheet You have to set the display property on these Custom Elements yourself (You will forget this 20 times, then you never make the mistake again)

► The CSS :defined pseudo selector targets standard HTML tags and JavaScript defined Custom Elements

► Thus the CSS :not(:defined) pseudo selector targets the UNDEFINED Custom Elements; they are still valid HTMLElement, CSS applies like any element

► DSD - Declarative ShadowDOM: <template shadowrootmode="open"> creates the same undefined Custom Elements with a shadowDOM

Sesse__ 12/29/2025||
> The UA - UserAgent StyleSheet (Browsers default stylesheet) defines CSS [hidden] { display:none }

I can only speak for Chromium, but this isn't about the UA stylesheet; everything in the UA stylesheet applies to custom elements just the same as the more standard HTML elements (e.g. the rule for [popover] will apply just fine to custom elements AFAIK), and there is no [hidden] rule in the UA stylesheet. You're probably mixing it up with the fact that hidden is a HTML presentation attribute, similar to how you can write <div align="right"> and it will become its own little property value set that gets applied to the element. That is indeed only the case for HTMLElements. (The difference matters for priority in the cascade; in particular, presentation attribute style has zero specificity.)

mgr86 12/29/2025|||
I'm a bit miffed about the dash. I wish it was a colon. Then well established XML could be simply name-spaced in, and then either styled with css and enhanced with JS. I suspect it wouldn't be that difficult to write something for nginx or apahce that simply converted the colon to a hyphen. Oh well, it cannot be 1999 forever.
jdthedisciple 12/29/2025||
Why is this not default practice?
icedrift 12/29/2025||
Mainly because it isn't semantic and breaks accessibility features. If you find yourself writing layouts like this you're probably ignoring a bunch of useful stuff like <aside> <article> <menu> etc. Unless you manually configure it yourself, screen readers won't know what's important to read, tabindex won't know where to jump around, and form fields won't know what values to offer.
zahlman 12/29/2025||
> isn't semantic

It's certainly better than calling everything a div.

> breaks accessibility features

I don't know if I'd call it breakage to just... not use them where they should be used. Of course if a real tag exists that adequately matches the author's intent, that should be preferred over a made-up one.

DrammBA 12/29/2025|||
> I don't know if I'd call it breakage to just... not use them where they should be used.

Accessibility only has 2 states: "Working" and "Broken", there's no third "I didn't bother".

kevincox 12/29/2025||||
> It's certainly better than calling everything a div.

It's not. For semantic purposes <my-element> is the same as <div class=my-element>. So on the surface they are equivalent.

But if you are in the habit of using custom elements then you will likely continue to use them even when a more useful element is available so <my-aside> rather than <aside class=my-aside> so in practice it is probably worse even if theoretically identical.

Basically divs with classes provide no semantic information but create a good pattern for using semantic elements when they fit. Using custom elements provides no semantic information and makes using semantic elements look different and unusual.

jeremyjh 12/29/2025|||
> But if you are in the habit of using custom elements then you will likely continue to use them even when a more useful element is available

This article is written for web developers. I’m not sure who you think you are addressing with this comment.

In any case - the argument is a weak one. To the extent people make the mistake you allege they can make it with classed div and span tags as well and I’ve seen this in practice.

mr_toad 12/30/2025||||
> But if you are in the habit of using custom elements then you will likely continue to use them even when a more useful element is available

You could say the same about divs. I’ve seen pages where everything is a div. No paragraphs, no headings, no tables, no lists, just divs.

novemp 12/30/2025|||
I've seen <span class=italics>, and it made me want to break things.
kevincox 12/30/2025|||
That is a strawman. I never said everyone who uses classes perfectly uses semantic elements.

My point is that if you are using <div class=my-element> you don't have to change your .my-element CSS selector or JS selection code to improve your code to <p class=my-element>. If you are using <my-element> it is much more work to change your selectors and now you have two ways of doing things depending on if you are using a native semantic element or a div (either a tag selector or class selector). You have made your styling code depend on your element choice which makes it harder to change.

ragall 12/29/2025|||
> For semantic purposes

But semantic purposes are not all possible purposes.

nailer 12/29/2025|||
> > If you find yourself writing layouts like this you're probably ignoring a bunch of useful stuff like <aside> <article> <menu> etc.

> It's certainly better than calling everything a div.

Yes but it's worse than <aside> <article> <menu> etc. as the comment you are replying to mentions.

chrismorgan 12/29/2025||

  <div class=article>
  <div class=article-header>
  <div class=article-quote>
  <div class=quote-body>
  ... a bunch more HTML ...
  </div>
  </div>
  </div>
  </div>
Just one quibble over this specific example (not the broader concept, which is sound): it probably didn’t have to be div soup to begin with. Something like this may have been more reasonable:

  <article>
  <header>
  <blockquote>
  <p class=quote-body>
  ... a bunch more HTML ...
  </p>
  </blockquote>
  </header>
  </article>
fpoling 12/29/2025||
This example also shows a weakness of custom tags compared with using the class attribute. An element can have only single name but may have several classes. And as classes are unordered set, one cannot in general emulate that with several elements as the nesting introduces an order absent in the class list.
handsclean 12/29/2025|||
I’d argue it’s a strength. You still have classes and custom attributes to reach for when you want an (effectively) unordered set, the difference is just that you define some boundary that’s exclusive. This reflects reality. Some helper classes work together by just slapping them together, but component-like classes, like a toggle and a hero image, don’t. If you do want to combine them, you need to think about how, potentially rearchitect, and implement it whether you’re using classes or tag names.
dleeftink 12/29/2025||||
Good use case for @container, @scope and :has(), where you forgo class definitions and use --custom-properties on the parent scope/container which are inherited downwards based on the existence of a scoped DOM pattern/container query, or 'upwards' by using a :has(child-selector) on the parent.

Although be sure to avoid too many :has(:nth-child(n of complex selector)) in case of frequent DOM updates.

MarcelOlsz 12/29/2025||
[flagged]
danlitt 12/29/2025||||
Honestly it depends what you're doing. A tag name is only correct when it unambiguously specifies the content. As in, a header is just a header - there's no "dual nature" that we have to support by allowing multiple tag names. This means the ontology you're representing has to be "linear" - you can have more specific and less specific tags, but never a "fork" where you could really choose either more-specific tag in order to emphasise a different "part" of the tag. Classes should always be for secondary properties, which are not the main "essence" of the content.

All I say above is a just a particular way of thinking about document markup, of course. If you don't agree with it, then tags are probably the wrong way to express what you're thinking of.

tomcam 12/29/2025||||
Not trying to be rude but to me that is the essence of composition which feels perfect to me
nonethewiser 12/29/2025||
Hot take: div soup isnt bad because html isn't purely structural. It's a natural consequence of a poor design decision. Div soup is a consequence of the design decision to couple html elements to styling, state management, etc.

It made sense in 1996. It does not make sense now.

verisimilidude 12/29/2025||
I've been doing this for about three or four years. Clever idea, tricky in practice. I don't think I'd recommend this approach broadly. But it works for me.

It's definitely possible to take it too far. When most tags in your HTML are custom elements, it creates new readability problems. You can't immediately guess what's inline, what's block, etc. And it's just a lot of overhead for new people to learn.

I've arrived at a more balanced approach. It goes something like this:

If there's a native tag, like <header> or <article>, always use that first.

If it's a component-like thing, like an <x-card> or <x-hero>, then go ahead and use the custom tag. Even if it's CSS only, without JS.

If the component-like thing has sub-components, declare the pieces using slot attributes. There will be a great temptation to use additional custom tags for this, like <x-hero-blurb> inside <x-hero>. In my experience, a <div slot="hero-blurb"> is a lot more readable. The nice thing about this pattern is that you can put slot attributes on any tag, custom or otherwise. And yes, I abuse the slot attribute even when I'm only using CSS, without JS.

Why bother with all of this? I like to limit my classes to alteration, customization. When I see a <div slot="card-content" class="extra-padding-for-xyz">, it's easy to see where it belongs and what makes it unique.

Some of you will likely barf. I accept it. But this has worked well for me.

keepamovin 12/29/2025||
I'm highly interested in approaches that utilize web grain in a balanced practical way. Do you have a framework/toolbelt or example sites to share? Would love to see.

If you're interested in my approach to custom elements I created: https://github.com/crisdosaygo/good.html

It utlizes custom elements, has autohooks for granular DOM updates, uses native JS template literal syntax for interpolation, imposes ordered component structure:

  .
  ├── package.json
  └── src
      ├── app.js
      └── components
          ├── app-content
          │   ├── markup.html
          │   ├── script.js
          │   └── styles.css
          └── app-header
              ├── markup.html
              ├── script.js
              └── styles.css

It even has a bit of a "comment node" hack to let you write "self-closing custom elements"

  <!app-header />
Good.HTML is the ride-or-die framework for BrowserBox.
verisimilidude 12/29/2025|||
Thanks for sharing, that’s an interesting framework. The self-closing tags are very nice.

Unfortunately, I don’t have anything public to show at the moment. Maybe I’ll blog about the approach some day.

keepamovin 12/30/2025||
Well, I hope to see it.
pegasus 12/29/2025|||
Why is this being downvoted? I'm baffled. The comment is coherent and relevant to the discussion at hand.
mikae1 12/29/2025|||
> And yes, I abuse the slot attribute even when I'm only using CSS, without JS.

In CSS, how do you target <div slot="hero-blurb"> based on the "hero-blurb" slot?

div[slot="hero-blurb"]?

verisimilidude 12/29/2025||
Yes, though often I’ll omit the tag, and just target [slot=“hero-blurb”]. Depends on the situation.
crabmusket 12/29/2025||
That reminds me of BEM, where slow= is like the "element" within a parent "block".
ok123456 12/29/2025||
By default, they will behave like spans.

You can customize it using the Custom Element API: https://developer.mozilla.org/en-US/docs/Web/API/Web_compone...

lofties 12/29/2025||
I used custom elements extensively in 2014 when support was not as widespread. I think it's a beautiful, elegant solution and I'm still a little bit bitter that React became as big as it was. Now everything "has" to be a SPA because developers want to use React, whereas most users would actually be better served with good 'ol HTML with some custom elements where needed.
toastal 12/29/2025|||
> Now everything "has" to be a SPA because developers want to use React

Have you followed anything in the last 5 years? Outside of bootcamp students, this has been on the decline for a while… in some cases overcorrecting for where a SPA might make more sense.

teaearlgraycold 12/29/2025||||
I’ve been getting into SSR with JSX as a template engine using kita. You still get full typescript analysis and composability. It beats any other SSR web templating system I’ve used.

I agree the need for everything to be a react app by default has gotten out of control. But I think if you’re a startup with unknown future needs it’s hard to ignore the flexibility and power of something like react. If you know you’re just making a CRUD app and good old fashioned form POSTs will do then it’s beautiful to have that speed and the lightweight pages.

skeptic_ai 12/29/2025||
You do the crud app and then they want: just make this to edit inline. You do some Ajax api Call with a tiny js. Then you need more and more. Then you have a mess and you’d be better with react. I still can’t find a project id be better of without react. When I tried without it bite me very quickly.
teaearlgraycold 12/29/2025||
Nothing wrong with JS. It all depends on whether you have a strong sense of the bounds of the project.
halfmatthalfcat 12/29/2025||||
SPAs are early 2010s homie. SSR has been dominant for the past 5 years.
troupo 12/29/2025|||
> I think it's a beautiful, elegant solution

Very confused by statements like these.

They are extremely verbose.

They are too high level, preventing many low-level optimizations.

They are too low-level, preventing you from using/implementing them without going into the details of how they actually work.

They break many platform assumptions and conventions, creating no end of problems both for end users and implementers, and needing dozens of new specifications to fix glaring holes that exist only because web components exist. All of those specs? A heavy dousing of Javascript of course.

Even the people who push them heavily cannot agree on what they are good is and what the goal of them is

WickyNilliams 12/29/2025|||
What makes custom elements good is inrerop. I can use them in react, Vue, angular, svelte, solid, or just plain ol' server rendered html. I can switch out the internals entirely for a WC lib, or not, with nobody knowing or caring.

This is a unique advantage to WCs. And it's such a compelling advantage that it makes almost all the downsides tolerable. At least if you are in a position where your component might be used in many places. Design Systems are a good example. The consumer can be any app, built on any technology.

And there are plenty of downsides. But they are mostly felt by the author, not the consumer. Similar to how TS libs can be very complex to author because of type level gymnastics, but when done right are easy to consume.

(I do not push them heavily, but I can appreciate strengths and weaknesses of all tools)

troupo 12/29/2025|||
> At least if you are in a position where your component might be used in many places.

I think someone once called them leaf components, and on this I agree.

WickyNilliams 12/29/2025||
They don't need to be leaf components to still have this strength. I've worked with design systems which have a <my-layout> component near the root which defines sidebar, header etc slots. This still works nicely with react, Vue etc

But I agree they tend to be better suited as "leafier" components

troupo 12/29/2025||
> I've worked with design systems which have a <my-layout> component near the root which defines sidebar, header etc slots.

Funnily enough this is exactly what original proposal of web components was against :)

WickyNilliams 12/29/2025||
Honestly I couldn't care less what the original proposal said! Things evolve. Utility is found in unforeseen places. That's the nature of ~everything. Personally I'm not a fan of that kind of component but not aligning with some original, preordained vision is a minor nit
singpolyma3 12/29/2025|||
You know what else can be used in all these contexts? Defined HTML elements
WickyNilliams 12/30/2025||
Not even sure what argument you're making here. A web component bundles one or more of: markup, styles, functionality. You can't do that with just html such that it's easily consumable in all the ways I mentioned.
publicdebates 12/29/2025|||
As far as I can tell, the whole web components umbrella came into being because React/Vue got really popular, and the spec/browser people said hey let's bring the core common denominator of those into native HTML/JS, as if it would bring us closer to having native Vue/React. Which of course never happened, partly because HTML is fundamentally incapable of having anything but string attribute values, and partly because reactive DOM is basically a hard problem that can't or maybe shouldn't be solved natively.
troupo 12/29/2025||
> As far as I can tell, the whole web components umbrella came into being because React/Vue got really popular, and the spec/browser people said hey let's bring the core common denominator

First web components proposal is from 2011. First specs are from 2011-2013.

React was introduced in 2013 and didn't gain much traction until at least a year later.

Vuejs was publicly announced in 2014.

publicdebates 12/29/2025||
Right, and that proposal was withdrawn, and a new one, the one we have now, was proposed based on lessons learned from (or inspired by?) React/Vue. Maybe there was a common ancestor or general consensus about the techniques floating around in the community before proposal #1, but it was clearly inferior and flawed, and #2 was the one I'm talking about.
troupo 12/29/2025||
> That proposal was withdrawn

"That proposal" was a talk by Alex Russel in 2011: https://web.archive.org/web/20121119184816/https://fronteers...

Web Components are not a single proposal. Their core originally is three specs:

- Custom Elements

- Shadow DOM

- HTML Templates

Custom Elements v0 was implemented by Google, but the API changed (especially with ES6 classes making their way into all major browsers), and now everyone's on Custom Elements v1. There are very little fundamental changes between the two beyond that.

Shadow DOM is there, is an endless source of bizarre problems that literally no one has, and in the end will need ~30 different specs and changes to the browser to fix those problems (for a sample see https://w3c.github.io/webcomponents-cg/2022.html)

HTML Templates were only implemented in Firefox, and were removed in favor of JavaScript-only HTML Modules which were eventually scrapped in favor of on-off additions to JavaScript imports (see e.g. "CSS Module scripts" https://web.dev/articles/css-module-scripts)

> was proposed based on lessons learned from (or inspired by?) React/Vue.

Lol. The world wishes it were so. There rarely was such an insular group of people developing major web standards as those developing web components. They were hostile to any outside input or influence and listened to no voices, and looked at no implementations but their own.

zikani_03 12/29/2025||
I would rather use semantic elements for the examples like the one in the article and use web components/custom elements where appropriate.

Web Components are underrated for sure. I had a need for a custom element[0] and it was not difficult to implement.

[0]: https://github.com/zikani03/hypalink

aaviator42 12/29/2025||
I used this to implement <yes-script>, the opposite of <noscript>, to be able to designate sections of a page to be hidden if JS was disabled. You can of course do the same thing with classes, but custom tags are fun.

https://github.com/aaviator42/yes-script

Joeri 12/29/2025|
By the way, you can also do this pure CSS using the scripting media feature: https://developer.mozilla.org/en-US/docs/Web/CSS/Reference/A...
riknos314 12/29/2025|||
I didn't know this existed. Thanks for sharing! Very useful api
rebane2001 1/1/2026|||
I would suggest not using this as it's not compatible with NoScript
tombert 12/29/2025||
Many years ago, I decided to reinvent the `blink` tag, because the monsters who make browsers removed support for it.

I didn't know you could just make up tags, but I figured I'd give it a shot, and with a bit of jquery glue and playing with visibility settings, I was able to fix browsers and bring back the glorious blinking. I was surprised you could just do that; I would have assumed that the types of tags are final.

I thought about open sourcing it, but it was seriously like ten lines of code and I suspect that there are dozens of things that did the same thing I did.

01HNNWZ0MV43FF 12/29/2025||
I think you can do it fully in CSS these days! https://www.w3docs.com/tools/code-editor/13719

I modified `.blink` to `blink` so it will target the tag instead of the class and it seemed to work

tombert 12/29/2025||
This doesn't surprise me, I've seen a lot of cool stuff being done in CSS.

I've never been much of a frontend person, so gluing stuff together with JQuery was kind of my go-to until I was able to abandon the web.

chrismorgan 12/29/2025|||
> because the monsters who make browsers removed support for it

Most browsers never implemented it in the first place. Safari, Chrome, IE and Edge never had it. In terms of current browser names, it was only Firefox and Opera that ever had it, until 2013.

tombert 12/29/2025|||
Huh, I would have sworn that Internet Explorer had the blink tag at one point, but I think my parents had Netscape and then Mozilla pretty early so maybe that's what I'm confusing it with.

Regardless, I stand by my comment. Monsters! I want my browser to be obnoxious.

chrismorgan 12/29/2025|||
Never mind, Microsoft got you with <marquee>.

In theory, in 1996 Netscape and Microsoft agreed to kill <blink> and <marquee> <https://www.w3.org/People/Raggett/book4/ch02.html>, but although they were kept out of the spec, neither removed its implementation, and then IE dominated the browser market, and <marquee> became popular enough that the remaining parties were bullied into shipping it (Netscape in 2002, Presto in 2003, no idea about the KHTML/WebKit timeline), and so ultimately it was put into the HTML Standard.

Sesse__ 12/29/2025||
KHTML added <marquee> support in October 2003 (commit 7bcdd98aa in the Chromium repository).
1f60c 12/29/2025||
I have to say, that is some excellent sleuthing.
Tistron 12/29/2025|||
I think I remember reading articles about how to implement blink in IE using behaviors, some IE only thing that didn't take hold(?), Maybe this was around IE5.
vbezhenar 12/29/2025|||
IE was holding back the progress even before Chrome and Safari were a thing.
delaminator 12/29/2025||
> IE was holding back the progress

Oh those times. IE accepted <table><tr><td><tr></table> whereas Nestscape demanded <table><tr><td></td></tr></table> and would just not render anything else - just blank grey

Humans loved it, when they had to type all this by hand, because missing /td would not kill your page.

Permissiveness won out.

I also remember the day JavaScript hit the net.

and all those "chat rooms" that did <meta refresh> to look live suddenly had no defence against this

<script>document.write('http://twistys.com/folder/porn.jpg')</script>

or alert bombs

chrismorgan 12/29/2025||
Oh those times. <script>document.createElement("table").appendChild(document.createElement("table"))</script> would crash IE, and some similar stupidities could even cause a BSOD as late as Windows 98.

(I think that was one such incantation, but if it wasn’t quite that it was close.)

prox 12/29/2025|||
Talking about this, I am still sad Flash got removed from the web.

Nothing to replace it with to afaik.

DemocracyFTW2 12/29/2025|||
Good riddance. I once had the honor of being featured together with many other artist on an HP website. It was implemented in Flash though, meaning it existed as a smallish rectangle in the middle of a website; within that rectangle you could click through to browse the exhibition one artwork at a time. This entailed that your path through the Flash app was not connected to the browser's address bar and exhibits did not get a URL of their own. When you wanted to direct others to your piece the only way was by giving them a "Japanese visitor's address", as in "go to this well-known named point (the domain name), from there walk west and when you see a tall black building, turn right and take the third alley to your left, I'm living in the fifth house down that alley".

Plenty to replace it with to afaik.

pverheggen 12/29/2025||||
Well technically you can still use Flash via Ruffle, a WebAssembly-based emulator:

https://ruffle.rs/

Sites like Kongregate amd albinoblacksheep are using it to revive their old catalog.

drowntoge 12/29/2025||||
Although Flash really sucked as a technology, it did inspire a lot of visual artistry on the web. Half of the cool stuff you saw on StumbleUpon was made with Flash by people who weren't proficient with JS/CSS, which weren’t capable enough to achieve the same results anyway.
tombert 12/29/2025||||
I stand by that Flash was the most fun way to write software, especially games.

It was so satisfying being able to animate something, and immediately have the ability to create code out if it.

I have not found a platform to replace that, though GameMaker gives something of a facsimile.

robertoandred 12/29/2025||
Just keep using Flash? It's called Animate now. https://www.adobe.com/products/animate.html
tombert 12/29/2025||
I know, but since there’s not a great way to deploy and share stuff it’s not the same.

Yes I know about Ruffle, but I don’t really want to make a retro game that targets an emulator, I want something that’s consistently updated.

Also Animates pricing model is bullshit.

robertoandred 12/30/2025|||
You can export it as HTML/CSS/JS and upload it somewhere.
tombert 12/30/2025||
I haven’t tried that lately but when I tried that a few years ago it was terrible.
socalgal2 12/29/2025||||
Flash was fun but it was never built for being responsive and handling desktop and mobile in one app. Everything was basically fixed layout. Adding in that responsiveness would have probably killed the "easy" part.
alex_duf 12/29/2025|||
Really? Flash had been such an absolute pain for me for years, I was so happy when my bank stopped using it so I could uninstall the heck out of it.
JediBurrell 12/29/2025||
I for one am glad that blink is no longer a thing, it's certainly behavior that should require more thought than a simple html element can provide.
tombert 12/29/2025||
I just kind of feel like removing it makes the internet less fun. 90's internet was basically a playground for geeky people to make things purely for fun, with basically no ambitions of making any money; people would host their own terrible web pages. My first real introduction to "programming" (other than making a turtle walk around) was when I was nine years old and bought "Make Your Own Web Page : A Guide for Kids" from my school, and this was something a nine year old kid could do because the web was easy and fun to program for. There weren't a billion JavaScript frameworks, CSS was new (if it was even supported), everything was done with tags and I loved it.

Yeah, the sites would be ugly and kind of obnoxious, but there was, for want of a better word, a "purity" to it. It was decidedly uncynical; websites weren't being written to satisfy a corporation like they all are now. You had low-res tiling backgrounds, a shitty midi of the X-files theme playing on a bunch of sites, icons bragging about how the website was written in Notepad, and lots and lots of animated GIFs.

I feel like the removal of blink is just a symptom of the web becoming more boring. Instead of everyone making their own website and personalizing it, now there's like ten websites, and they all look like they were designed by a corporation to satisfy shareholders.

ssl-3 12/29/2025|||
Aye.

Before blogging was called "blogging," people just wrote what they wrote about whatever they wanted to, however they did that (vi? pico? notepad? netscape communicator's HTML editor? MS frontpage? sure!), uploaded it to their ISP under ~/public_html/index.html or similar [or hosted it on their own computer behind a dialup modem], and that was that.

Visibility was gained with web rings (the more specialized, the better -- usually), occasional keyword hits from the primitive search engines that were available, and (with only a little bit of luck necessary) inclusion on Yahoo's manually-curated index.

And that was good enough. There was no ad revenue to chase, nor any expectation that it'd ever be wildly popular. No custom domains, no Wordpress hosts, no money to spend and none expected in return. No CSS, no frames, no client-side busywork like JS or even imagemaps.

Just paragraphical text, a blinking header, blue links that turned purple once clicked, and the occasional image or table. Simple markup, rendered simply.

Finish it up a grainy low-res static gif of a cat (that your friend with a scanner helped make from a 4x6 photograph), some more links to other folks' own simple pages, a little bright green hit counter at the bottom that was included from some far-flung corner of the Internet, a Netscape Now button, and let it ride.

It was definitely a purer time.

meigwilym 12/29/2025|||
You have me in tears...
flexagoon 12/29/2025||
> <main-article>

> <article-header>

> <article-quote>

> <quote-body>

Not the best example, because in this case, you could just use real HTML tags instead

  <article>
  <header>
  <blockquote>
  <p>
aimor 12/29/2025|
If you use the predefined HTML tags you also get whatever default styling the browser decided is appropriate.
rasso 12/29/2025||
This is how you can set default styles for all your custom elements:

    :where(:not(:defined)) {
         display: block;
    }
adzm 12/29/2025|
Amazing, I was literally just trying to see if I could figure out how to do this. Thanks!
hecanjog 12/29/2025||
You sure can! They all have inline defaults like `<span>` so set some CSS baseline on them as needed, but this is like the best kept secret of HTML or something? Unknown tags will become `HTMLUnknownElement` and behave like a span.

Edit: the reason for avoiding this in the past was name-spacing. But the standard says you can use a hyphen and then you're OK, native elements won't ever use a `-`.

Edit 2: also it's great because it works fine with CSS selectors too. Write stuff like `<image-container>` in plain HTML docs and it's fine.

Edit 3: but also `<albums>` tags and etc which won't be adopted into the HTML standard soon work too if they don't conflict with element names, and the rare case that they might be adopted in the future as an element name can be resolved with a simple text search/replace.

Edit 4: This all really has little to do with javascript, but you can use `querySelector` and `querySelectorAll` with any of these made up names the same as any native name too.

It's very nice to write. I used and liked vue for a little while when it was needed(?) but modern HTML fills that gap.

ameliaquining 12/29/2025|
Nitpick: If a nonstandard element name contains a hyphen (and is otherwise a syntactically valid custom element name), the element's DOM object is an instance of HTMLElement, not HTMLUnknownElement.

Quoth the standard: "The use of HTMLElement instead of HTMLUnknownElement in the case of valid custom element names is done to ensure that any potential future upgrades only cause a linear transition of the element's prototype chain, from HTMLElement to a subclass, instead of a lateral one, from HTMLUnknownElement to an unrelated subclass."

firefoxd 12/29/2025|
In the olden days, internet explorer couldn't support html5 tags. I found a snippet of code from my 2010 library [0] that I used to use to remedy the problem. You see if you created the tags via JavaScript, IE would somehow recognize them. You could discard them right after. Here was my script:

    (function(d) {
        'abbr article aside audio bdi canvas data datalist details figcaption figure footer header hgroup mark meter nav output progress section summary time video'.replace(/\b\w+/g,function (a){
            d.createElement(a);});
    })(document);
It didn't take long before I realized I could just add any random tag, add it to my shim, and render it on any browser.

[0]: https://idiallo.com/blog/revisiting-my-old-javascript

tentacleuno 12/29/2025|
I'm sure that's how the popular html5shim used to work, too. I remember looking at the source out of curiosity.
More comments...