Resilience

A presentation at Halfstack London in November 2024 in London, UK by Niels Leenheer

Slide 1

Slide 1

Resilience

Slide 2

Slide 2

Hi, I’m Niels. I’m a Front-end developer. 30 years and counting. My first official job title was…

Slide 3

Slide 3

Webmaster. This is me back in 1994, working on my first website. As you can see I am holding the power sword which gives you the ability to write flawless HTML and defeat Skeletor, the lord of the JavaScripts.

Slide 4

Slide 4

If I counted correctly, this is the 12th time I am giving a talk at HalfStack. I just love the mix of web development topics and to see people use browser APIs and Javascript in creative and unexpected ways.

Slide 5

Slide 5

So… now the awkward thing… I know this is technically a JavaScript conference…

Slide 6

Slide 6

Except my talk will have no Javascript. No React. No Node. Not even Deno and Typescript. No script at all. Except for noscript.

Slide 7

Slide 7

The noscript tag.

Slide 8

Slide 8

For this talk we’re going back to basics and back in time. We’re going to ask the important questions, like…

Slide 9

Slide 9

Can you nest noscript tags?

Slide 10

Slide 10

Can you style a noscript tag?

Slide 11

Slide 11

And what happens when you put a script tag in a noscript tag?

Slide 12

Slide 12

And we’re going to talk about the one thing that HTML is…. that JavaScript simply is not. Whenever you make a mistake in Javascript something bad will happen. One typo and your build will fail. Or worse your browser will… Explode!. Really. True story.

Slide 13

Slide 13

But not HTML. Resilience against errors and mistakes is build into the fabric of HTML. You are allowed to make mistakes. In fact you are expected to make mistakes, because HTML was intended to be used by non-professionals. Everybody can make a website.

Slide 14

Slide 14

Just read the source code of another website, try it for yourself and call yourself a webmaster. That is what I did. That is what I still do… Except now I ask ChatGPT and Copilot to solve my problems and I call myself a front-end developer. Or when I feel expensive, I am a front-end engineer. But in my heart I am still a webmaster.

Slide 15

Slide 15

This is Tim. Tim is a Web Developer. Back in the 80s, he was a engineer at CERN - you know the particle accelerator thing - and he wanted to make publishing research and managing information easier allowing scientists to at CERN to collaborate with colleagues around the world.

Slide 16

Slide 16

So he did what comes naturally to every engineer, come up with overly complicated ways to solve ‘simple’ problems. Let’s build a world wide network of connected information. A world wide web of knowledge if you will. Can’t be too difficult, right? So he wrote a paper “Information Management: A Proposal”.

Slide 17

Slide 17

His supervisor - Mike Sendall - though it was interesting and wrote this on top of his paper…

Slide 18

Slide 18

“vague but exciting”. And that started the whole World Wide Web revolution.

Slide 19

Slide 19

He created WorldWideWeb - which was the name of the first browser - which was not just a browser, but also an editor, and created the first website. Not with the vaguest idea that it would lead to the web of today, but to let everybody - anybody - publish information. And it already had the concept of resilience. Sir Tim. THE web developer. And yes, that is his real job title.

Slide 20

Slide 20

That first website is still here. Still works. After more than 30 years. Any browser will work. This is in my opinion amazing. This truly is resilience.

Slide 21

Slide 21

So lets look at the source code. It even looks like HTML, but a bit weird. We can see familiar tags, like BODY, H1, P and A. But also NEXTID tag and a TITLE in a HEADER tag. And where is the HTML tag?

Slide 22

Slide 22

But it still works. No errors. The page just renders fine.

Slide 23

Slide 23

Why does it still work? Browsers will simply “ignore” tags that it does not recognise. This quote is directly from that first website.

Slide 24

Slide 24

So a modern browser will see this NEXTID tag - which it really does not understand… the browser will ignore the tag.

Slide 25

Slide 25

Well, ignore is a bit of a strong word. That tag is turned in to an element in the DOM, it’s still there. It’s still a NEXTID element, but it has no special meaning. It’s just a element, kinda like a regular SPAN element.

Slide 26

Slide 26

In fact this is why NOSCRIPT works.

Slide 27

Slide 27

If your browser does not support scripting, it also does not support the NOSCRIPT tag. It will “ignore” it an turn it into a generic HTML element. Like a span. So the fallback content will be visible.

Slide 28

Slide 28

