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
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.)
<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>Although be sure to avoid too many :has(:nth-child(n of complex selector)) in case of frequent DOM updates.
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.
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.You can customize it using the Custom Element API: https://developer.mozilla.org/en-US/docs/Web/API/Web_compone...
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.
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.
Web Components are underrated for sure. I had a need for a custom element[0] and it was not difficult to implement.
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.
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.
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.
Regardless, I stand by my comment. Monsters! I want my browser to be obnoxious.
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.
I modified `.blink` to `blink` so it will target the tag instead of the class and it seemed to work
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.
Nothing to replace it with to afaik.
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.
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.
(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.> <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>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.
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."