87 comments

[ 3.0 ms ] story [ 140 ms ] thread
How fortunate, I was looking for something like this today for a side project. HTML can do so much already, I'd rather lean into it than use one of the bloated frameworks/libraries out there.

Really helpful to see it all in one place!

Have you tried htmx?
htmx isnt meant to solve frontend element problems, it's for more easily communicating with a backend.
Yes! I just used it last week to create a quick gallery website. It's been a lot of fun playing around with it. Like the other poster said though I wasn't able to get it to do everything I wanted in frontend so used a bit of vanilla javascript as well.
It's so cool how much stuff you can get done with just stock HTML.
Has anyone ever encountered a real world scenario where you reached <h6>?
Yep! The first tech job I ever had was at a hyper local marketing agency, so most of my time was spent updating restaurant menus and sales for little local stores.

The restaurant menus would always reach into insane levels of hierarchy, mostly because many of them made way too many things. Sometimes you need the:

Restaurant -> Menu -> Antipasti -> For Groups -> Fried -> Cheesy

hierarchy to feature the mozza sticks and arancini correctly.

I made a web version of a huge book written by my former professor/boss. It definitely used 6 heading levels, maybe even more.
One of many things that irk me, like why limit to 1-6 instead of allowing an attribute for arbitrary size, eg <h level=15>
You can go beyond 6 with ARIA, e.g. role="heading" aria-level="7". I don't know what the limit is. I think it's challenging to find distinct visual styles for many heading levels.
They tried to make the the explicit number irrelevant and infer the level by the number of nested sections, so instead of:

    <article>
      <h1>Title</h1>
      <section>
        <h2>Section</h2>
        <section>
          <h3>Sub Section</h3>
          <section>
            <h4>Sub Sub Section</h4>
          </section>
        </section>
      </section>
    </article>
You could simply use <h2> repeatedly and keep the semantic structure of the former.

    <article>
      <h1>Title</h1>
      <section>
        <h2>Section</h2>
        <section>
          <h2>Sub Section</h2>
          <section>
            <h2>Sub Sub Section</h2>
          </section>
        </section>
      </section>
    </article>
However this was never implemented by any browser or screen reader and was finally dropped from the standard.

http://html5doctor.com/computer-says-no-to-html5-document-ou...

Most of these aren't widely used because they were quaint attempts at solving problems that no longer exist, could be better solved with CSS (as the author concedes with <small>), and very much depend on browser implementation.

