Going back to Web Basics: Structuring HTML
But we might have forgotten the true purpose and magic of HTML. HTML is a parse-able document that is the main place for content. And this content is, for all its intents and purposes, is both readable by computers and all kinds of users. Baked into its tags are little helpers for users.
Little helpers that help computers understand the structure of your document, which help people search the most important information they need.
Little helpers that help computers add that extra information when things fail to load or when you need to load the right asset provided .
Little helpers that help computers add voices or visual ques to help disabled users or people who has accessibility issues.
Tutorials and In-the-Wild HTML
There are still some good tutorials on how to write good HTML but there are some that has overused
spans turned into titles…
<header id="top" class="main-header">
This is the Title Text
with another title here.
or emphasizing texts using span…
<span class="italics">Emphasis on this text</span>
Returning to Basics
How I (hope I will) write my HTML
I still have those bad habits, especially when you are a developer who wants to get things done because of deadlines and bad tutorials. But I am hoping what I can share to you my current practice and opinion on how to structure your HTML.
Starting with the structure
My landing page would have a structure like this:
Now given above, let’s dissect this one.
This allows the document to be treated as an HTML 5 document. Nothing much to explain here…
I like my documents to be in
utf-8 so as to help the browser and other bots to not use their time to infer the encoding.
<meta name="viewport" content="width=device-width, minimum-scale = 1.0, initial-scale = 1.0, maximum-scale = 5.0, user-scalable=yes,
Now this is where it gets interesting. The viewport allows us to make our site mobile responsive. The one above just says that the viewport size should be at least equal to the size of the viewport of the phone. But what really gets me interested is the last two parts.
maximum-scale = 5.0, user-scalable=yes
Most of the tutorials I’ve seen puts
maximum-scale=1, user-scalable=no. These two sets stops the user to pinch-zoom your mobile website. Now, that is good for design, but bad for accessibility. It doesn’t help people who have problems with their eyesight if they can’t read your text and they can’t zoom into it. So in my opinion,
maximum-scale=5, user-scalable=yes. You can see more of the explanation here.
I added also this…
Because of Safari 9. This makes Safari 9 at least follow the standard for Responsive Websites. You can check it out here: http://adrianroselli.com/2015/10/dont-disable-zoom.html
<meta name="generator" content="Page Generator v1.0.0">
This helps browsers and statistics lovers know what is your favorite IDE or page generator or something. I like to keep this around and put my own Slush builder later.
<meta name="description" content="This is the description of the page">
The helps search engines provide a description of your page on search results. Descriptions are like Twitter texts: 160 character snippet of what your page is about. You can check here on tips on how to write your page description. Knowing some good micro-copy might give you advantage.
<meta property="og:title" content="Title of the Page to be shown in Facebook">
<meta property="og:type" content="website">
<meta property="og:image" content="https://example.com/image-to-be-shown-in-facebook.jpg">
<meta property="og:description" content="This is the description of the page that will show in the facebook card">
These are meta tags that are helpful in making your page a bit more share-able in Facebook.
<meta name="twitter:card" content="summary_large_image">
<meta name="twitter:site" content="@twitterHandleOfSite">
<meta name="twitter:creator" content="@twitterHandleOfCreator">
<meta name="twitter:title" content="Title of the Page to be shown in Twitter">
<meta name="twitter:description" content="This is the description of the page that will show in the twitter card">
<meta name="twitter:image" content="https://example.com/image-to-be-shown-in-twitter.jpg">
And these are meta tags that are helpful in making your page a bit more share-able in Twitter.
As you can see both of the Facebook and Twitter meta tags have areas to put your title and description. These will show up as the title and description cards when you share your page. Much like the
meta description and the
title tag, it will be useful to use the same ideas here on how to write a good description.
Web App Manifest and Fallback
<link rel="manifest" href="manifest.json">
Using the manifest.json, it allows the user to add your website as an app in their phone/tablet’s homepage. The Web App Manifest essentially standardize the way we set icons, app behavior, splash screens, even the site’s short name that will show on the home screen. But…
Only Chrome and Opera supports it. That’s why we have fallback mechanisms for other browsers…
<!-- Add to homescreen for Chrome on Android. Fallback for manifest.json -->
<meta name="mobile-web-app-capable" content="yes">
<meta name="application-name" content="Title of this Page">
<!-- Add to homescreen for Safari on iOS -->
<meta name="apple-mobile-web-app-capable" content="yes">
<meta name="apple-mobile-web-app-status-bar-style" content="black-translucent">
<meta name="apple-mobile-web-app-title" content="Title of this Page">
<link rel="apple-touch-icon" sizes="48x48" href="images/manifest/images/icons/icon-48x48.png">
<link rel="apple-touch-icon" sizes="72x72" href="images/manifest/images/icons/icon-72x72.png">
<link rel="apple-touch-icon" sizes="96x96" href="images/manifest/images/icons/icon-96x96.png">
<link rel="apple-touch-icon" sizes="128x128" href="images/manifest/images/icons/icon-128x128.png">
<link rel="apple-touch-icon" sizes="144x144" href="images/manifest/images/icons/icon-144x144.png">
<link rel="apple-touch-icon" sizes="152x152" href="images/manifest/images/icons/icon-152x152.png">
<link rel="apple-touch-icon" sizes="192x192" href="images/manifest/images/icons/icon-192x192.png">
<link rel="apple-touch-icon" sizes="384x384" href="images/manifest/images/icons/icon-384x384.png">
<link rel="apple-touch-icon" sizes="512x512" href="images/manifest/images/icons/icon-512x512.png">
<!-- Tile icon for Windows 8 (144x144 + tile color) -->
<meta name="msapplication-TileImage" content="images/manifest/images/icons/icon-512x512.png">
<meta name="msapplication-TileColor" content="">
<meta name="msapplication-tap-highlight" content="no">
Now of course these are not exhaustive but it currently suffices my needs.
Above the Fold Inline Style
// Styles for the above fold
For performance purposes, I split my styles into two separate parts. Styles that show above the fold, and styles that are under the fold. The purpose of the separation is that CSS blocks the rendering of content. And loading a stylesheet (or any file) in the head blocks the rendering of the body part. To minimize the performance impact and reach the time-to-first-paint (or showing the content immediately), I would put the essential styles at the top and defer loading the other styles at the bottom. The styles above the fold are put in the head so that it is part of the content document when it is being loaded first, parsing it quickly to show the design when the body renders. You can check good practices here and here. You can also understand how rendering works by reading it here.
See that I have separated the page into three main sections:
footer. This corresponds to a lot of pages in the wild where you have a header, main content, and footer, and it reflects to the structural outline as well. Nice job on not using just
divs and making it easier to understand by users, screen readers, bots, and devs.
In the main header, the logo is inside the
h1 tag so that it can tag that the header section with a title.
picture/img tags can be inside
h1 tags because they are considered phrasing content. Now it also has a nav list for a list of links. We can add parts here like search forms and login buttons, but we’ll save it on another article.
Quick detour: Aside
<h2>Side bar footer</h2>
Although there are three main sections, in our document there are actually four parts. The aside is a tag that represents content that is tangentially connected to the main content of the document. I used it as a drawer in this example for mobile phones. I could also just use a simple
nav tag as a drawer and it would suffice. Now because this is an
aside tag, it quickly becomes under the outline of the header based on the html outline algorithm. Again, the drawer for me is optional and I am still debating with myself about it (if should just use a
nav with tab icons as a primary navigation (either positioned above or below the screen) or use the hamburger/drawer combo for smaller screens.
<p>This is the section with a CTA</p>
<a href="/cta" class="cta">
<h2>Section 1 here</h2>
<h2>Section 2 here</h2>
<h2>Section 3 here</h2>
<h2>Section 4 here</h2>
Now the main content shows you the structure that is usual to most landing pages. You have a banner and several sections. I have used a
header tag instead of a
section tag to differentiate the banner from the other sections so that I can tell the computers that this is the title of the main content. If this becomes an article type of page, I would just wrap this in another tag called an article, but that would be for another article.
<h1>Main Footer here</h1>
Of course, the
footer has all the essential information about the authors, or copyright data, or footer nav links.
<link rel="stylesheet" href="style.css">
// adds styles later
var style = document.createElement('link')
style.rel = 'stylesheet'
style.href = 'style.css'
var first = document.getElementsByTagName('link')
Because we have put only the above-the-fold styles at the top, we put here a script that lazy-loads the remaining css files. Lazy-loading CSS files are different in such a way that you can’t just put a
async attribute to a link tag (much like in
script tags). Once you put a
link tag, either in the
head or the
I added a
// Polyfills and other script essentials here
Lastly, we load all the scripts that you need to make the site a little bit more interactive. I would put here my Google Analytics, Facebook Analytics, Error monitoring scripts, Polyfills, and libraries to create a richer experience.
A word of caution though for this type of pages: If you are going to add the JS at the last part but your page is dependent on the JS to make it interactive, it will have a big performance impact, pushing the time-to-interactive further. This will eventually frustrate your users. If you can have your HTML + JS (and maybe CSS) to have only a size of 150KB (ideal is 50KB) to show and interact with essential content, then you are good.
This is my own opinionated (and at the minimum, documented) way of structuring my HTML files. I would like to know yours or if this can be improved better. In my later articles, I would try to include how to structure your page using web components that uses ShadowDOM and how it impacts screen readers.