Friday, November 11, 2016

How to handcode a simple blog in HTML5

Here's a screenshot of the final result to give you an idea of what you will learn to code.

Tutorial

Hello people! In this post I will show how to code your own static blog in HTML5 and begin blogging by minutes. This is for HTML beginners and a step-by-step, learn-by-doing tutorial. Yeah, there are many ready-to-use blog platforms that do not require you to hand-code everything, including this, Blogger. But making your own blog from scratch is a good way to learn about HTML, CSS and how web sites are made. You are encouraged to try out all the code snippets in your browser to see how they render and what the effect of each tag is. Copy and paste each sample in a simple PLAIN text editor, that is Notepad, not Word and save the result as index.html, then click on it and it will be opened with your browser. After each modification, save the new version in Notepad and hit your browser's reload button to make it aware of the code change and redisplay the page. Let's start from an empty HTML page:
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>YOURNAME's Blog</title>
</head>
<body>
</body>
</html>
Now, what is a blog? It's a collection of posts (articles), displayed from the most recent one. That's the page "main content" - posts - but there is also a page header with the name of the blog and a tagline.
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>YOURNAME's Blog</title>
</head>
<body>
<header>
<p>My daily thoughts...</p>
<h1>YOURNAME's Blog</h1>
</header>
<main>
<article>...</article>
<article>...</article>
</main>
</body>
</html>
You choose how many posts to put in any page, from one to many, depending on how long they are. Now, let's detail each of the posts content. Post have a title and consist usually of paragraphs of text, but you may also want to post a video or an image and you can intermingle text and images/video as you wish. Each post has a publication date that we chose to put in the article footer:
<!DOCTYPE html>
<html>
<head>
<meta name="generator" content=
"HTML Tidy for HTML5 for Linux version 5.2.0">
<title>YOURNAME's Blog</title>
</head>
<body>
<header>
<p>My daily thoughts...</p>
<h1>YOURNAME's Blog</h1>
</header>
<main>
<article>
<h1>Text post</h1>
<p>First paragraph... ends here.</p>
<p>Another paragraph.</p>
<footer>
<p>Posted <time datetime="2016-11-20T18:45+01:00">on 2016/11/20 at
6:45pm</time></p>
</footer>
</article>
<h1>A picnic on the lake</h1>
<article><video src="vids/picnic.mp4" controls preload>
<p><a href="vids/picnic.mp4">Download my picnic video</a>.</p>
</video>
<footer>
<p>Posted <time datetime="2016-11-19T13:34+01:00">on 2016/11/19 at
1:34pm</time></p>
</footer>
</article>
<article>
<h1>My pets</h1>
<p><img src="imgs/fido.jpg" alt="Fido">This is my dog Fido. He
needs my attention all the time!</p>
<p><img src="imgs/alice.jpg" alt="Alice">And this is my kitty,
Alice! Do not disturb her when she's sleeping...</p>
<footer>
<p>Posted <time datetime="2016-11-17T10:03+01:00">on 2016/11/17 at
10:03am</time></p>
</footer>
</article>
</main>
</body>
</html>
Note the IMG tag alt attribute is for the benefit of visually impaired people, search engines or users that have disabled image loading in the browser, e.g. to save bandwidth on slow connections. It defines a replacement (ALternate Text) for images, which will be shown if the image doesn't exist or is deleted too. You may want to describe the picture better, e.g. "My kitty-cat Alice sleeping on the sofa", instead of just "Alice". For those browsers that cannot display embedded videos, a download link is provided inside the VIDEO tag. Note also to keep things tidy we collect all images in a imgs/ subfolder and likewise on videos. It is a good idea to use the TIME tag to provide a machine-readable format for the date and time. This is a format standardized by ISO and includes a numeric timezone - that +01:00 part, which means 1 hour ahead of Greenwich standard time. We then need to add navigation links. The first time you want to create a new page, you copy index.html to 2.html and delete articles so to get an empty blog page you can add new articles to. You also rename index.html to 1.html. After the closing tag, you add a page footer with a navigation menu in both files. In the same footer you can also fit a copyright notice, if you wish. Then you create index.html as a link to 2.html, which is the latest page. In 1.html:
</main>
<footer>
<nav>
<p><a href="2.html">Newer Posts</a> —
<a href="index.html">Home</a> —
Older Posts</p>
</nav>
<p>Copyright © YEAR YOURNAME</p>
</footer>
In 2.html:
lt;/main>
<footer>
<nav>
<p>Newer Posts —
<a href="index.html">Home</a> —
<a href="1.html">Older Posts</a></p>
</nav>
<p>Copyright © YEAR YOURNAME</p>
</footer>
You now probably got what to do when adding a third page. Remember to update the file link, making index.html point to 3.html and activate the "Newer Posts" clickable link in 2.html to point to 3.html. If all pages are linked together like this, visitors will be able to browse through your blog as it were a book to leaf through and you will make sure a search engine will index your entire blog. You only need to add the index.html page address in the "Add site to index" service of the search engine or make sure your blog is linked by another already-indexed site. As you have seen, with HTML you define the logical structure of the page, but not its visual appearance. If you display 2.html with a browser now, you will see it looks pretty dull, because the default formatting styles for tags are basic and simple. To spice up your blog, you need to change the presentation style of the structure you defined with HTML. This requires you to have a bit of the typesetter's creativity and is done with another language, called CSS (Cascading Style Sheets). You will put the style definitions in a separate file so that they will be shared amongst all pages. In all pages you will need to add a tag to link to the stylesheet. Nest that into the HEAD tag:

