Why and how to build a website without JavaScript

When I had just little experience with coding websites the thing I liked most was building fancy things using JavaScript. Building kick-ass animations but also changing or even manipulating the DOM (Document Object Model) to change the behaviour of my website. When a school teacher viewed one of my project I got the feedback that my website was not working well without JavaScript and was blocking my users from things like navigating through the website. From this day on I decided to always test my website having JavaScript disabled.

According to Blockmetry in the fourth quarter of 2016 0.2% of the page views from worldwide traffic across all devices in the fourth quarter of 2016 had JavaScript disabled. They measured this looking for the <noscript> tag and filtering out non-human traffic (bots).

You might argue that 0.2% is not that much, and that it takes to much time to adjust your existing projects. Don’t forget that 0.2% is based on worldwide traffic and that there might be a possibility that you are building a website for a target group that has JavaScript disabled in higher numbers. This means that when you are working on larger projects you should research your users and determine whether it makes sense to optimise your website to fully work without JavaScript. As said updating existing projects is time consuming, but when you are building projects from scratch it’s a good thing to do this from the start. Make it a pattern to code with this topic in mind so that it doesn’t take extra time.

Now let’s get into a bit of coding and testing to actually learn how to build websites that do not require JavaScript.

Disabling JavaScript for testing purposes

It’s a good habit to test all your projects having JavaScript disabled. Most browsers allow you to disable this in the developer console.

On Mac you can open Google Chrome’s DevTools using Option-Cmd-I. Go to settings by clicking the three vertically aligned circles and on the right side, check the checkbox where it says ‘Disable JavaScript’.

If you are using a different type of computer and/or browser, please search the internet on how to open the developer console. Also make sure they support the option to disable JavaScript. Otherwise use Google Chrome.

A navigation with and without JavaScript

A bad habit that I used to have is toggling my navigation using JavaScript. Users who were visiting my website on the mobile with JavaScript disabled could not use the menu.

var menu = {
icon: document.querySelectorAll(‘img’)[0],
list: document.querySelectorAll(‘ul’)[0]
};
if(menu.icon) {
menu.icon.addEventListener(‘click’, toggleMenu);
}
function toggleMenu() {
if(menu.list.classList.contains(‘hide’)) {
menu.list.classList.remove(‘hide’);
} else {
menu.list.classList.add(‘hide’);
}
}

If you want to know how the HTML and CSS looks, please view the Codepen example below.

Example: https://codepen.io/HomoDeus/pen/owVZva

Say hello to Mr. Label and Mrs. Input.

Let’s remove all the JavaScript and replace it with around 10 lines of CSS and two HTML elements, the label and input.

Writing clean code feels good, so let’s remove the .hide class from the nav element.

Add an input element with an id. I named it toggleMenu, because we want our navigation to toggle. Wrap a label around the img element and set the for attribute equal to the id of the element. This allows us to trigger the input element when clicking the label.

<header>
<a href='/'>Logo</a>
<label for='toggleMenu'>
<img src='' alt='menu' />
</label>
</header>
<input id='toggleMenu' type='checkbox' />

<nav>
<ul>
<li><a href='/'>Home</a></li>
<li><a href='/'>Products</a></li>
<li><a href='/'>About</a></li>
<li><a href='/'>Contact</a></li>
</ul>
</nav>

Whenever the label is triggering the input field we will display the <nav> element.

nav, input {
display: none;
}
input:checked + nav {
display: block;
}

We hide the input element. Because we don’t need it visually.

input {
position: absolute;
left: -9999em;
}

Example: https://codepen.io/HomoDeus/pen/BZbWZK

Sometimes we can’t ignore JavaScript

We use JavaScript to change the behaviour of a website. We have the freedom to change the behaviour as we want, which means that we can sometimes change the behaviour in a way that makes the website less accessible. My principle is that we may only use JavaScript to enhance things, meaning that everything should work without JavaScript but could make it more pretty using it.

The right user feedback

Whenever your website relies on JavaScript. Let’s say you build something with sockets to send real-time data to multiple users. We want to make sure that we give users that do not have JavaScript enabled the right feedback. In the screenshot below I wanted to let followers of a certain user receive a message after clicking the share button in real-time. Without JavaScript this does not work. The good thing is that the user was able to share a house with other users and that the real-time message was just to enhance the share feature.

Using socket.io to send data from the client to the server

But what if you have a core feature that requires you to have JavaScript? This is where the <noscript> tag comes in handy. This element allows you to show something if JavaScript is turned off in the browser. You can also add HTML and use CSS within this element.

<main>
<noscript>
<p>
You have JavaScript disabled. Your experience might be affected.
</p>
</noscript>
</main>

To show how this works I builded an example. However Codepen does not work with JavaScript. What a coincidence. You can copy the code in the example below and see for yourself. Don’t forget to turn off JavaScript :)

Example: https://codepen.io/HomoDeus/pen/zzbwGX

Make things fancy

So I can not use JavaScript anymore? Of course you can. But only to enhance things. JavaScript should not be used to change the default behaviour of a component like in the navigation example.

A powerful methodology as Sam Dwyer describes is progressive enhancement. It allows web developers to concentrate on building accessible websites. The principle is that you start building a rock-solid foundation and then adding enhancements to it if you know certain visiting-user agents can handle the improved experience.

I like to build my websites first placing all the content and place it within the correct HTML. If you don’t have content yet use dummy content. Don’t use Lorem Ipsum but real looking data.

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Clothes Shop</title>
</head>
<body>
<h1>Baby clothes</h1>
<p>For new born up to a year old</p>
<ul>
<li>
<span>Bluesky Shoes</span>
<img src='/img/bluesky.jpg' alt='Blue with white clouds'>
<span>€19.99</span>
<button>Buy</button>
</li>
<li>
<span>Red T-Shirt</span>
<img src='/img/bluesky.jpg' alt='Red with white dots'>
<span>€15.99</span>
<button>Buy</button>
</li>
</ul>
</body>
</html>

This doesn’t look so nice yet, so the next step is to add the CSS. We will use a mobile-first approach.

body {
font: 100%/1.1 'Open Sans', Arial, sans-serif;
margin: 0;
}
main {
padding: 2em 0.5em;
}
h1 {
font-size: 1.5em;
line-height: 1.5;
margin: 0 0.5em 0 0;
}
p {
margin: 0 0 2em; 0;
}
ul {
display: flex;
list-style: none;
margin: 0;
padding-left: 0;
}
@media screen and (min-width: 60em) {
li {
width: 50%;
}
}
li span:first-child {
font-weight: bold;
}
button {
background-color: DeepSkyBlue;
border: 1px DeepSkyBlue solid;
border-radius: 4px;
color: white;
display: block;
font-size: inherit;
padding: 0.5em 2em;
}
img {
width: 100%;
}

After having tested the website and we are sure that everything works accordingly let’s enhance the website with some JavaScript.

var buttons = document.querySelectorAll('button');
buttons.forEach(function(el) {
el.addEventListener('click', changePosition);
});
function changePosition() {
this.style.marginLeft = '10px';
}

Of course this is not a full working website but it’s pure to give you an idea of a working website using the JavaScript to enhance things.

A short summary

Websites should work without JavaScript. New projects should be build using the Progressive Enhancement methodology so that JavaScript can be used as an enhancement and you are sure your website works having it turned off. Developers should keep this in mind and change their coding style in a way that is not more time consuming and beneficial to both the user, client and their boss. And if you can convince your clients to improve existing projects to give their users a better browsing experience, that would be awesome.

Sources