You don’t need external assets in an HTML file – Terence Eden’s Blog


(Written mostly to settle a good-natured disagreement.)

One of the great advantages of HTML is that it can call on external resources. Your index.html can load a style.css and display a picture.jpg. But… it doesn’t have to use external resources.

(I know this isn’t news to some of you – but everyone has to start somewhere.)

Here are three techniques for inlining external assets.

Easy Mode

The normal way of adding a stylesheet to HTML is something like:

<link rel="stylesheet" type="text/css" href="whatever.css">

That loads an external resource. You don’t have to do it like that though. Inside your HTML document, you can write:

<style type="text/css">
body {
   background-color:#f00;
}
</style>

Similarly, for JavaScript, the normal mode of writing is:

<script src="whatever.js"></script>  

But, again, you can inline all your JavaScript:

<script>
   alert("hi!");
</script>  

Easy-peasy! Let’s go for something a bit more difficult.

Hard Mode

Let’s say we want to include a fancy webfont in our page. Normally, our CSS would contain something like this:

@font-face {
    font-family: 'whatever';
    src: url('whatever.woff2') format('woff2');
}

But URLs can be Base64 Encoded. This is a clever way of turning binary data into something suitable for including inline in a text file. This means, rather than calling an external URl for the font, we can place the entire contents of the font file inside the HTML file. Like this:

@font-face {
    font-family: 'whatever';
    src: url(data:application/font-woff2;charset=utf-8;base64,d09GMgABAAAAACdkABIAAAAAVNAAACcBAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP0ZGVE0cGh4bjDwcIAZgAINaCBoJhGURCAr9CPFrC4IEAAE2AiQDhAQEIAWHYgeDUgx+G/FMBcd1twORKPRvOypqglyVHhzXYeMgQM/HZP...==) format('woff2');
}

The same is true with every external resource you might want to use. For example, here’s what a normal image looks like in HTML:

<img src="whatever.gif" alt="Animation of a cute kitten yawning." />

And here it is, inlined with Base64:

<img src="data:image/gif;base64,R0l....." alt="Animation of a cute kitten yawning." />

The entire image file – every single byte – is converted into Base64 and written inside the HTML document. The browser doesn’t load it from an external file. If your Internet connection disappears, you can still load the image.

Magic! OK, let’s go one step further…

Extreme Mode

How about if we take all of our external resources and compress them into a single .zip file. And then inline that file into an HTML document. And then use JavaScript to extract that compressed file to render directly in the browser.

Sounds ridiculous, but it is possible!

SingleFileZ is a library which does just that. Visit the demo site and save the page. You’ll get a single HTML file. Disconnect from the Internet and open the HTML file. It will automatically display as per normal. If you’re feeling adverturous, rename the .html file to .zip and you’ll be able to unzip it.

Downloading it

If you’re in control of your server, or you can set the HTTP headers, it’s possible to set the Content Disposition to tell the browser to download and save a file rather than rendering it in the browser:

Content-Disposition: attachment; filename="whatever.html"

If not, you can use the HTML5 Download attribute in your markup:

<a href="whatever.html" download="whatever.html">Download the file</a>

Try it now!

What have we learned today

It’s possible to create a single, self-contained HTML file which contains CSS, JS, Fonts, Images, and anything else you would normally load externally.



Source link