The Web Standards Model

Coding explainers for web design students

Part 1 Don't break the web

This article introduces some of the core concepts of contemporary web design and the language used to describe them. It's intended to provide an overview of the web development process and introduces a framework within which we can develop our understanding of HyperText Markup Language (HTML), Cascading Style Sheets (CSS), JavaScript, and how these three technologies work together.

Reading time: 15 minutes


Many people believe that to code successful webpages, the designer/developer needs only an understanding of HTML, CSS, and JavaScript, and that this understanding can be gained simply by watching YouTube videos. Others believe that even the details of the three technologies are not so important and that webpages can be built by employing ready-made templates. Neither of these approaches is likely to result in an optimal outcome for designer, client, or user.

The best webpages are produced when the designer/developer has a good understanding of the core principles and the underlying philosophy of web design. Such issues are rarely discussed on YouTube and are not evident in ready-made templates.

The clearest and most powerful principle of web design is the Web Standards Model. Not only does it provide a framework for how HTML, CSS and JavaScript should work together, but it provides the foundation for a philosophy that includes other core principles such as progressive enhancement.

What are web standards?

The three technologies with which webpages are built are constantly evolving. For the most part, these changes are designed to make it easier to build webpages and to allow designers and developers to build richer experiences for their users.

To ensure that all developers use HTML, CSS, and JavaScript in the same way, and to ensure that all browsers render the results consistently, each technology has a specification that explains how it should be written and implemented. When a developer builds a webpage in such a way that the technologies conform to the published specification, that webpage can be said to be “conformant”. Conformant webpages can be easily understood by any other developer and will render consistently in any browser. Moreover, webpages developed in such a way will remain backwards-compatible as new standards are introduced.

Who creates web standards?

Web Standards are created and maintained by standards bodies. There are several of them and they work closely together to ensure all technologies remain interoperable. The W3C is probably the best known of the standards bodies. The W3C developed the original standards for HTML and CSS. Currently, the HTML standard is developed by the WHATWG in collaboration with the W3C. The CSS standard is developed solely by the W3C. ECMAScript, the core specification for JavaScript, is developed by the ECMA.

Web standards are “open”

One of the beautiful things about web technologies is their open nature. They are not owned by anyone and there are no licencing issues when using them — anyone can use them at any time in any context. Similarly, the standards bodies are open organisations, who invite other interested organisations and individuals to come together and decide how technologies should work and how they should evolve. Web standards are democratic and develop by consensus.

A philosophy

Individually, the specifications developed by WHATWG, W3C, and ECMA help us to understand how the code that forms each of the three technology layers should be written. Standards bodies may also recommend how they should be implemented. For example, The W3C Web Accessibility Initiative (WAI) recommend how headings should be used in HTML. What they don't tend to do is explain how the three technologies should work together. The Web Standards Model fills that gap by describing the relationship between the layers.

The Web Standards Model is a conceptual framework which starts by identifying the purpose of each of the three layers and by giving them a name based on that purpose. HTML forms the Structure layer, CSS forms the Presentation layer, and JavaScript forms the Behaviour layer. HTML adds structure to our content, CSS controls how our content will look (presentation), and JavaScript is used to control the behaviour of our content.

The web standards model Content Text, images, ... Structure HTML Presentation CSS Behaviour JavaScript

The naming of the layers is important because it defines not only the purpose of each layer, but it asserts the exclusivity of that layer's purpose. For example, CSS is referred to as the presentation layer because that is its function (to control the way content looks), but it also implies that neither HTML nor JavaScript should ever be used for that same purpose.

Presentational markup

Before the introduction of CSS in 1996, HTML was also used to control the presentation of content and because of the backwards compatibility of the web, it still can. However, this approach is now considered bad practice and “presentational markup” is non-conformant because it is not supported by current web standards. For example, presentational HTML elements such as <font> are described as “obsolete” because they do not form part of the current specification and should not be used. However, for backwards compatibility, most browsers will still support the font element. It is therefore most commonly referred to as “deprecated” rather than obsolete. Deprecated means that its use is strongly discouraged, even if it still works. There is no guarantee that browsers will continue to support it in the future, so it should not be used for new web projects, and it should be removed from old websites.

Presentational markup is also “non-semantic”. In other words, it imparts no meaning to our content. Since the purpose of HTML is to give structure and meaning to content, elements that are purely presentational have no place in the current specification. You should use an HTML elements reference to check which elements are part of the current specification and may therefore be used to build modern websites.

There is no doubt that the history of HTML makes it difficult for those new to web design to easily understand what is conformant, according to the current specification, and what is deprecated but still supported by browsers. Fortunately, you can check to see whether your HTML is conformant or not by using the W3C Markup Validation Service. This service will highlight any errors in your markup and explain why the error has occurred.

A separation of layers

The core principle of the Web Standards Model is that we keep the three layers separate. In practice, this is done by ensuring that each of the technologies is contained within its own file. Typically, HTML will be written to a file called index.html, CSS to a file called style.css, and JavaScript to a file called script.js. The final rendered version of our webpage appears when the browser loads all three files — three separate layers coming together to form a single, coherent document. The actual filenames may vary but the core principle of separation should always be observed.