I was excited when <details> and <summary> landed in all evergreen browsers for example, but just to get the content to slide open (guiding the user) instead of pop open requires JS (the best implementations I've seen use WAAPI), Safari adds a proprietary pseudo element, etc.

> I was excited when <details> and <summary> landed in all evergreen browsers for example, but just to get the content to slide open (guiding the user) instead of pop open requires JS (the best implementations I've seen use WAAPI), Safari adds a proprietary pseudo element, etc.

It is possible to have sliding animations without JS, it just isn't very pretty on close (on open looks fine):

https://codepen.io/dada1smo/pen/LYydWBg

(note, that is not mine, I found it via a comment on a css-tricks link).

Thanks! I should have specified it's impossible without a fixed height (height: auto).
<small> used to be a formatting tag, but with HTML5 it became a “fine print” tag.[1] Formatting-only tags like <font> have long been deprecated and fallen out of use.

  [1]: https://developer.mozilla.org/en-US/docs/Web/HTML/Element/small
...and <i> is supposed to mean "idiomatic text" now but let's be honest it's never used that way
> Some of deprecated elements won’t render without some extra work, for example <frame> and <frameset> are designed to be used instead of a <body>, for I guess some kind of collage web page made up of other pages.

The author is too young to remember frames, huh? :) I'd just link the Wikipedia article ( https://en.wikipedia.org/wiki/Frame_(World_Wide_Web) ), but I feel like it doesn't explain it very well.

So, to briefly explain -- in the early web (OK, not the really early web, but once it got popular) frames were very common. They were commonly used for menus/sidebars, as well as things like headers that were meant to stay visible. So perhaps a page would have three frames -- a frame up top with a persistent header, one on the left with a sidebar, and then one main frame with the content.

Each frame acted fairly independently, with e.g. its own back/forward history (a link in a frame would by default only affect that frame, although you could have links in one frame open in another, useful for implementing a sidebar). This meant using back/forward/reload/etc with frames could be pretty troublesome and unintuitive. If you somehow got a page into a messed-up state where the wrong thing was loaded in one frame, it could be hard to get out of this state other than by navigating to the page from the start. Or it could be troublesome if you accidentally loaded just the content page without the framing page it was supposed to be a part of.

CSS got rid of most of the use case for frames, which is good, because frames were a real pain to deal with as a user!

One usage of frames I recall was for sites that were meant to act as an index of other sites, where there’d be a sidebar on the left with links to various sites that opened on the right.

I think this was actually a pretty good use case for frames, especially back before browser tabs existed. It was nicer to run through a list of links in one window with frames than to jump back and forth through history or juggle multiple windows.

When I was young and still lesrning the basics I used it as a table of content for some long webpages that you could use to quickly jump from one anchor to another, or as a sitemap.
I remember the arms race between these kind of framing sites (often increasingly scammy) and sites that did not want to be framed and had various anti-framing scripts.
I remember a search engine working like that, but I forget it's name. Dog something? It's ground breaking idea was, hey all these search engines kind of suck and you have to go to about 10 of them to find what you want - so what if you enter one search term on our page and we'll Iframe in the results from 10 different search engines!

I remember everyone at my university using it for quite a while, then google came out we were floored with the simplicity of it's home page (imagine what ten 1999 yahoo search competitor results crammed into one page looked like :D )

Dogpile?
Dogpile! That's it! Oh wow it even has it's own wikipedia page, and it's still online (albeit a very different site now).
Dogpile was the first search engine I ever used. My dad had a buddy who was into tech stuff, who showed us how to use it.

Later I learned about AskJeeves from a cousin who showed me how to download emulators and ROMs (this would have been in the mid-late 90s).

It's funny to think how much of my early tech experiences came from in person interactions. Dad's friend also built the first computer which I owned, which belonged to my grandma until she got a shinier Dell pre-built for a birthday.

I was allowed to "purchase" that machine for the price of two free mows (so $40). This was a steal by any metric. It became the foundation for basically all my computer learning into my preteen and teen years and the centerpiece of my bedroom. I have many fond memories of kicking back in my bedroom with ZSNES or bootleg Family Guy episodes.

Idk that I'd really connected until today how much of an influence that friend of my dad's had on my life, just through a few simple acts of thinking the net was cool and sharing with my family.

iframe can do that: just change the src attribute.
This reminds me of “frame buster” JavaScript. It was a piece of JS that goes in the site to combat above mentioned behavior and “freed” your webpages from someone else’s content frame.
Is this the same as now right clicking on an iframe and selecting "Show This Frame Only"?
No -- the point of a frame-buster script is that it's a script included on a page to force that page out of a frame, it's not something the user runs deliberately.
The big issue with this any really an use of frames is that you can't bookmark or share the state.
The first website I created on GeoCities back in the 90s used frameset. In exactly the same layout you have mentioned.
Eric Meyer, the king of css still has his old css references in frames pages https://meyerweb.com/eric/css/references/css1ref.html
I get "www.w3.org refused to connect." Is that expected?
I guess it is some sort of cross-site security thing. Devtools just says "blocked:other" as the reason for not displaying it.
Firefox on Android actually has a great error message here:

> Nightly Can’t Open This Page

> To protect your security, www.w3.org will not allow Nightly to display the page if another site has embedded it. To see this page, you need to open it in a new window.

> Learn more…[1]

> [Open Site in New Window]

[1]: Links to https://support.mozilla.org/en-US/kb/xframe-neterror-page

Oh my god! You must be very confused now, being told an error message, and some detail about it.

Dear end-user, do you need therapy? I'll make sure that message is removed in the next release, so other end-users are not subjected to such horribly frightening information.

Chrome shows the following:

> Refused to frame 'https://www.w3.org/' because an ancestor violates the following Content Security Policy directive: "frame-ancestors 'self' https://cms.w3.org/".

It only shows that in the console for me. The rendered error page just says 'www.w3.org refused to connect.'
Then came iframes, also terrible.
Then came the adtech boom. <img> got things started but a hidden iframe running ads in rotation? That minted fortunes.
Awesome article. Like the author, I'm also confused about when to use b and strong & i and em.
I had thought that <b> and <i> describe how something should look, whereas <strong> and <em> describe the meaning of something. <b> means "this text should be thicker and darker than it normally would be", <strong> indicates "this text has gravitas... interpret that however you want". In other words, visual vs. semantic.
I have heard similar but the consequences always seemed weird to me. Following this if something is important and also should look visually different, I should use both <strong> and <b>. However If something is important and I don't want it to show, I should use <strong> alone and <b> alone only for the case where something should look important but that has actually no meaning as the meaning conferring tag would be <strong>.
The quintessential semantic use of <b> is for typographically offsetting key words in a longer text, like how 5th Edition D&D adventures do when referencing a monster that has a stat block in the Monster Manual. It’s not strength of voice, but it has meaning that the text be emboldened.
Just use b and i, em and strong are bloat and are harder to type if you are hand-writing html. The semantic web is dead anyway.
I’m not sure if screen readers actually work like this but the intention was that text that is <em> is spoken with emphasis, like “oh, please”, whereas <i> is simply italic, like veni, vidi, vici.
So <i> will give my screen reader an Italian accent?
That's where the classic nickname 'Mario tags' came from.
this an ancient debate, but in practice there is no difference
My sense is that the more complicated explanation that OP found is just retconning, trying to explain away the fact that someone in the committee didn't like <b> and <i> but couldn't get anyone else on board with deprecating them.

In practice, any sane screen reader or default visual style will treat them exactly the same.

<em> is for emphasis, <i> is for other things that typically use italic text (except those that fall under <dfn> or <var>), such as foreign words. Analogously for <strong> and <b>.
Lol, in modern react apps sometimes I find <span style={{fontWeight: 'bold'}}> or even better some made up "component" like <Box> or <Typography>. Then there is styled components like bold = styled.span`font-weight: bold`. It's amusing.
This comes up briefly but I do still find it ridiculous that there's no simple standard CSS declaration to hide something from visible display but keep it for screenreaders.

Everything I've seen still does clip, or positions the content off the side of the page, or something like that. How is this not just an alternative "display" value, or an additional property?

There's been a "speak" property floating around in one of those theoretical CSS modules that would accomplish this but as far as I know it has zero uptake among implementers.

> no simple standard CSS declaration to hide something from visible display but keep it for screenreaders

ARIA attributes allow for that.

https://developer.mozilla.org/en-US/docs/Web/Accessibility/A...

Example code.

https://stackoverflow.com/questions/26032089/in-html-how-can...

aria-label/labelledby is not always a workable solution. Sometimes you really need the text to be sitting there on the page as text for things to work right.

Note that the very SO thread you linked to goes immediately to doing position/clipping tricks right after mentioning aria-label.

Why should it be a part of CSS, that handles visual representation, and not part of HTML, which handles data, structure, and semantics?

I wonder if a whitespace <div> with a right aria-label could fit the bill.

CSS's display: none and visibility: hidden already affect what the screenreaders can "see." So it's already involved.
And getting sick is a great reason you might use the phone to call into work but it doesn't imply getting sick is therefor the way to run all other phone usage through. I.e. it changes the behavior of the screen reader because it hides the content of the document and a screen reader knows it doesn't make sense to read content that was removed but that doesn't provide any support for why content which only affects screen readers belongs in the styling language as well.

Further point, in case you still disagree whether it makes sense for CSS to include the ability or not: CSS supports pseudo-elements but that doesn't mean tags in your page should be turned into pseudo-elements just because you can.

> I wonder if a whitespace <div> with a right aria-label could fit the bill.

Aria-label only works on interactive elements. I believe except the div has a `role`, screenreaders will ignore the label.

I was trying to make a web browsing ai agent a few days ago and I was shocked to find that hacker news comments are implemented as table inside table inside table.
I was delighted when I found this out - my userContent.css to make HN more readable (make content have a limited width, set a 1.5em line-height and extra padding-top for all paragraphs).

I no longer struggle to read HN on a wide browser which display 250 characters on a single line. Each paragraph is readable, and the paragraph breaks are visibly higher than the line-height.

Do you mind sharing this? Sounds like it would solve the exact problem on my ultra-wide monitor.
Not at all, copied verbatim from my userContent.css file, full path $FIREFOXPROFILE/chrome/userContent.css:

      @-moz-document domain(news.ycombinator.com) {
         .comment {
            font-size: 12px;
            line-height: 1.75em;
            padding: 10px 0 10px 0;
            max-width: 64ch;
            display: block;
         }
         .commtext {
            font-size: 12px;
            line-height: 1.75em;
            padding: 10px 0 10px 0;
            max-width: 64ch;
            display: block;
         }
      }
While we're talking userContent.css hacks, I'd be delighted to share my snippet to make code blocks look like (simplified) Mac windows in case anyone else wants to play with it.

There's definitely room for improvement but I don't think it looks half-bad: https://i.stack.imgur.com/xcyoE.png

    @-moz-document domain("news.ycombinator.com") {

        body {
            font-family: -apple-system, "Adobe Clean", -apple-system, Helvetica, sans-serif !important;
            font-size: 11pt;
            color: #828282;
            background-color: #1B2835 !important;
        }

        * {
            font-family: -apple-system, "Adobe Clean", -apple-system, Helvetica, sans-serif !important;
        }

        * code {
            font-family: "Fira Code", "Monaco",  "Consolas", "Courier New", monospace !important;
            margin: 0;
            padding: 0;
            font-size: 0.9em;
        }

        code:before {
            content: "⬤⬤⬤";
            position: absolute;
            top: 5px;
            left: 12px;
            color: #ccc;
            letter-spacing: 3px;
            -webkit-text-fill-color: #ccc; /* Will override color (regardless of order) */
            -webkit-text-stroke-width: 1px;
            -webkit-text-stroke-color: #223b4f; 
        }
        code:before::first-letter {
            color: #ff5f56 !important;
        }

        pre {
            background-color: #234 !important;
            border-radius: 15px;
            padding: 30px 0px 10px;
            border: 0.5px solid #223B4F  !important;
            box-shadow: inset 0 0 1px #123;
            position: relative;
        }

        table#hnmain{
            background-color: #1B2835 !important;
        }

        a:link {
            color: #bfbfbf !important;
            text-decoration: none;
        }

        .c00 {
            color: #cecece !important; 
        }    

        .cdd {
            color: #768696 !important; 
        }    

        .c5a {
            color: #465666 !important; 
        }


    }
