70 comments

[ 3.0 ms ] story [ 73.9 ms ] thread
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.

I probably wouldn't do this for a lot of reasons.

That being said, if you read through that post and were intrigued, you might also like custom web components: https://web.dev/articles/custom-elements-v1

It's a simple way to add more to your "made up" HTML tags. So you could have a tag called <my-code>, for example, that automatically has a copy button and syntax highlights the code.

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

https://lit.dev/

That's the premise behind Lit (using the custom elements api)! I've been using it to build out a project recently and it's quite good, simpler to reason about than the current state of React imo.

It started at google and now is part of OpenJS.

As someone who writes html only rarely (I'm more of a "backend" guy, and even use that term loosely.. most of my webdev experience dates back to the CGI days and often the html was spat out by Perl scripts) and usually in vim, I am pleased to know there is an in-built solution outside of me properly indenting or manually counting divs. Thanks for enlightening me.
> <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>
If you use the predefined HTML tags you also get whatever default styling the browser decided is appropriate.

  <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>
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.

Wow, this is great, unlocks lots of freedom. I was under the impression that this was not possible, maybe through web components or <slot>.

As a side note, I’ve been going through all the HTML elements slowly to learn the fundamentals, and it turns out that lots of elements are just a <div> or <span>, with different default styles and default ARIA things.

And a <div> is just a <span> with display block…

This and TFA both help me to realize HTML is pretty darn simple.

the comments here informing us they default to behaving like <span> instead of like <div> is the biggest disappointment of my day so far
If this works, then the point of having standards, is just for screen readers??
You can but you never ever should. Do not do this. Use the `class` attribute to provide extra context about the kind of data your tag represents, that is what it is for.
But there's no real reason to, and it just adds confusion around which elements are semantic -- bringing formatting, functionality, meaning to screen readers and search engines, etc. -- vs which are custom and therefore carry no semantic meaning.

If there's no native semantic tag that fits my purposes, I'd much rather stick to a div or span as appropriate, and identify it with one (or more) classes. That's what classes are for, and always have been for.

Support for custom HTML elements seems more appropriate for things like polyfills for actual official elements, or possibly more complicated things like UX widgets that really make sense conceptually as an interactive object, not just CSS formatting.

Using custom element names as a general practice to replace CSS classes for regular formatting just feels like it creates confusion rather than creating clarity.

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.

Hmmmm.

On the one hand I kind of want to use any random tag and have it work.

On the other hand ...

    <div class=main-article> # or <div class="main-article">

    versus

    <main-article>
I am not 100% sure, but I think I kind of prefer the div tag.

I understand that it is not the same semantically, but I am using div tags and p tags a LOT. I avoid the new HTML tags for more semantic meaning as this adds cognitive load to my brain. I'd rather confine myself to div and p tags though - it is just easier. And I use proper ids to infer additional information; it is not the same, but I kind of want to keep my HTML simple too. So I don't want to add 500 new custom HTML tags really. Even though I think having this as a FEATURE, can be useful.

This is what Angular does, where an Angular component is typically rendered as a custom tag. I find it to be one of the (very) few nice things about Angular, as it can be helpful to track down components in a large codebase. I haven’t used React for many years, but makes me wonder if custom tags as a convention would be similarly useful.
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.

That reminds me of BEM, where slow= is like the "element" within a parent "block".
> 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"]?

This is how you can set default styles for all your custom elements:

    :where(:not(:defined)) {
         display: block;
    }
Amazing, I was literally just trying to see if I could figure out how to do this. Thanks!
i'm very curious how screen readers would handle this. what a terrible idea
> Good luck trying to insert something inside of “article-heading” but after “article-quote” on the first try.

Indentation can help.

Isn't this the basis for every web framework? E.g., Vue Templates?