We must always guard against the possibility of poor implementation. It is perfectly possible to mix the three technologies. We can write CSS inline with our HTML and we can even write JavaScript inline with HTML. We could have all three layers written to a single HTML file, and if we did that, our webpage would work perfectly well and would be conformant with the specifications. But simply making things work is not enough, we need to ensure that our implementation is as good as it can be, not for its own sake, but because it will help others to experience our web content more easily. Our web documents will be more inclusive for our users and more manageable for us and our colleagues if we maintain a clear separation of the layers.

Keeping things modular

The web is a hostile environment, and there are many reasons why one or more of the technology layers might fail. A temporary break in wi-fi or phone signal may prevent a CSS file from loading. A link to the file may be broken or browser caching may cause an old version of the file to be loaded. There may even be a problem on the web server, causing files not to be served correctly.

You may be tempted to wonder why, if the process is so fragile, we don't just bring all the layers together into a single file. That way the user would get to see all or nothing. The problem with this approach is that it requires all our CSS and all our JavaScript to be written to each and every HTML file. In addition to the points made above, this would result in two key problems, performance and management.

Performance: The size of our website will increase significantly, causing the user to download more data for every page viewed after the first one. The result is that our website becomes slower, with pages taking longer to load. When we keep our layers separate, browsers will cache CSS and JS files so that they are not downloaded for every HTML file that requires them, resulting in better performance for the user. Binding the three technology layers together in a single file would result in a poorer user experience. Additionally, larger file sizes are not good for the planet because more energy is required to store, transfer and display them. Web developers and designers should aim to provide the best possible user experience and be advocates for sustainability.

Management: Developing websites is a complex undertaking and the more we can do to avoid repetition the better. Repetition is a problem because it usually means that every time we want to update the visual styling of an element, every instance of the CSS rule that controls the style of that element would need to be updated. In such cases, consistency becomes a major consideration. Say we have a website with 300 or perhaps 3,000 pages and we want to modify the styling of the <h1> element on each page. We would need to edit every HTML file in our website (all 3,000 of them). By separating out the presentation and writing our CSS to its own file, we create a modular solution. The benefit is that the changes we want to make can be achieved by editing a single file, irrespective of how many pages we have.

The web is not a free-for-all

There are many ways in which code can be poorly implemented and still work but, as we have already pointed out, it is not sufficient simply to make things work. The building of good webpages requires a deep understanding of contemporary best practice, and that usually means knowing the accepted approaches, the core principles, and adhering to an underlying philosophy. Developing an appreciation for web standards and adopting the Web Standards Model as a framework is the first step in the process of building excellent webpages that do not break the web.

Progressive enhancement

We can consider each layer of the web standards model to be an enhancement on the one before it. The structure layer enhances our content with HTML (adding structure and meaning), the presentation layer enhances the content further with CSS, and so on. We refer to this process as “progressive enhancement”. With each additional layer, we provide a richer experience for the user. Conversely, if layers are removed, one by one, we can say that the experience goes through a process called “graceful degradation”. Graceful because we allow our layers to fail without denying our users access to the core content, and degradation because, with the removal of each layer, the richness of experience is degraded. For example, if JavaScript fails, we may lose some bells and whistles, but the document retains its visual design. If CSS also fails, we still see the content styled using the browser default. Adhering to the principles of progressive enhancement is the best way to build resilient websites that work for all users.

Browser support

A further reason for adopting a progressive enhancement mindset is that it allows developers to implement new features in CSS and JavaScript, even if browser support is still patchy. The principle here is that users with a browser that supports a new feature will get an enhanced experience, but those who don't will get the standard experience and are not negatively impacted. This principle is sometimes referred to as “cutting the mustard”. If a user's browser cuts the mustard, the user will get an enhanced experience, and if not, the design gracefully degrades.

Shouldn't all users get the same experience?

Over time, the principles of web design evolve. It used to be thought that websites should look the same in all browsers. Today we take a more pragmatic view. Providing that all users have access to the same core content (a principle we refer to as “one web”), it doesn't matter so much if the presentation varies a little depending on the browser they are using. In any case, with responsive web design, it is unlikely that a webpage will look the same on a phone, a tablet, and a desktop monitor. The idea that websites should look the same in all contexts makes little sense. So, we can emphatically answer the question, “do websites need to look exactly the same in every browser?” with a little help from designer Dan Cederholm.

The front-end

The three technologies we've been discussing in this article, HTML, CSS, and JavaScript, are referred to as “front-end” technologies because they all work in the browser (considered to be the front-end of the web). We use this term to differentiate them from technologies used on the server, which are referred to as “back-end” technologies. In most cases, the user's experience of a website results from a series of transactions between the front-end and the back-end (the browser and the web server). For example, the browser will make a request to the server for a file; in response, the server sends the requested file to the browser. Completed webpages are the result of many such transactions.

Other words and phrases may also be used to describe this process. Browsers are sometimes referred to as “clients”, and our three front-end technologies described as “client-side” technologies (as opposed to “server-side” technologies). The word “client” is used to refer to the relationship that the browser has with the server. The browser acts as a client, making requests with the server responding to those requests.

Browsers may also be referred to as “user agents”. This is a generic term used to describe any software application that interprets web content sent across the internet and which makes that content accessible to the user. In the case of a browser, the content is received in the form of HTML, CSS, and JavaScript. The browser then uses the instructions contained in the files received from the server and renders the content so that it can be visually interpreted by the user.

