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
<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>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.
You can customize it using the Custom Element API: https://developer.mozilla.org/en-US/docs/Web/API/Web_compone...
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.
> <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> :where(:not(:defined)) {
display: block;
}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.
(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.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.
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.
> You are allowed to just make up elements as long as their names contain a hyphen. Apart from the 8 existing tags listed at the link, no HTML tags contain a hyphen and none ever will. The spec even has <math-α> and <emotion-> as examples of allowed names. You are allowed to make up attributes on an autonomous custom element, but for other elements (built-in or extended) you should only make up data-* attributes. I make heavy use of this on my blog to make writing HTML and CSS nicer and avoid meaningless div-soup. ↩
(HN filtered out a "face with heart eyes" emoji from the second example.)
If I were going to use them, I'd be inclined to vendor them just to prevent any sort of collision proactively
<donatj-fancy-element>
<donatj-input />
</donatj-fancy-element>What makes this awesome is that no future version of HTML can make your custom component stop working; it's supported down at the "bare metal" level.
I wrote an article [0] a couple years ago about how and why this came to be.
0: https://levelup.gitconnected.com/getting-started-with-web-co...
<!DOCTYPE html>
<html
xmlns="http://www.w3.org/1999/xhtml"
xmlns:ns1="mynamespace"
xmlns:ns2="yournamespace"
><body>
<CustomElement>Hello</CustomElement><!-- Custom element in the XHTML namespace -->
<ns1:CustomElement>Hello</ns1:CustomElement>
<ns2:CustomElement>Hello</ns2:CustomElement>
<style type="text/css">
@namespace ns1 "mynamespace";
@namespace ns2 "yournamespace";
CustomElement {
color:green;
}
ns1|CustomElement {
color:red;
}
ns2|CustomElement {
color:blue;
}
</style></body>
</html>
``` <pre><code class="janet">(<special>defn</special> <symb>bench</symb> <str>`Feed bench a wrapped func and int, receive int for time in ns`</str> [<symb>thunk</symb> <symb>times</symb>] (<special>def</special> <symb>start</symb> (<built-in>os/clock</built-in> <keyword>:cputime</keyword> <keyword>:tuple</keyword>)) ```
The goal is to make content readable by anything. As more users access information through systems like ChatGPT instead of visiting websites directly, content that isn’t easily interpreted by AI crawlers risks becoming effectively invisible.
Think `<readable-code>`, get a Slack thread where three seniors debate whether it's `<user-profile-card>` or `<profile-card-user>` while the shipper quietly ships it with `<div class="card">`.
One place I'd love to see this is in a classless html framework. My experience is you always wind up wanting something like cards, and then either writing classes, or having a slightly magic "use these elements in this order" incantation[1].
It would be great to have a minimal framework that peppers in a couple elements of the kind <card>, <accordian> etc.
[0] I did ask an LLM at one stage too, and it also didn't mention this behaviour exists.
[1] pico css does this.for.example for cards/accordians
JSX solves the "named containers" problem in code:
<ArticleHeader>
<ArticleQuote>...</ArticleQuote>
</ArticleHeader>
But the tags don't show up in the real DOM. Everything compiles to plain divs. Whether that matters depends on if you care about inspecting the rendered HTML or just the source code.With how this article was written (the use of "then" when they meant "than", mentioning "article-heading" when that is not in their previous example, but rather "article-header") makes me believe this didn't get much thought on the topic they wrote about, but rather wrote up a quick post.
Additionally, the problems that they bring up can be mitigated with the use of BEM structure for their class names.
https://github.com/h5bp/html5-boilerplate/blob/v0.9/css/styl...
I realized that I could just make up tags and style them and it was work.
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.
Which future version? Is there something I'm missing? I'd like to have html6 that has feature parity with native, but I'm afraid we got html5 and just stopped there. And if there will be an html6 why can't we just state "use version 5 in this document" so there won't be any name clashing between supported and custom tags?
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.
<invoice> <avatar> <dice> <card> <view> <toolbar>
You name it, it works wonders and make my life easier. Of course I am a lone developer so I don't care.You can check in this demo some custom tags used sparingly https://my.adminix.app/demo
If, for some reason the CSS doesn't load, your site may break completely instead of degrading gracefully. Maybe it will mess with people who have an unusual browser configuration too. It may look nice on your side, but on the user side, I only see disadvantages. It may look like it saves a few bytes, but with compression, it may not.
With classes, I can do:
carList = document.querySelector('.carList')
With custom tags, that is not possible because variable names cannot have hyphens in them.For merely defining custom elements you need JS anyway, so these aren't a technique intended for text authors. Yet as another way to organize code in webapps, custom elements are competing with JS which already has multiple module and namespace and OO import features that are much more flexible.
So as usual, random people on github (aka WHAT working group individuals aka Google shills) reinventing SGML, poorly. Because why not? The end goal always has been to make ad blocking an infeasible arms race and gather "telemetry."
HTML5 Shiv was needed, with added history https://www.paulirish.com/2011/the-history-of-the-html5-shiv... (2011)
Server-side you can use jsdom to polyfill document, it supports Web Components too.
You don't need much, but an editor - collapse the sections to get the view as small as in the blog snippet, and then you'll have both opening and closing of the tag you're in highlighted, so you won't miss and won't need any luck
Indentation can help.
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.