(comment deleted)
The article is interesting, but I often come across resources that talk about or reference the HTML5 specification by the W3C. Since 2019, HTML has become a living standard (and therefore no longer has a version number). It is available through Whatwg here: https://html.spec.whatwg.org/multipage/
You can nest details/summary tags. I once created a choose-your-own adventure using it and posting it on our corporate intranet (I had a generator script to stitch things together. The actual text was only a few pages long.) The HTML was 5mb ... I broke a lot of browsers that day. It had to be deleted.
This sounds interesting, but I’m not following. Do you mind expanding?

Specifically, how does nesting details/summary tags relate to 5 MB of HTML, and how does that relate to breaking a lot of browsers?

Sounds like a great story, and I’d love to hear it!

If you have a story with the following prompt:

> go left

> go right

Where each of those is a branch in the story. Even if both branches converge eventually, all possibilities need to be in each branch. And so on. The number of summary tags is n! where n is the number of possible decisions.

Thus you very, very quickly end up with a very large dom. Browsers aren’t really optimized to display hundreds of thousands of these tags, so they crashed.

The GP made an entire game in an (autogenerated) static HTML file. Most browsers don't have a 5MB single HTML as an usual target, and I guess not as a test case either.
Semantic HTML has excellent potential. I personally like the style where footnotes for running text are placed in the right-side margin, in a smaller and/or semi-greyed font, and maybe with details/summary expanders.