FYI:A front-end developer is someone who builds the part of a website that works in the browser. Their main focus is on the use of HTML, CSS and JavaScript, but the role includes many other responsibilities.

This is for everyone

Some people may use additional or alternate user agents. For example, a blind or partially sighted person may use a screen reader. This is a software application that reads web content to the user. Such applications are referred to as “assistive technologies“. However, they are entirely reliant upon web developers using conformant code and marking up content so that the structure of a document is logical and consistent, and that the semantics of the content are accurate. Best practice coding, especially of HTML, is the foundation of accessibility (sometimes abbreviated to A11y). Good code makes our content available to everyone, irrespective of their circumstance. This is the reason why everything we have discussed so far is crucial in contemporary web practice. As responsible web designers and developers, we should all share Tim Berners-Lee's vision that “this is for everyone“.

It wasn't always this way

Today, all professional web developers and designers understand the importance of web standards. Contemporary websites are built to be conformant with standards and in accordance with agreed principles. But this wasn't always the case and, in the past, web standards was a controversial issue.

Early in web history (from the mid-1990's), some commercial organisations thought it would be a good idea to add their own proprietary elements to HTML. These elements would only be recognised in their own browser. This period of web history became known as the browser wars as browser vendors competed for dominance. As you might imagine, this caused problems for developers. With several variations of HTML on offer, which one should be used for a given project?

Clearly, the situation was not sustainable and unchecked, would have led to a web of chaos. On 1st October 1994, Tim Berners-Lee formed the World Wide Web Consortium (W3C) in an attempt to foster collaboration and agreement within the industry and to set out the specification for a definitive version of HTML. Progress was slow because commercial organisations could see the potential of the web and wanted to control it for their own benefit.

 Designing with Web Standards, first edition
Figure 1.1

In 1998, the Web Standards Project (WaSP) was formed by George Olsen and others. Its remit was to campaign for web standards and to persuade browser developers to support the standards being set by the W3C. One of WaSP's co-founders was Jeffrey Zeldman, who's 2003 book, Designing with Web Standards became a best seller. It was subsequently updated in a second (2007) and third (2009) edition and probably did more than any other initiative to raise awareness of web standards. This book became a major influence on web developers and consequently on their employers and clients.

By the early 2000's, the web standards argument was largely won, with industry partners agreeing to cease proprietary development and to collaborate with the W3C (and subsequently with WHATWG) on a single, standard version of HTML and other technologies. On 1st March 2013, the Web Standards Project was disbanded with a blog post by Aaron Gustafson entitled “Our Work Here is Done”. It had taken almost 20 years of discussion, argument, and persuasion, but eventually, web standards became the accepted way forward for all involved with the process of web development.

Top of document

Part 2 A practical demonstration

As a practical demonstration of the Web Standards Model, we are going to build a simple page component that adds the three technology layers, HTML, CSS, and JavaScript to some content which, in this case, is just a few lines of text. We're keeping things simple so we can focus on the fundamentals of the development process.

Reading time: 30 minutes

Essentially, building websites is a 4-step process. The first step is to prepare the content. The second is to mark up that content with HTML, adding structure and meaning. The third step is to use CSS rules to describe how the marked-up content should be presented. The fourth step is to add any behaviours using JavaScript — in our example, the content will be styled differently depending on the day of the week. We will work with HTML, CSS and JavaScript to build what, in Brad Frost's Atomic Design Methodology, is called an organism (built from atoms and molecules). Our organism (shown here) will be fault-tollerant and built using current best practice techniques.

Opening times

9:00am to 5:00pm
9:00am to 5:00pm
9:00am to 5:00pm
9:00am to 5:00pm
9:00am to 8:00pm
8:00am to 6:00pm

This organism is a list of opening times for a shop. It has several features, each implemented by a different layer of the web standards model. The structure layer is used to identify which items of text form the heading, which are the names of the days of the week (terms), and which are the opening times (data). When the structure layer is added to our content, the organism will have structure, and the content will have meaning.

The presentation layer is used to arrange and style the various text elements so that they are more easily readable. Remember, Web Design is 95% Typography, so typographic design is a primary aspect of web design. In most cases, we'll begin our design of content by considering typeface, line height, use of white space, etc.

There is also a hover effect — the organism appears to move towards the user when the mouse cursor is over it or when it is tapped on a mobile device. This is done to provide some emphasis/focus to the organism and to add an element of fun/engagement. The design of this action uses Google's Material Design principles. I am using a hover effect here to demonstrate a particular point. However, most users will associate hover effects with clickable links, so they should be used with caution.

The behaviour layer is used to add a CSS class to the HTML elements that display today's opening times. This will cause them to be styled differently from the elements for the other days in the list. This has the benefit of highlighting the most relevant information for the user. They don't need to know what day it is today — we're not making the user think! Our organism is doing the thinking for them.

Let's work through that process, one step at a time…

Tip:If you're new to web design, you may not be familiar with all the details of the code in the following sections. If that's the case, don't worry. The most important thing is that you develop an understanding of the broad principles.


Content comes in many forms, but most commonly it will be text. Even richer content types like images and videos will provide a text alternative for fault tolerance and for accessibility.

Content All web design projects begin with the production of content. The content itself is carefully designed for web users. Text is concise with headings and sub-headings that facilitate “skimming and scanning”. Images are art-directed, sized appropriately and optimised. Video and audio are encoded for use online. Once all content is prepared, the process of design can begin.

Content out

Designing for the web is all about designing content. Without content, there is nothing. The client needs content to convey a message, the designer needs content to effectively communicate that message, and the user is looking for powerful and informative messages that provide a good user experience. The principle of beginning the design process with content is known as “content out” — we start with content and design out from there. Historically, it was thought that designing empty containers that could be filled with content after the design was complete was an acceptable approach. Indeed, some templating systems are still based on this logic. However, in a world of responsive design, using old design analogies for the web doesn't lead to the best outcomes. Current best practice demands a content out approach.

Opening times
Monday 9:00am to 5:00pm
Tuesday 9:00am to 5:00pm
Wednesday 9:00am to 5:00pm
Thursday 9:00am to 5:00pm
Friday 9:00am to 8:00pm
Saturday 8:00am to 6:00pm
Sunday Closed

Code block 2.1

Content order

The core content for our web organism is shown above. It's a simple text file that contains everything we need to begin the process of development and design. Notice that the order of the lines of text matches the arrangement of text in our finished organism. Content order is an important accessibility consideration because screen readers will always read text content in the order that it appears in the file, irrespective of where it is visually located in the browser window.

A text file displayed in a web browser
Figure 2.1. Our text file (content.txt) displayed in the Firefox browser.

Curiously, if we open this text file in a browser, the content will be displayed as shown here. This is the ultimate fallback. Even if there is no HTML, no CSS and no JavaScript, our browser will still display the raw text and allow the user access to our content.

The structure layer

Let's continue our journey by considering each of the three technology layers in turn. The first layer will provide the structure of the organism. We do this by marking up the content with HTML tags.

Structure Structure is the first layer of enhancement that we apply to our content. The process involves “marking up” content with HTML tags. HTML defines the structure of our document – appropriate heading levels will define the document outline. HTML will also add meaning (semantics) to our content, allowing it to be more easily understood by browsers and bots.

The following code block shows the HTML that describes our opening times organism. Note that all elements are correctly nested, and that the level of nesting is indicated by indentation. We use indentation so that we can clearly see the relationship between elements.

<section id="widget"> <!-- open widget -->
    <h3>Opening times</h3>
        <dd>9:00am to 5:00pm</dd>
        <dd>9:00am to 5:00pm</dd>
        <dd>9:00am to 5:00pm</dd>
        <dd>9:00am to 5:00pm</dd>
        <dd>9:00am to 8:00pm</dd>
        <dd>8:00am to 6:00pm</dd>
</section> <!-- close widget -->

Code block 2.2

The HTML is quite simple, consisting of a <section> element, containing a heading and a description list (sometimes referred to as a definition list), but despite its apparent simplicity, the HTML is performing two important tasks. It adds structure and meaning to our content.


The core content for our organism is the text in the heading, and a list of the opening times for each day of the week. To this core content, we add the first of our three layers — the structure layer. This layer is applied by adding HTML to our content. The HTML provides structure to our document (hence, “structure” layer), but it also adds meaning to our content. HTML is only ever used to do these two things — it provides structure to our documents and adds meaning to our content.

How does it do this? Well, one of the ways that structure is added to our document is by providing a logical sequence of heading levels so that the document outline is completely consistent. For example, the main (first order) heading will always be marked up as <h1>, while (second order) sub-headings will be marked up as <h2>. Any (third order) sub-sub-headings will be <h3>, and so on. Most documents are unlikely to include heading levels lower than <h3> or perhaps <h4> for complex documents, but HTML allows for heading levels down to <h6>.

The most important point that needs to be emphasised at this stage, is that the various heading levels are not used to determine the way a heading should look (e.g. the size of the text). They are only ever used to create a logical sequence. For example, <h2> may immediately follow <h1>, but <h3> may not because that would introduce an inconsistency to the logic of the document outline (a map of heading levels for a particular document). Have a look at the document outline for this page to get an understanding of the logic used for heading levels in this document.

Notice that at no point do we step down more than one level at a time. The sequence of headings is ordered and logical.

<h1>The Web Standards Model

<h2>Part 1 ▸ Don't break the web


<h3>What are web standards?

<h4>Who creates web standards?

<h4>Web standards are “open”

<h3>A philosophy

<h4>Presentational markup

<h4>A separation of layers

<h4>Keeping things modular

<h4>The web is not a free-for-all

<h3>Progressive enhancement

<h4>Browser support

<h4>Shouldn't all users get the same experience?

<h3>The front-end

<h3>This is for everyone

<h4>It wasn't always this way

<h2>Part 2 ▸ A practical demonstration

<h3>Opening times


<h4>Content out

<h4>Content order

<h3>The structure layer



<h3>The presentation layer

<h4>Separating structure from presentation

<h4>Browser default styling

<h4>Organising the rules

<h3>The behaviour layer

<h4>Separating structure from behaviour

<h4>The script in four parts

<h4>JavaScript modifies the HTML

<h4>Building user experience layer by layer

<h3>Robustness and order

<h3>Further reading

Heading levels are an important aspect of document structure, but they are only part of the overall structure of content. Most documents will be sectioned into various parts. There may be a document header, there will be the main section of the document, and there may be a footer. Some documents may also have a sidebar. Each of these areas of content may be marked up using the appropriate semantic container element so that the structure of the document is clearly defined.

In our HTML, we are using the generic <section> element because the organism forms a discrete sub-section of our document, and HTML does not provide anything more specific. There is no <opening-times> element in the HTML specification. However, we can suggest the purpose of our section by using a heading with appropriately descriptive text (all sections should have a heading). Note that the heading level we are using is <h3>, that's because the level must be consistent with the document outline. Heading levels are set relative to the document, not to the section, so it would be incorrect to mark up our section heading as <h1> unless it was also the main document heading.


The second purpose of HTML is to add meaning to our content. We use the word “semantic“ to describe HTML that correctly conveys the meaning of content. In our example, we have marked up our opening times as a description list, not only because it provides a logical structure (which it does), but because it most accurately describes the relationship between the name of the day and the associated opening times. There is a semantic link between the description term <dt> and the description data <dd>.

We could have marked up our opening times as an ordered list or as an unordered list. There is no doubt that our content is a list of opening times, so it should be marked up as a list of some sort (because that's what it is). Beyond that, we have a choice. HTML provides three different list types. The question, therefore, is which list is most semantically accurate?

As we have already suggested, the description list is designed to mark up name-value groups. In our example, the name of the day is our name or term, and that is marked up as a description term <dt>. The associated opening times for that day are the description data and so we mark up that text as <dd>. No other list type provides a similar structure, so we can be sure that we are using the most structurally and semantically accurate way of marking up our content. The semantics of the description list ensure that assistive technologies can easily understand the relationship between the description term and the description data — one is intrinsically linked with the other.

Although our example is more complex, it is the same simple logic that says we should mark up a paragraph using the <p> element. Any text between opening and closing paragraph tags is not just text, it is a paragraph. We are effectively declaring that the text forms a paragraph and in doing so, we have added semantics to our content. Before markup, the content was just text, but now it's a paragraph.

It's important to realise that HTML and the other technologies are constantly evolving and contemporary best practice changes rapidly. You're likely to come across HTML that was written years ago which may have been considered good practice at the time, but which is now out-of-date. For example, you may see this…

<div class="navigation">navigation goes here</div>

Code block 2.3

…which was typical of HTML written before 2014. Today, we'd mark up our navigation like this…

<nav>navigation goes here</nav>

Code block 2.4

The key difference here is that the first example provides no meaning to the user agent. A <div> is a simple, non-semantic container. Adding a class attribute with a sensible name that describes the content does not add any meaning to the element — it is still a non-semantic container.

The second example is a semantic container, and its meaning is understood by all user agents. A browser will recognise this as being a container for navigation and is therefore able to convey that meaning to the user.

The <nav> element, along with other semantic container elements such as <header>, <main> and <footer> were introduced with HTML5. As a result, the <div> element is used much less frequently than it was because we now have better, more meanigful ways to mark up our content. It has also been suggested that we should no longer be using classes.

One of the most important reasons why we should always aim to use HTML to provide good document structure and content semantics is that it makes our documents more accessible to people using assistive technologies (e.g. screen readers) and to non-human user agents (e.g. search engine bots).

On the face of it, HTML may seem quite simple, but it takes time, effort, and experience to know how best to mark up content. This is the reason why HTML generated by software such as page builders is often so poor.

FYI:HTML5 was released as a “recommended” specification for marking up webpage content by the W3C on 28th October 2014. One of the most notable features of that release was the introduction of new semantic container elements.

To complete our HTML file, we need to add some additional HTML to ensure our document is “well formed”. This involves adding a doctype, head and body sections etc. Take a look at the source code for our example organism to get an idea of what a complete HTML file looks like.

Marked up content displayed in a browser with default styling
Figure 2.2. The HTML file (index.html) in our browser, with default styling.

Once we have completed the marking up of our content and are satisfied that we have been able to apply a logical structure to the document and have provided appropriate meaning to the content, we can consider the first layer of the Web Standards Model to be complete. When viewed in the browser, our page will be styled using the browser's own default styling. Clearly, we'll want to improve on that but to do so we need to move to the second layer.

The presentation layer

The second technology layer is CSS. This will provide the “look-and-feel” of our organism. We do this by declaring rules that describe the way our marked-up content will be styled. CSS is a declarative language. That means we tell the browser what we want, we don't need to tell it how to do it.

Presentation Presentation is the second layer of enhancement. This is done by defining CSS rules that determine how our marked-up content will look in a browser. We begin with typographic design, specifying alignment, spacing and typeface. Our design choices should ensure that content is legible, accessible and provides a good user experience.

Separating structure from presentation

One of the most important characteristics of the web standards model is the separation between the layers — each of the layers is discrete. One of the cornerstones of contemporary approaches to web design is the separation of structure from presentation. In other words, we keep HTML and CSS apart. This leads to a much more manageable and maintainable project, meaning that, for example, we can modify the appearance of hundreds of webpages simply by editing a single CSS file.

The importance of this approach cannot be overemphasised. It is particularly important because historically, structure and presentation were mixed. HTML did both jobs. In our contemporary approach, we refer to markup that describes the way things look as being “presentational markup”, and we consider this to be bad practice. Remember, HTML has just two purposes, to provide structure to our documents and meaning to our content. Presentation is exclusively the purpose of CSS.

Having established the ground rules, we need to understand how it is possible to maintain distance between HTML and CSS and yet allow the browser to see both. In practice, this is quite simple.

   <meta charset="utf-8">
   <title>Opening times | Coding Explainers</title>
   <link rel="stylesheet" href="style.css"> <!-- link to CSS -->

Code block 2.5

We will link to our CSS from our HTML file simply by adding a <link> element to the head section, as shown above. That way, our HTML remains pure in a file, usually called index.html and our CSS also remains pure in a file, usually called style.css. Filenames may vary but the principle remains good — we have maintained a separation of our structure and presentation by storing each of the technology layers in separate files.

The link element has two attributes. The rel attribute defines the relationship of the linked document to our HTML file — in this case, it's a stylesheet. The href attribute specifies the URL of the linked file.

Once we have linked to the CSS file, any rules we add to that file will be used by the browser to style the marked-up content in our HTML file.

Browser default styling

When we have marked up our content correctly with HTML, it will be automatically styled by the browser according to the markup we have used. For example, the heading is displayed in bold type, and the description list is displayed so that the description data is indented.

Browser default styling can be convenient for checking the accessibility of our content. We can see, at a glance, that our content order is correct, that our document structure is consistent etc. However, default styling can be confusing for beginners because it gives the impression that we have caused our content to be styled, simply by marking it up with HTML. We must remember that HTML is not used for presentation, that is a job for CSS. For that reason, to mitigate against the fact that different browsers may use different defaults, and because default styles may conflict with our own styles, we always apply a CSS reset. The reset is used to remove any default styling added by the browser. Commonly we will use the Meyer Reset before proceeding with our own styling, but there are other approaches.

Marked up contend displayed in a browser after a CSS reset has been applied
Figure 2.3. HTML in our browser with default styling removed.

Once we have applied our browser reset we are ready to proceed with our design by applying our own styles. You'll notice that our content, as displayed in the browser, is now more difficult to read because all white space and visual hierarchy has been removed. However, the reset gives us a blank canvas upon which we can create our own unique design.

We'll usually begin with a rule for <body>. Here's what the body rule looks like for our web organism:

/* == Page styling == */
body {
    font-family: Roboto, Arial, Helvetica, sans-serif;
    font-weight: 300;
    color: #333;
    background-color: #ddd;

Code block 2.6

A CSS rule is made up of a selector and one or more declarations. Each declaration is formed of a property/value pair. For example, our body rule uses a type selector to select the <body> element. It then uses four declarations to set the value of four CSS properties. Note that the font-family property has several values. This is referred to as a “font stack”. Essentially it is a series of fall-backs. Here we're telling the browser that we prefer our text to be rendered in Roboto, but if that font is not available, it should be rendered in Arial, and so on. The last value is a keyword, in this case sans-serif. This means, if none of the preferred fonts are available, use the default sans-serif font. This approach to font handling is the same fault-tollerant approach used for progressive enhancement.

The HTML file displayed in a web browser after the body rule is added
Figure 2.4. The body rule sets the default font and colour properties for the document.

Organising the rules

Generally speaking, CSS is organised in such a way that global rules come first, and these are followed by more specific rules. In this way, the value of inheritable properties can cascade to elements that are descendants (children, grandchildren etc.) of the ancestor element. So, for example, the parent element for our organism is a <section> with an ID “widget” — it contains all the other elements. This element is styled first so that its child elements will inherit any inheritable property values. We're selecting this parent element using an ID selector by referring to the ID #widget. An ID is a unique identifier, so there is no ambiguity about which element we are selecting.

/* == The organism container == */
#widget {
    background-color: #fff;
    width: 410px;
    padding: 0 0 2.0rem;
    border-radius: 14px;
    margin: 2.0rem auto 0;
    box-shadow: 0 0 14px #666;
    transition-duration: 400ms;

Code block 2.7

Notice that our rule for #widget does not include the font-family property. That's because we don't need to specify it unless we want it to be different from what is used elsewhere in the document. This property is specified for the <body> element of the document. Our organism will inherit the font-family value from <body> because font-family is an inheritable property, and <section> is a descendant of <body>.

The HTML file displayed in a web browser after the #widget rule is added
Figure 2.5. The #widget rule sets the width and positioning for the organism.

After the parent container is styled, the next rule is for the hover state of the same element. We use the :hover pseudo class selector appended to the ID name to select only the hover state of the element.

#widget:hover {
    transform: scale(1.02);
    box-shadow: 0 0 28px #666;
    /* Using Material Design principles
    to make the card appear to move
    towards the viewer rather than
    simply getting bigger */

Code block 2.8

The next rule moves down one level in the hierarchy. We're styling the heading. To select it, we're using a descendent combinator (#widget h3), meaning the <h3> element that is a child of #widget. If there were several <h3> elements within the #widget parent, all instances would obey the rule, but in this example, we have just one.

/* == The organism children == */
#widget h3 {
    font-family: 'Fira Sans Condensed', Arial, Helvetica, sans-serif;
    font-weight: 600;
    font-size: 3.2rem;
    text-align: center;
    background-color: #eee;
    padding: 1.2rem 0;
    border-top-left-radius: 14px;
    border-top-right-radius: 14px;

Code block 2.9

For this element we are specifying a value for font-family and various other typographic properties. That's because we want the <h3> inside our organism to look different from the <h3> elements elsewhere in our document. In other words, we are overriding the global style for <h3> and styling it exactly as we would like to see it in our organism.

The HTML file displayed in a web browser after the h3 rule is added
Figure 2.6. The h3 rule sets the font properties and whitespace for the heading.

Staying at the same level, the next rule is used to style the description list. Again, we're using a descendent combinator to select it, just as we did for <h3>.

#widget dl {
    /* Description list layout with CSS Grid */
    display: grid;
    grid-template-columns: 150px 200px;
    width: 350px;
    font-size: 1.2rem;
    line-height: 2;
    margin: 1.7rem auto 0;

Code block 2.10

We're using CSS Grid to control the arrangement of elements within the description list. It's almost as if the two were made for each other. An overall width is set and then two grid columns that add up to the width value.

The HTML file displayed in a web browser after the dl rule is added
Figure 2.7. The dl rule sets the font properties and arrangement of text.

The next two rules step down another level within the HTML hierarchy. Both the <dt> and <dd> elements are children of the description list (<dl>). We could have selected them by referring to the description list in a descendent combinator (e.g. #widget dl dt and #widget dl dd), but there is no need because those elements will always have <dl> as a parent, so it can be omitted from the selector.

#widget dt, #widget dd {
    padding: 0 0 1px 20px;
    border-bottom: 1px dotted #888;
#widget dt:first-of-type, #widget dd:first-of-type {
    border-top: 1px dotted #888;

Code block 2.11

Using the same logic, we are also setting a rule for the first description term and description data elements, using the :first-of-type pseudo-class selector. All the definition term and definition data elements will have a border at the bottom, but only the first elements will have a border at the top.

Note that, as far as possible, we're keeping all rules for the same element close together in our CSS file. This helps us to see, at a glance, all the style rules relating to a specific element. This will help to avoid any potential confusion when our CSS file becomes more complex.

The HTML file displayed in a web browser after the dt and dd rule is added
Figure 2.8. Our organism with all CSS, displayed in the Firefox browser.

This image shows what our organism looks like when the structure and presentation layers are complete. It also demonstrates what our organism will look like if JavaScript were to fail. You can see that all our content remains visible and is correctly styled. The only thing we don't see is the highlighting of today's opening times, but that could be considered non-essential because all the required information is still available to the user.

The final rule uses the class selector .today. It only does something if JavaScript is available, and class="today" has been dynamically added to the <dt> element for the current day of the week. Effectively, the name for the current day of the week will be highlighted because the .today rule increases the font-weight and darkens the color compared with the inherited property values used by the rest of the text in the list.

We are also able to style the <dd> element that immediately follows the element with the "today" class by using an adjacent sibling combinator to select it. This means we only need to add the class to the <dt> element and then use the power of modern CSS to select the <dd> element. This helps to keep our markup and our script lean.

.today, .today + dd {
    /* This class is added by JavaScript */
    font-weight: 500;
    color: #000;

Code block 2.12

At this stage, we have no JavaScript, so the .today rule does nothing, but it's ready to be called into action when required.

To get a complete picture of what the linked style.css file looks like, see the source code for our web organism.

The behaviour layer

The third technology layer is JavaScript. All webpages will use HTML and CSS, but not all webpages require JavaScript, it should be used sparingly and only where necessary. JavaScript is an imperative language. That means we must provide an explicit sequence of statements that tells the browser what to do.

Behaviour Behaviour is the final enhancement of our content. JavaScript is used to control user interactions and to perform required functions. As this is the most fragile of the enhancement layers, we must ensure that our document remains useable even if JavaScript should fail. Our document should always “degrade gracefully”, leaving content accessible.

Separating structure from behaviour

As with CSS, it is theoretically possible to mix JavaScript with HTML. Scripts can be added to our index.html file and JavaScript can even be written inline with HTML. Neither of these options is desirable, and modern JavaScript allow us to easily separate the behaviour layer from the structure layer. The benefits of doing this with JavaScript are similar to the benefits of separating CSS from HTML — it results in a modular set of assets that can more easily be developed and maintained.

In practice, our JavaScript is usually written to a file called script.js, and this file is then linked from our HTML file in a similar way that of our CSS file. The key difference is in the markup we use to make the link. To make a link to a script file, we use the <script> element. This element has one attribute, the source attribute (src). The attribute value is the URL of the linked file.

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

Code block 2.13

Notice that the link to the script file is made immediately before the closing body tag. The reason for this placement is that it allows the browser time to read the HTML, and build the document object model (DOM) before the script runs. This is important because the script may be used to manipulate the DOM (our script does), and it can only do so effectively if the DOM is complete when the script runs.

The script in four parts

Our script performs a simple task and is in four parts. The first part is a single statement that gets the number of the day of the week and assigns it to a variable called today. Note that we are declaring the today variable using the let keyword. That's because the value of today will change later in the same block of code.

// get the day number from a new date object
// assign to a variable
let today = new Date().getDay();

Code block 2.14

The second part is an if/else clause that converts the number of the day so that it is consistent with the order of the days of the week in our description list, and the node lists we will create in part three. Effectively, we are converting the number of the day of the week into the corresponding node list index.

// Sunday is the first JavaScript day but it's
// the last day in our list so change 0 to 6
// and decrement all other day numbers so they
// match with the node list indexes
if (today === 0){
    today = 6;

Code block 2.15

The third part selects all the description term elements (as a node list) and assigns them to a variable called dts. Variables are just simple containers for storing things. The name I've given this variable is just convenient and descriptive.

// select all the description term elements
// assign to a variable
const dts = document.querySelectorAll('dt');

Code block 2.16

We are using the document.querySelectorAll() method to select all the definition term elements in our document. This is a lovely method because it allows us to use CSS selector syntax to make our selections. It's just one of the ways that modern JavaScript makes it easy for us to keep our JavaScript separate from our HTML.

The dts “variable” is declared using the const keyword. Unlike today, the value of dts will not change during the script and we therefore declare it as a constant.

Finally, the fourth part uses the node list index (held in the today variable) to select the reference to the relevant <dt> element, and to set the value of the className property to 'today'. This has the effect of adding class="today" to the corresponding decription term element. This sort of technique is often referred to as “DOM Scripting” because we are using JavaScript to manipulate the document object model.

// use the day number (today variable) to add
// the 'today' class to the appropriate dt
// element so it and the adjacent dd can be
// styled in CSS
dts[today].className = 'today';
// node lists begin at 0, so day 1 in our list
// (Monday) will be node 0

Code block 2.17

When all three layers come together in the browser, our web organism performs as designed and provides the best possible user experience with the minimum amount of code.

Notice that we are using plenty of comments in all three layers of our document to explain how things work. This will help us to remember why we made the decisions we did and the annotations will help our collaborators or team members to understand our logic. This is particularly important for JavaScript, which is why the comments in that file form a commentary for the script.

JavaScript modifies the HTML

The markup below illustrates what our HTML description list will look like on a Tuesday when JavaScript has dynamically added the class name to today's <dt> element. The text “Tuesday” and the associated opening times will both be highlighted when rendered in a browser. They will be styled according to the .today CSS rule. This is a great example of HTML, CSS, and JavaScript all working together in harmony, despite being separated into their respective files.

        <dd>9:00am to 5:00pm</dd>
        <dt class="today">Tuesday</dt>
        <dd>9:00am to 5:00pm</dd>
        <dd>9:00am to 5:00pm</dd>

Code block 2.18

The final result is shown in the following image. HTML is providing the structure and semantics, CSS the styling (presentation), and JavaScript the dynamic (in this case time-based) aspect of our design (behaviour). Despite this close working relationship, each layer remains separate from the other, meaning that we have a modular build which gives us great flexibility and efficiency for future design and development.

A completed organism in a browser
Figure 2.9. Our completed organism in a browser as it will appear on a Tuesday.

Building user experience layer by layer

Our organism is now complete and is built using all three layers of the Web Standards Model. In addition, we have seen how, with each added technology layer, we have been able to progressively enhance the user experience without compromising access to the original content. Our organism is fault-tolerant and will gracefully degrade if things go wrong.

Robustness and order

Notice that we have introduced the three layers in a specific order. Structure first, presentation second, and behaviour third. This order is important because it describes the relative robustness of the three layers, beginning with the most robust (structure) and ending with the least robust (behaviour). Our objective always is to ensure that we entrust the most important parts of our design to the most robust technology layer. This should mean that if a less robust layer were to fail, our design will degrade gracefully, and the user would still be able to access the core content.

The web is a hostile environment, and we can never be sure where or how our documents will be viewed. For example, we don't know whether the user agent being used to view our designs is able to interpret JavaScript. Neither do we know whether (for whatever reason) the user has turned off JavaScript in their browser. As designers and developers, we have no control over any of these things. We therefore need to factor some fault-tolerance into our designs, and that usually means considering carefully what functions we entrust to each of the three layers.

We now know that we need to ensure that if JavaScript is unavailable or fails, the user can still access our content. That effectively means that we should not use JavaScript for mission-critical functions such as generating content on the fly. JavaScript should only ever be a progressive enhancement of HTML and CSS; it should not be used to replace their core purpose. Unfortunately, some current websites (such as YouTube) do not observe this important principle.

YouTube in a browser with JavaScript disabled
Figure 2.10. YouTube in a browser with JavaScript disabled.

In our example organism, JavaScript is used to highlight today's opening times. If it were to fail, the user can still view the opening times for all days of the week. The progressive enhancement we made is lost, but the content degrades gracefully is still readable.

We can extend this principle and suggest that any function of our design should be delegated to the most robust layer capable of implementing it. Our example organism appears to move towards the user when they mouse over or tap it. This function (the scaling of the element) could have been implemented using JavaScript, and in the past, that was the only way it could be implemented. However, modern CSS is perfectly capable of making this happen. If the effect can be made equally well using either JavaScript or CSS, it should always be implemented with CSS because that is the more robust technology. As CSS continues to evolve in the future, and becomes more capable, we will be doing more interface design in the presentation layer and not relying on JavaScript for functions that are essentially visual in nature. This will leave JavaScript free to do the heavy lifting of techniques like DOM Scripting.

Further reading

For more on this topic, read:

Top of document