Now in blog.css you will add style rules one by one and reload the blog page in the browser to check the result. E.g. I wish a kind of golden yellow background for the main content (posts):
main {
  background-color: gold;
}
Fortunately, you can simply use plain-English color names. I also want to have some space between posts' text and the borders of the main page content. It's a good idea, while you are coding a style, to turn on the display of the border of each element, so you can actually see the structure of your page. This is the purpose of the first rule with * meaning any tag name (any HTML element). I chose a dotted border because a solid one clutters the page too much:
* {
  border: 1px dotted;
} 

main {
  background-color: gold;
  padding: 2em;
}
"em" is rough relative typographical measure, meaning the size of an "M" in the current font, so 2em means 2 times the size of the current font. You probably notice the first article's title is not at the same vertical and horizontal distance from the main content borders. The vertical distance is more. Why is that? You should now each element has not only padding space inside the borders that delimit it, but also margin space outside the borders that separate it from other elements. By default, an h1 element has such a top and bottom margin space. So to make distances even, we just need to set to zero out the top margin of the h1 element, but of the first article only. In CSS lingo this is done like so:
article:first-of-type h1 {
  margin-top: 0;
}
Let's say we want some words to be highlighted in the article text. There is a STRONG tag, which gives strong emphasis to the words it surronds. Let's wrap your beloved pets' names with that. You will see they are rendered bold. I only want to change the emphasised text color from default black to red:
strong {
  color: red;
}
By default images are put inline with the text surrounding them, with the image bottom aligned to the bottom of the text line that contains it. Make the sentences about your pets very long, reload the page and you will see what I mean. Unfortunate default behaviour! We rather want to wrap text around the image. Here is how to tell the browser to do that for every image inside a paragraph:
p img {
  float: left;
}
We chose to float images to the left - you can also use "right". But look what may happen: if text around an image is not long enough to fill up all the the image height, whatever follows will flow to the right of the image too. We better not let cats and dogs run into each other :-)
So we need a way to clear the wrapping and tell the browser to return to normal, default flow. Thinking about it, we may have many short paragraphs of text that should wrap around an image. So we better put the IMG tag outside, before the first P tag that should wrap around it. Then we will tell the browser to stop wrapping text when a new image or anything else we do not want to wrap around the image follows. How to do that? There is a special element with no semantic associated, called DIV for DIVersion, which you should use when you need to wrap two or more elements for styling purposes only, and, I repeat, there is other meaning attached. By giving the DIV a class name, you can easily style all DIVs with the same class name in the CSS. So here's the correct HTML and CSS for inserting images between text, wrapping the text at the left or right of an image, with added space between them and even a nifty 1-pixel image border added. Everything inside the div will be wrapped around the image, but what follows the div, whatever it is, won't. E.g. the selector div.right_img + * means to apply a style rule to all (*) sibling tags following (+) DIVs with the right_img class (div.right_img). For these we do not want any floating elements to the left or the right (clear:both).
<div class="left_img"><img ...>
<p>...</p>...<p>...</p></div>
<div class="left_img"><img ...>
<p>...</p>...<p>...</p></div>
<p>...</p>...<p>...</p>
<div class="right_img"><img ...>
<p>...</p>...<p>...</p></div>
div.left_img, div.right_img,
div.left_img + *, div.right_img + * {
  clear: both;
}