But every implementation of styles like this seem to require some sort of detailed knowledge of CSS to wrangle it into working order.

Regarding the <menu> element, which the OP mentions their confusion about as:

> I was initially surprised that it survived to HTML 5 (while <menuitem> didn’t) because modern browsers treat it as essentially a <ul>. Researching further on Wikipedia I read: "MENU existed in HTML Tags, and was standardized in HTML 2.0; deprecated in HTML 4.0 Transitional; invalid in HTML 4.0 Strict; then redefined in HTML5, but removed in HTML 5.2," and now I don’t know what to think.

HTML 5.2 was retired by W3C in 2021 in favour of the WhatWG HTML Living Standard, which (unlike HTML 5.2) never deprecated <menu>, and has been redefined as representing "a toolbar consisting of its contents, in the form of an unordered list of items (represented by li elements), each of which represents a command that the user can perform or activate.".

Wikipedia's list of elements seems to be out of date here — along with a lot of the Wikipedia information on HTML versions — as the <menu> element is still alive. Given its history of being repeatedly deprecated, and the fact that event recently browsers were confused by exactly what semantics to assign to <menu>, you are probably nearly always better off using <ul> with an appropriate ARIA role attribute (toolbar, menu, or menubar).

It's got <marquee> I'm happy.
Did the same thing. Just scrolled to find it!
Bing back <blink>!
You can do that and <marquee> with some css rules for the tag. I did on a few joke sites I made a couple years back.
This reminded me of when when I first learned HTML in around 1995… anybody else remember Kevin Werbach’s Barebones Guide to HTML?

It was basically a site that listed all the HTML tags and what they did.

That plus a text editor and early version of Netscape Navigator was all you needed, and you were off to the races to learn and experiment!

First, this is a fantastic way to learn, such a great exercise!

It's also fun to see the author ponder some of the older and now unused elements, speculating on their use, when "back in the day" they were thrilling to suddenly have access to.

That said, handcrafting HTML through every rev since Mosaic, I don't like MDN because of retcon changes like "description list". I prefer original spec, "definition list".

To me dl, dt, dd, makes more sense to think of as "definition list", with defined terms, and defined definitions.

OK, description is broader than definition, but for me, definition is easier to remember the list (dl) has terms (dt) and definitions (dd).

And W3 calls it "definition list":

https://www.w3.org/TR/html4/struct/lists.html#edef-DL