If your browser does support scripting, it also supports the NOSCRIPT tag. And by “support”, I mean that it actively makes sure that the NOSCRIPT element and all of its descendant do not show up on screen.

Slide 29

Slide 29

This is one of the basic principles of HTML. It ensures forward and backwards compatibility. You could use a browser from 1995, such as Mosaic and load the HalfStack website. It will work. Without any styling of course, because CSS did not exist yet. But still, you can read the text and click links. This is what resilience means.

Slide 30

Slide 30

With this mechanism you can do cool stuff , like bring back your favourite tags from the past.

Slide 31

Slide 31

Like the BLINK tag. Yeah, let’s bring back the BLINK tag.

Slide 32

Slide 32

In currently browsers the BLINK tag is just like any other unknown tag. It’s basically a SPAN. So the text will show up on screen, but it is not blinking. This we need to fix.

Slide 33

Slide 33

So, just add a little CSS and we can style our BLINK tag. An infinite animation between two keyframes. Turning on and off the visibility. This will work. We’ve brought back the BLINK tag. And NO I’m not going to demo this.

Slide 34

Slide 34

And why stop with the BLINK tag. We can do the same for the MARQUEE tag. It’s a little bit more difficult, but we can get this working. All we need to do is………. wait. We don’t need to do anything.

Slide 35

Slide 35

MARQUEE actually still works in all browsers. I didn’t realise this. It’s deprecated by the HTML5 spec, it isn’t actually “baseline”… but you can actually still use it….. If you wanted to…. Seriously, don’t.

Slide 36

Slide 36

What is it that makes HTML so resilient? What makes it so flexible and error friendly? What is it that makes it special?

Slide 37

Slide 37

All the magic happens between your HTML source files and the Document Object Model, The DOM.

Slide 38

Slide 38

When the browser parses your HTML file, it uses a tokenizer and a tree builder. And those two build the DOM tree that the browser uses to render the page. The browser doesn’t render the HTML, it renders the DOM.

Slide 39

Slide 39

The tokenizer

Slide 40

Slide 40

Basically does nothing more than just analyse that HTML file character by character. And it tries to extract all the information it needs to build that DOM tree.

Slide 41

Slide 41

So when we have a piece of HTML like this, it will start with in an initial state.

Slide 42

Slide 42

The data state. It sees the SMALLER THAN SIGN and thinks this might be a tag. So it goes to the…

Slide 43

Slide 43

TAG OPEN STATE. It sees the letter A and continues with the

Slide 44

Slide 44

TAG NAME STATE and adds that letter A to the tag name. It then sees a SPACE.

Slide 45

Slide 45

and switches state again…

Slide 46

Slide 46

And so on… character by character…

Slide 47

Slide 47

Slide 48

Slide 48

Slide 49

Slide 49

Slide 50

Slide 50

Slide 51

Slide 51

Slide 52

Slide 52

Slide 53

Slide 53

Slide 54

Slide 54

Slide 55

Slide 55

So now it has all the data about this tag. It knows the TAG NAME, the ATTRIBUTE NAME and the ATTRIBUTE VALUE.

Slide 56

Slide 56

It now has the token and emits it to the tree builder

Slide 57

Slide 57

There are 68 different states

Slide 58

Slide 58

Some are simple.

Slide 59

Slide 59

Most are a bit more complicated.

Slide 60

Slide 60

But most importantly. When it encounters a PARSE ERROR, it will not stop processing the file. It will not show an error message. It will switch to a different state and just continue on.

Slide 61

Slide 61

Together, all of these rules determine what HTML looks like. And in this case in particular it determines what TAG names are allowed to look like. It determines which characters are allowed an which are not. And just like the rest of HTML, the tokenizer is very forgiving.

Slide 62

Slide 62

This is a tag.

Slide 63

Slide 63

As long as the first character of the tag name is an ascii letter, we’re good. And this is not an upside down “n”, but a “u”.

Slide 64

Slide 64

To be fair, the equals sign is a parse error, but the rules specify exactly what needs to happen in this case. The first equals sign becomes the attribute name.

Slide 65

Slide 65

Now I know what you are thinking. This is an accident waiting to happen. But this is why custom elements work.

Slide 66

Slide 66

This is why Angular works. Yes, attributes can start with an asterisk. And yes parenthesis in an attribute name is also fine.

Slide 67

Slide 67

It’s why Vue works. An attribute that starts with an at sign… no problem.

Slide 68

Slide 68