div.left_img img, div.right_img img {
  margin: 1em;
  border: 1px solid black;
}

div.left_img img {
  float: left;
} 

div.right_img img {
  float: right;
}
Now that you can format illustrated books (give it a try), we can refine the overall fonts. We want the characters of the main text to be a bit bigger than the default. This applies to the paragraphs inside an article, not the P in the header, so we can't just write P as a selector. "article p" means any p nested inside an article (a "child of" article). Larger here means larger than the font size of the parent element (article), which is the default one, so a bit larger than the browser default. I also want smaller, italicized article footers, because they are less important than the text itself and I do not want them to stand up too much. And small-caps font for the post titles. In a small-caps font, all lowercase letters are converted to uppercase letters. However, the converted uppercase letters appears in a smaller font size than the original uppercase letters in the text.
article p {
  font-size: larger;
}

article footer {
  font-size: smaller;
  font-style: italic;
}

article h1 {
  font-variant: small-caps;
}
Let's add a thick black border to tell the main content apart from the page header and footer. Change the top rule for main so that it reads as follows:
main {
  background-color: gold;
  padding: 2em;
  border-top: 0.5em solid black;
  border-bottom: 0.5em solid black;
}
And embellish the page footer with colors... Note that after setting a red background, the default bluish link color is no more appropriate: it does not contrast well on darkred. So now we change both visited and unvisited link colors for the footer. We also wish to center the page footer content, which contains the NAVigation menu and a copyright note. They are both text paragraphs, taking up all the horizontal space available, so we just need to center the text inside their boxes:
body > footer {
  background-color: darkred;
  color: white;
  padding: 1em;
}

body > footer p {
  text-align: center;
}

body > footer a:link, body > footer a:visited {
  color: gold;
}
Note we want to style only the footer at the end of the page, not the ones belonging to each post. body > footer means footer that is the direct child of body and thus excludes those FOOTERs that are the direct child of article. > means direct child, not descendant. The latter could be child, nephew, grand-nephew, etc. Note we add some padding space to the footer, which also makes it taller. Our last CSS feat is the styling of the site headline. The artist instinct in me wants that buzzword - "blog" - in very big bold red text and the owner name just above it in smaller all capitals. The tagline to the left, bigger than the name but smaller "blog". Since both the blog owner name and the word "blog" are part of the H1 header, in order to style them separatedly, we need the SPAN tag. This tag has no structural meaning, much like DIV, but while the latter is a "block-level" element, SPAN is an "inline-level" element. Nah, just big words to say that SPAN applies to a portion of text without breaking it with a newline before and after itself. You can't nest a DIV inside an H1 because that would break the H1 element in two, which does not make much sense to do. Change your HTML in both files so that the site title looks like this:
<header>
<p id="tagline">My daily<br>thoughts are<br>all here in</p>
<h1><span id="name">Name Surname</span><br><span id="blog">my 
blog</span></h1>
</header>
Some tags are given an ID attribute - guess what - to identify them. We do not use a CLASS attribute, though we could. An ID is more appropriate when there is one and only one tag to style. ID values must be unique throughout all the document. IDs are referred in the CSS with a hash mark before the chosen nickname. In order to center two block elements side-by-side, I had turned them to inline-block, so that for the purpose of presentation, they behave just like inline elements. You may want to try the effect of the added and/or modified CSS rules one by one, for a better understanding:
#blog {
  font-size: 2em;
  color: red;
}

article h1, #name {
  font-variant: small-caps;
}

#tagline {
  display: inline-block;
  font-size: 2em;
  text-align: right;
  margin: 0.5em;
}

