This is cool! I was actually wondering about how to make this work recently and obviously did a bad job of researching it because I didn't realise it already existed[0].
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
<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>
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.
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.
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.
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.
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.
It utlizes custom elements, has autohooks for granular DOM updates, uses native JS template literal syntax for interpolation, imposes ordered component structure:
```
<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>))
```
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.
> 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.
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.
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.
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.
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.
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.
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.
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.
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."
I was there like fifteen - twenty years ago before the hyphen standard and shadow dom and all that when JS libraries briefly leaned into just making up their own elements. I think everyone collectively agreed that it was a bad idea and it fell out of popularity.
If I were going to use them, I'd be inclined to vendor them just to prevent any sort of collision proactively
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.
I just evaluated Lit for work and while we didn't go with it, it was very nice. I love the base custom elements API regardless of using Lit or not, turns out that's all you really need to make intricate UIs that feel seamless.
Something about Lit/web components that's not written clearly on the label is the hoops you have to jump through to style elements. If you're using tailwind in the whole app, you just want to pull it into your custom elements without much boilerplate. My main app compiles a single minified app.css, it felt not so modular to now include that in every single component. The alternative is create a subclass that injects tailwind into Lit components. It'd be perfect it just had a switch to inherit everything the page already has.
While you can easily turn rendering to shadow DOM off on a per-component basis, that removes the ability to use slots. It only really works for leaf nodes.
Pulling a stylesheet into every component is actually not bad though. Adopted stylesheets allow you to share the same stylesheet instance across all shadow roots, so it's quite fast.
By default, Lit renders into shadow DOM. This carries benefits like encapsulation (including the style encapsulation you mention). If you prefer global styles, you can render into light DOM instead with that one-line switch.
However, shadow DOM is required for slotting (composing) components, so typically what I'd recommend for theming is leveraging the array option of each component's styles:
static styles = [themeStyles, componentStyles]
Then you define your shared styles in `themeStyles`, which is shared across all components you wish to have the same theme.
oh nice! I didn't know that you can just make it use light dom.
protected createRenderRoot() {
return this;
}
And that's what it takes! I like using tailwind/utility classes so for the styles I'd need to have layers of compiled css files rather than one giant one.
Interesting, I'd be curious to know why you all decided not to go with it if you're open to sharing! Minimally to know if I should look at any other promising frameworks.
I see a good case for my company to use Lit for creating complex components such as highly interactive panels/widgets to be shared between React/Angular apps in our large ecosystem. However the decision was: 1. Prefer sharing plain JS/TS over framework code so try that first and 2. if the component is so complex and tricky to get right, it probably needs to be re-implemented in each framework anyways (or some sort of wrapper)
My secondary concern with Lit is the additional complexity of using shadow and light DOM together in long lived React/Angular apps. Adding a new paradigm for 75+ contributors to consider has a high bar for acceptance.
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.
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.
So, the article doesn't discuss this, but there's actually a really good reason to make up and use custom elements: the browser can hydrate their dynamic behaviour automatically. For example, suppose you have:
<div class=expander>
<button aria-expanded=false>Expand</button>
<!-- Some other stuff here -->
</div>
And you have some JS that handles the expander's behaviour:
for (const expander of document.querySelectorAll('.expander')) {
const btn = expander.querySelector('button');
btn.addEventListener('click', () => {
btn.ariaExpanded = 'true';
});
}
This will work fine for `.expander` divs that are already in the page when the event handler is set up. But suppose you dynamically load new expander divs, what then? Your event handler is not going to retroactively set up their click listeners too.
Custom elements solve exactly this problem. You can now do:
<expander-elem>
<button aria-expanded=false>Expand</button>
<!-- Some other stuff here -->
</expander-elem>
And the browser will ensure that it always sets up the listeners for all of the expanders, no matter whether they are loaded on the page initially or dynamically injected later. Without this you would have had to jump through a bunch of hoops to ensure it. This solves the problem elegantly.
Yes, the hydration behavior of custom elements is nice. You don’t even need to do anything special with JS bundle loading.
Simply render your <element> (server-side is fine) and whenever the JavaScript downloads and executes your custom elements will mount and do their thing.
Beware that connectedCallback runs _every time_ a custom element is added to the dom. So you should make sure to only add event listeners once by tracking internally if the element was already initialized.
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.
> And a <div> is just a <span> with display block…
It's a bit more subtle than that. HTML5 defines "Content Models", two of which are 'Phasing Content' and 'Flow Content'. Phasing Content can only contain text and text-like tags (em, strong, bold) whereas Flow Content can contain anything.
Technically <span> is defined as accepting Phrasing Content and <div> accepts Flow Content. Changing this with CSS doesn't change the content model.
Although browsers are very forgiving so it all works anyways and this is very in the deep end, I can't think of the last time I've consciously thought of this stuff.
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.
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.
A more common alternative to counting divs would be CSS classnames or (for unique elements on the page) IDs. You'd do `document.querySelector('.my-class')` to locate `<div class="my-class">` or similar, rather than using the fact that e.g. something is nested 3 divs inside <body>.
Even if this custom element trick didn't work, I don't see why one would need to count divs (at least if you control the markup, but if not then made-up tags aren't an option anyway). The article even mentions using class names as an option.
Sorry, I didn't mention class names because the article explicitly did and I assumed that my aversion to the extra typing would be presumed by a reader of my comment. My mistake.
So yeah, I guess what wasn't obvious from my statement of gratitude was that I appreciate knowing that there is a more concise way of keeping track - even without CSS styling. If I make up tags, they will just inherit default styling but to my eye I can be clear about where things are closed, and where to insert things later. I was talking about the manual editing (in vim, as I mentioned), rather than any dynamic query selectors. Make more sense?
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.
https://blog.jim-nielsen.com/2023/html-web-components/ - Jim Nielsen has a series of posts on how to use made up HTML tags in a way that doesn't just fail to nothing when the javascript defining the custom-element doesn't get successfully executed.
I think it makes sense that if HTML detects an unknown element that it doesn't give it block styling automatically. Only if you specifically specified it for that type of element.
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.
> 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.
Serious question: are you saying that an entire webpage using only div and p tags is easier for you to grok than if the same webpage used standard tags like article and blockquote?
You're leaving so much functionality on the table. It also sounds like you're not using ARIA either, so your site is inaccessible to users of assistive technology.
You could use roles on your div tags to give a screen reader a fighting chance:
The HTML5 specification was released in 2014, so tags like article, section, header, figure, etc. have been around for more than a decade; they are not that new.
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
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:
It even has a bit of a "comment node" hack to let you write "self-closing custom elements" Good.HTML is the ride-or-die framework for BrowserBox.``` <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>)) ```
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.
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.
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.
You can customize it using the Custom Element API: https://developer.mozilla.org/en-US/docs/Web/API/Web_compone...
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.
https://github.com/aaviator42/yes-script
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."
> <article-header>
> <article-quote>
> <quote-body>
Not the best example, because in this case, you could just use real HTML tags instead
If I were going to use them, I'd be inclined to vendor them just to prevent any sort of collision proactively
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.
While you can easily turn rendering to shadow DOM off on a per-component basis, that removes the ability to use slots. It only really works for leaf nodes.
Pulling a stylesheet into every component is actually not bad though. Adopted stylesheets allow you to share the same stylesheet instance across all shadow roots, so it's quite fast.
It does! <https://lit.dev/docs/components/shadow-dom/>
By default, Lit renders into shadow DOM. This carries benefits like encapsulation (including the style encapsulation you mention). If you prefer global styles, you can render into light DOM instead with that one-line switch.
However, shadow DOM is required for slotting (composing) components, so typically what I'd recommend for theming is leveraging the array option of each component's styles:
Then you define your shared styles in `themeStyles`, which is shared across all components you wish to have the same theme.https://github.com/gitaarik/lit-style
My secondary concern with Lit is the additional complexity of using shadow and light DOM together in long lived React/Angular apps. Adding a new paradigm for 75+ contributors to consider has a high bar for acceptance.
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.
Custom elements solve exactly this problem. You can now do:
And then set up the listener: And the browser will ensure that it always sets up the listeners for all of the expanders, no matter whether they are loaded on the page initially or dynamically injected later. Without this you would have had to jump through a bunch of hoops to ensure it. This solves the problem elegantly.Simply render your <element> (server-side is fine) and whenever the JavaScript downloads and executes your custom elements will mount and do their thing.
HTML5 Shiv was needed, with added history https://www.paulirish.com/2011/the-history-of-the-html5-shiv... (2011)
http://www.badgers-in-foil.co.uk/projects/docbook-css/
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.
It's a bit more subtle than that. HTML5 defines "Content Models", two of which are 'Phasing Content' and 'Flow Content'. Phasing Content can only contain text and text-like tags (em, strong, bold) whereas Flow Content can contain anything.
Technically <span> is defined as accepting Phrasing Content and <div> accepts Flow Content. Changing this with CSS doesn't change the content model.
Although browsers are very forgiving so it all works anyways and this is very in the deep end, I can't think of the last time I've consciously thought of this stuff.
https://html.spec.whatwg.org/#the-span-element
https://html.spec.whatwg.org/#the-div-element
https://html.spec.whatwg.org/#content-models
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.
Even if this custom element trick didn't work, I don't see why one would need to count divs (at least if you control the markup, but if not then made-up tags aren't an option anyway). The article even mentions using class names as an option.
So yeah, I guess what wasn't obvious from my statement of gratitude was that I appreciate knowing that there is a more concise way of keeping track - even without CSS styling. If I make up tags, they will just inherit default styling but to my eye I can be clear about where things are closed, and where to insert things later. I was talking about the manual editing (in vim, as I mentioned), rather than any dynamic query selectors. Make more sense?
Inline styling is kind of the default in HTML.
Indentation can help.
On the one hand I kind of want to use any random tag and have it work.
On the other hand ...
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.
Serious question: are you saying that an entire webpage using only div and p tags is easier for you to grok than if the same webpage used standard tags like article and blockquote?
You're leaving so much functionality on the table. It also sounds like you're not using ARIA either, so your site is inaccessible to users of assistive technology.
You could use roles on your div tags to give a screen reader a fighting chance:
The HTML5 specification was released in 2014, so tags like article, section, header, figure, etc. have been around for more than a decade; they are not that new.