But, yeah… you can go too far. According to the HTML parser spec, this is a valid tag. Not a HTML tag, but a tag nonetheless.

Slide 69

Slide 69

This too… Oh…. Eh wait… No this is a mistake. This is obviously…

Slide 70

Slide 70

No not a proper tag.

Slide 71

Slide 71

Yeah, let’s check the spec. If the tag name contains a space it switches to the before attribute name state.

Slide 72

Slide 72

But yeah…..

Slide 73

Slide 73

This is not a space. For typographic reasons there are many different spaces of different sizes. All of them white space. But this is not unicode code point 20. This is not a space. This is a FIGURE SPACE.

Slide 74

Slide 74

Slide 75

Slide 75

Slide 76

Slide 76

Now, if you really want to mess with your coworker, just run this script on his or her computer. It will replace all spaces between the a and the href to a figure space. In all HTML documents. This will really mess every up.

Slide 77

Slide 77

Every document will suddenly be completely screwed up… And the funny part is, when you look at the documents in code editor with a monospaced font, you can’t see the difference…. Pretty evil, right. So actually… don’t do this.

Slide 78

Slide 78

Seriously, don’t do this. I’m not responsible for anything that happens.

Slide 79

Slide 79

So, can you break HTML? Can you put an emoji in an tag name or attribute name and break HTML? Well, no. Not really. This….

Slide 80

Slide 80

is allowed…. eh… wait….

Slide 81

Slide 81

this is allowed…. yes. Emoji are just unicode and you can put any unicode character in a tag name as long as it starts with a regular letter.

Slide 82

Slide 82

And you can style it like this. This works. Just sprinkle a little bit of CSS and voila. And it doesn’t have to be I Love. It can be Is shit. And it doesn’t have to be HTML. It can be any random 4 letter combination.

Slide 83

Slide 83

Of course nobody serious would want to use emoji’s in production, right…?

Slide 84

Slide 84

Anyone remember this?

Slide 85

Slide 85

Now I am not saying nothing matters. All tags are equal and semantics are not important…

Slide 86

Slide 86

Semantically this is just as bad as…

Slide 87

Slide 87

This… These are not a buttons.

Slide 88

Slide 88

This is a button. It works as a button. You can tab to it. You can click it. And it’s free.

Slide 89

Slide 89

All the tags we created are not HTML tags. They have no function. You can style them, but that is it. Functionality wise they are nothing more than a <span>.

Slide 90

Slide 90

The other reason why HTML is so resilient is the tree builder. The tree builder receives the tokens from the tokenizer and actually builds the DOM tree with it. Sounds easy, but it really is more complicated than it seems.

Slide 91

Slide 91

So, if we have a piece of HTML like this. A simple a tag with some text in it. The tokenizer will produce three different tokens.

Slide 92

Slide 92

The open tag, the character token and the closing tag.

Slide 93

Slide 93

And the tree builder turns that into a HTMLAnchorElement DOM node and a text node. Still simple so far. But that is actually not what happens when the tree builder receives these tokens. It does so much more.

Slide 94

Slide 94

It actually creates missing elements that are required for your HTML document. Let’s see what happens.

Slide 95

Slide 95

So, the first token is a A TAG OPEN token, but that does not make sense in this context

Slide 96

Slide 96

So it creates the HTMLHtmlElement

Slide 97

Slide 97

Slide 98

Slide 98

Then the HTMLHeadElement

Slide 99

Slide 99

Slide 100

Slide 100

And a HTMLBodyElement… and now the A tag open finally makes sense.

Slide 101

Slide 101

So it creates it….

Slide 102

Slide 102

And the text node.

Slide 103

Slide 103

And closes the Anchor element.

Slide 104

Slide 104

And we’re done. We actually now have a DOM that makes sense and is complete. It creates all the nodes that were missing. And this is why that very first HTML page works, even though it didn’t have an HTML element. Even without that HEAD element it will work just fine. It just re-creates the missing elements.

Slide 105

Slide 105

There is now a HTML and HEAD tag. And it move the HEADER tag to the body, because that is where it makes sense.

Slide 106

Slide 106

But it also fixes your mistakes. So if the tree builder encounters some tags that are not nested in the right way, it will try to make sense of it. For example.

Slide 107

Slide 107

Everyone makes mistakes. And we don’t want this to happen.

Slide 108

Slide 108