header {
  text-align: center;
}

header h1 {
  display: inline-block;
  text-align: right;
}

FINAL THOUGHTS

HTML and CSS are not easy. Everything should be easier. It wouldn't be difficult to accomplish the goal of keeping structure and style separated using a what-you-see-is-what-you-get (WYSIWYG) editor without writing any line of code. The main reason why this is hard to do with the current web standard is the way CSS works and is defined. CSS is a tricky language and not very general and powerful enough for being easily generated by a GUI. The great diversity of devices capable of displaying web pages can make it harder to make the page look the same everywhere, but a stricter standard would have helped to achieve that. Unfortunately we have to cope with what we have. As a consequence web development remains difficult, slow and quite expensive. Not within any internet user's reach, as it should be.

SOURCE CODE

index.html

<!DOCTYPE html>
<html>
<head>
<meta name="generator" content=
"HTML Tidy for HTML5 for Linux version 5.2.0">
<meta charset="UTF-8">
<title>Antonio Bonifati's Blog</title>
<link rel="stylesheet" href="blog.css">
</head>
<body>
<header>
<p id="tagline">My daily<br>
thoughts are<br>
all here in</p>
<h1><span id="name">Antonio Bonifati</span><br>
<span id="blog">my blog</span></h1>
</header>
<main>
<article>
<h1>Text post</h1>
<p>First paragraph... ends here. This is how a <a href=
"http://www.google.com">link</a> looks like.</p>
<p>Another paragraph.</p>
<footer>
<p>Posted <time datetime="2016-11-20T18:45+01:00">on 2016/11/20 at
6:45pm</time></p>
</footer>
</article>
<article>
<h1>A picnic on the lake</h1>
<video src="vids/picnic.mp4" controls="" preload="">
<p><a href="vids/picnic.mp4">Download my picnic video</a>.</p>
</video>
<footer>
<p>Posted <time datetime="2016-11-19T13:34+01:00">on 2016/11/19 at
1:34pm</time></p>
</footer>
</article>
<article>
<h1>My pets</h1>
<div class="left_img"><img src="imgs/fido.jpg" alt="Fido">
<p>This is my dog <strong>Fido</strong>. He needs my attention all
the time!</p>
<p>He is a baby beagle and like to catch the ball.</p>
</div>
<div class="right_img"><img src="imgs/alice.jpg" alt="Alice">
<p>And this is my kitty, <strong>Alice</strong>! Do not disturb her
when she's sleeping...</p>
<p>I bought a small cyan sofa for her.</p>
</div>
<footer>
<p>Posted <time datetime="2016-11-17T10:03+01:00">on 2016/11/17 at
10:03am</time></p>
</footer>
</article>
</main>
<footer>
<nav>
<p>Newer Posts — <a href="index.html">Home</a>
— <a href="1.html">Older Posts</a></p>
</nav>
<p>Copyright © 2016 Antonio Bonifati</p>
</footer>
</body>
</html>

blog.css

/* Uncomment when developing and debugging */
/*
* {
  border: 1px dotted;
}
*/

main {
  background-color: gold;
  padding: 2em;
  border-top: 0.5em solid black;
  border-bottom: 0.5em solid black;
}

article:first-of-type h1 {
  margin-top: 0;
}

strong {
  color: red;
}

div.left_img, div.right_img,
div.left_img + *, div.right_img + * {
  clear: both;
}

div.left_img img, div.right_img img {
  margin: 1em;
  border: 1px solid black;
}

div.left_img img {
  float: left;
}

div.right_img img {
  float: right;
}

article p {
  font-size: larger;
}

article footer {
  font-size: smaller;
  font-style: italic;
}

article h1, #name {
  font-variant: small-caps;
}

body > footer {
  background-color: darkred; 
  color: white;
  padding: 1em;
}

body > footer p {
  text-align: center;
}

body > footer a:link, body > footer a:visited {
  color: gold;
} 

#blog {
  font-size: 2em;
  color: red;
}

#tagline {
  display: inline-block;
  font-size: 2em;
  text-align: right;
  margin: 0.5em;
}

header {
  text-align: center;
}

header h1 {
  display: inline-block;
  text-align: right;
}

No comments: