Category Archives: HTML

Base64 encoding

Base64 encoding is used when embedding binary in text based formats such as JSON, XML, YML etc. in such cases if we need to add a binary type, such as images or files etc. and we must pass then via a text format, then we need to Base64 encode this type of data first.

Use cases

Within web applications this is often used to pass binary within a JSON request/response object, but can be also seen when embedding images directly into HTML, for example

<img src="data:image/png;base64,your-binary-encoded-data..." />

It’s also used for Email attachments (MIME) as well as Authentication tokens – JWT tokens often use Base64URL (a variant of Base64).

Other use cases include clipboard copy/pasting of blobs (images/files etc.) into a text based clipboard format as well as being used from transporting over text only channels.

Where and why not to use Base64 encoding?

Base64 should NOT be used for streaming raw binary (application/octet-stream), large files or in binary safe protocols such as gRPC, websockets and HTTP when using the aforementioned large binary data etc.

First off, these protocols already support raw binary data so the affects of encoding are only on the negative side – if we encode to Base64 we will see, potentially, significant increases in the data size…

To Base54 encode using Javascript in the browser we can use

// encode 
const text = "Hello, world!";
const encoded = btoa(text);

// decode
const decoded = atob(encoded); 

In C# we can use

// encode
byte[] bytes = Encoding.UTF8.GetBytes("Hello, world!");
string base64 = Convert.ToBase64String(bytes);

// decode
byte[] decodedBytes = Convert.FromBase64String(base64);
string decoded = Encoding.UTF8.GetString(decodedBytes);

Calculating the Base64 encoding affects

Base64 encoding encodes every 3 bytes of binary data in 4 ASCII characters, so we essentially expand a binary data payload when using Base64 encoding

var base64Size = (binarySize/3) * 4

Or we can approximate with

var base64Size = 1.33 * binarySize;

Plus up to 2 padding characters “=” if the binary size is not divisible by 3.

This means that for every 1MB (1048576 bytes) the Base64 size is about 1.4MB (1398104 chars) giving us a 33% overhead.

This ofcourse is significant in streaming of data as it adds to the bandwidth and memory overhead along with increases in CPU usage for the encoding/decoding.

Light and Dark theme favicon’s

Nowadays we’d like to support light and dark themes, whether it be due to the OS settings or browser, for example we can switch from lights to dark mode using Chrome’s Settings | Appearance | Mode (chrome://settings/appearance)

So let’s see how we can show different icons in our index.html based upon the selected theme.

<link rel="icon" href="/favicon.ico" type="image/x-icon" sizes="16x16" />
<link rel="icon" href="/favicon-light.svg" type="image/svg+xml" media="(prefers-color-scheme: light)" sizes="16x16">
<link rel="icon" href="/favicon-dark.svg" type="image/svg+xml" media="(prefers-color-scheme: dark)" sizes="16x16">

The first line is a fallback icon for a browser not supporting themes etc. and, as you can see the prefers-color-scheme is used to determine which icon to use.

What’s the purpose of the lang attribute in HTML ?

When creating an an HTML document, we would include the lang attribute to specify the language of the content within the document.

This allows browsers, screen readers etc. to correctly interpret and present content and allows screen readers to pronounce words in the style of the language selected. So for example we’d have

<!DOCTYPE html>
<html lang="en">
  <!-- content -->
</html>

Note that we use the short form language, i.e. “en” or long form such as “en-GB” or “en-US”

Obviously this would need to be changed if your application support i18n, so we might use something like the following, if we’re using something like the i18n package for React

document.documentElement.lang = i18n.language;

// OR

document.documentElement.lang = i18n.resolvedLanguage;

If you do not set the lang or set it to an empty string this simply means the language is unknown.

Whilst this post talks about the html tag, you can actually set the lang on other elements, such as paragraphs p so on a per element basis.

Simple node based HTTP server

In a previous post we used webpack to run an HTTP server, in this post we’re going to create a bare bones HTTP server using the http package.

In your chosen folder run the usual commands

  • yarn init y
  • tsc –init
  • Add a folder named public off of the folder you source will be in (this will be where we add static html files)

Now lets’ add the required packages

  • yarn add node-static @types/node-static

Add the following to the package.json

"scripts": {
  "start": "node server.js",
  "build": "tsc"
}

In the public folder add index.html with the following

<html>
  <head></head>
  <body>
  Hello World
  </body>
</html>

Now let’s add the code to start up our server (mine’s in the file server.ts)

import ns from "node-static";
import http from "http"

const file = new ns.Server("./public");

http.createServer((request, response) => {
    request.addListener("end", () => {
        file.serve(request, response);
    })
    .resume()
})
.listen(4000);

Simple run yarn build then yarn start and the server will start. Navigating your preferred browser to http://localhost:4000/ will then display the HTML file, i.e. Hello World text.

Storing extra data within your HTML elements using data-* attributes

I came across a simple problem, I have an array of objects in React with a name (something to display to the user) and an expression tree (which makes up a query associated with the name).

What I wanted to do is that when a name is selected in a material-ui Select component, that it then passes the name and the expression data to a handler.

Ofcourse there are several ways to achieve this but this is a really simply solution. We create an array of MenuItem‘s for the Select and we store the expression tree along with the MenuItem

If you take a look at Using data attributes you’ll see that HTML5 has a way of adding attributes to an element using the data-* syntax.

The name of the attribute to be added simply starts with data-, for example data-expression and now when the Select onChange event is handled, we can get at, not only the value selected but also the data attribute value.

Here’s an example of us setting up a MenuItem

return [{name: "None", expression: undefined}]
  .concat(publicQueries).map(e => {
    return <MenuItem key={e.name} 
      value={e.name} 
      data-expression={e.expression}>{e.name}</MenuItem>
});

Notice that we simply declare the data-expression and assign some data to it. Nothing special here.

Now within the onChange handler of the Select component we might have a handler like this

handleOnChange(e: any, child?: any) {
   const selecteNamed = e.target.value;
   const selectedExpression = child.props['data-expression'];
   // do something useful with these
}