We don’t want to go back to the days of XHTML. Where every document had to be very strictly conforming to the spec, otherwise the browser would just give up and show the ugly error message.

Slide 109

Slide 109

Fortunately with HTML5 browsers won’t throw an error anymore. This will just render. In a very specific way, defined by the spec. No interpretation differences between browsers. This will work in a very specific way. Quiz time. What style will the 3 be? Will the browser ignore the closing B tag, or close the I tag? Or what? Who here knows…?

Slide 110

Slide 110

So lets take a look.The first part is pretty straightforward.

Slide 111

Slide 111

We get a B and I element with the correct text… But what happens now?

Slide 112

Slide 112

But now we get the CLOSING B TAG token. This is not what the tree builder expected. So it tries to figure out which tag it needs to close.

Slide 113

Slide 113

And that is this one. So it closes this one and goes back to the BODY element.

Slide 114

Slide 114

Then it sees another text token. But it does something special. It maintains a list of active formatting elements. The B is an formatting element, but we just closed it. So that list contains just one. The I element. That one is still active. We never closed it.

Slide 115

Slide 115

So that text token, not only creates a text node. It also creates a new element for that still active formatting element. So the 3 is italic.

Slide 116

Slide 116

And that brings us back to the first website created by Tim Web developer.

Slide 117

Slide 117

If you validate that very first website. You’ll get some errors. One reason is because the validator only goes back to version 2 and that very first website is not even HTML 1. But there is also something else. There is an actual error in that very first document.

Slide 118

Slide 118

And that just confirms to me that allowing errors is something that is build into the DNA of HTML. Did you see it? Here! There is an CLOSING A TAG without a OPENING A TAG. Just a simple mistake, but the browser won’t care.

Slide 119

Slide 119

And again, this is what makes HTML special. This is what makes HTML for everyone. You don’t need a computer science degree to make a website. You are allowed to make mistakes.

Slide 120

Slide 120

Everybody can make a website. Some will be bad. Some will be good. It can be about Star Trek fanfic, or React. Or your cats. It can be about any other random unimportant subject. But it will be a website. And the browser will render it.

Slide 121

Slide 121

I think that is beautiful. That is what the web is about. Not just about consuming content, but also making content. It is about sharing knowledge. It’s about making connections.

Slide 122

Slide 122

I get a little bit sad that nowadays almost nobody has a personal website anymore. We all use commercial platforms like WordPress, Facebook or …X. And that is understandable - web development has become too difficult. You need a computer science degree just to install your development environment.

Slide 123

Slide 123

For you and me this isn’t a problem. We are webmasters. We rule the web. We copy and paste, experiment and have fun with tags and elements. But it makes me a little bit sad most people are dependent on platforms owned by madmen with super inflated ego’s and wannabe dictators.

Slide 124

Slide 124

This isn’t what the web is supposed to be. I know photo feels a long time ago. A lot has changed in the world. But the web should be for everybody. So, if you don’t have a website. Make one. Experiment. It doesn’t have to be good. Make content and share knowledge. That is the web.

Slide 125

Slide 125

Oh, I have a website. Compared to some of other personal website I see it is pretty rubbish. But it is MY website. And it works in all browsers. And I share knowledge on it.

Slide 126

Slide 126

So finally let’s get back to the NOSCRIPT tag. With what we’ve learned we can now answer the questions from the beginning.

Slide 127

Slide 127

What happens when you nest two NOSCRIPT TAGS? Well lets just see.

Slide 128

Slide 128

The second noscript tag isn’t a tag at all. Everything will be text until the browser encounters a closing noscript tag. Everything, including the second opening noscript tag. And it will simply ignore the second now lonely closing noscript tag.

Slide 129

Slide 129

What happens when you try to style a NOSCRIPT tag? For example set visibility to visible. Set the display to block. Opacity? Bang important?

Slide 130

Slide 130

Well, that simply does not work. The contents of the NOSCRIPT tag is not hidden by CSS which you can override. It is ignored in the renderer. The NOSCRIPT tag will never be rendered. It is the only element that is de fined do absolutely nothing.

Slide 131

Slide 131

And a SCRIPT TAG inside of a NOSCRIPT tag. Well I’m sorry.

Slide 132

Slide 132

That is obviously not going to work. Why would you want to do that?

Slide 133

Slide 133

Except…. Yeah….

Slide 134

Slide 134

And with that, I’ve officially used JavaScript in my talk.

Slide 135

Slide 135

Thank you!