import { addBanner, addArticle, addTitle, addHeader, addParagraph, addClassParagraph, addSubHeader, addOrderedList, addUnorderedList, addBlockquote, addInset, addInsetList, addInsetCodeListing, addInsetBulletList, addImageWithCaption, addButtonGroup, addSidebar, addSyntax, menu, global_menu } from '/scripts/import.js';
import { local_menu } from '/scripts/webdev.js';
const heading = document.querySelector(".heading");
const global = document.querySelector(".global_menu");
const local = document.querySelector(".local_menu");
const sidebar = document.querySelector(".sidebar");
const main = document.querySelector(".main_content");
heading.append(addTitle("CSS Essential Training"));
heading.append(addParagraph("Christina Truong - LinkedIn Learning - October 2019"));
heading.append(addParagraph("Chapter 3 - The Box Model"));
main.append(addSubHeader("Introduction to the Box Model"));
main.append(addParagraph("It may not be obvious or intuitive, but the browser sees everything in the viewport as being contained in a rectangular area. That includes both block element such as paragraphs and inline elements such as links or images. Consider this simple HTML page."));
main.append(addInsetCodeListing(["<head>", "<meta charset=\"utf-8\">", "<meta http-equiv=\"X-UA-Compatible\" content=\"IE=edge\">", "<meta name=\"viewport\" content=\"width=device-width, initial-scale=1\">", "<title>My Learning Website</title>", "<!-- HTML5 shim and Respond.js for IE8 support of HTML5 elements and media queries -->", " <!-- WARNING: Respond.js doesn't work if you view the page via file:// -->", " <!--[if lt IE 9]>", " <!--[if lt IE 9]>", " <script src=\"https://oss.maxcdn.com/html5shiv/3.7.2/html5shiv.min.js\"></script>", " <script src=\"https://oss.maxcdn.com/respond/1.4.2/respond.min.js\"></script>", "& lt;![endif]-->", "</head>", "<body>", " <h1 id=\"1\">This an h1 element.</h1>", " <p id=\"2\">This is just a paragraph.</p>", " <p id=\"3\">Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. It has survived not only five centuries, but also the leap into electronic typesetting, remaining essentially unchanged. It was popularised in the 1960s with the release of Letraset sheets containing Lorem Ipsum passages, and more recently with desktop publishing software like Aldus PageMaker including versions of Lorem Ipsum.</p>", " <p id=\"4\">Yes, another paragraph but this one has a <a href=\"#\" id=\"8\">LINK</a> in it although it doesn't go anywhere.</p>", " <p id=\"5\">Like my career - ho hum!</p>", " <h2 id=\"6\">This is an h2 element, smaller than that h1 but bigger than a paragraph.</h2>", " <p id=\"7\">This is the last paragraph.</p>", "</body>", "</html>"]));
main.append(addParagraph("It is very simple, just containing a few elements, but I have used a simple method of giving each element a unique id, using the numbers 1 to 8. There is no CSS attached to it so it looks like this."));
main.append(addParagraph("Now, I will attach a CSS stylesheet to this and give each of the elements a different background colour using the ids as selectors. With the CSS applied, the page now looks like this. I also changed the text colour in a couple of the elements so that they could be more easily read. I also changed one of the paragraphs in the second version to make it bigger and more box like."));
main.append(addParagraph("This illustrates some interesting points relating to the model. Each colour shows a rectangle which show the area that the element occupies and it looks more clearly like a box than it did in the first version. Notice also that the browsers default styles are being applied because there is no reset being used. This means that you will likely not see any padding, but you will see gaps between the coloured blocks because there are default margins. If I add padding to any element, or a border of, let's say, 10 pixels, both of these things would make the boxes larger."));
main.append(addParagraph("Both the border and the padding will increase the size of the elements so if you are calculating the dimensions, let's assume an element has a width of x pixels and a height of pixels. The size is calculated like this"));
main.append(addSyntax("Width = x + padding-left + padding-right + border-left-width + border-right=width"));
main.append(addSyntax("Height = y + padding-top + padding-bottom + border-top-width + border-bottom-width"));
main.append(addParagraph("The border is usually expressed as a width so I have called it that in relation to both the border-top and the border-bottom."));
main.append(addParagraph("In contrast, a margin represents the space between elements so we don't take it into account when calculating the width of the dimensions, but we do need to take it into account when calculating the amount of width the element occupies on the page. You can see that in the example where more space is being used because of the vertical margins. Another, p[perhaps clearer, demonstration of this can be found in the web development tools. If you inspect an element, you will see a box in the right hand column showing the element with its dimensions and it shows how much is added by both the padding and the border. It also shows the margins surrounding the element."));
main.append(addSubHeader("Inline, Block and Display"));
main.append(addParagraph("Something else that this simple page demonstrates is the normal flow. The block elements are placed, by default, one after another in a stack. Inline elements, such as the link, appear in the line, but it will run down to the next line if there isn't enough room for it on the previous line, in their container. By default, this would be the viewport as it is for the demo page, but you can create containers that are less than the width of the viewport, so a line width is going to be determined by the container's width rather than the viewport's."));
main.append(addParagraph("In general, we could say that the width of a block element is the width of its container. On the other hand, the height is determined by the content so if you have, let's say a paragraph with some text in it, the height will be the same as the font-size in pixels."));
main.append(addParagraph("So, an element is either a block element or an inline element. However, we can change this so that a block element is displayed as a line element and vice versa, and we do that with the display attribute. If we go back to our box model demo for a second, you may have notice that each of these blocks contain some text and in most cases, the text doesn't fill a whole line. However, as we can see from the background colour, the element itself does fill the line so this is a good visual demonstration of the box model."));
main.append(addParagraph("Now, I will change a couple of these elements by adding a display attribute like this."));
main.append(addInsetCodeListing([" #a2 {", " display: inline;", "}"]));
main.append(addParagraph("I will use a similar rule to change the display type for our link to block and we can see how this affects the page display in boxmodel2.html. Now, the link is on a line by itself because it is being treated as a block element. You may also notice that the element with id a2 is still being displayed on a line by itself, but the background colour no longer extends to the end of the line. This is because the elements immediately before and after it are still being displayed as block elements. If we change the display property of the second paragraph to inline (it has the id a3), it now starts on the same line as the previous paragraph and the black backgrounds ends at the end of the line of text, it doesn't extend to the full width of the viewport. We can see this in boxmodel3.html."));
main.append(addParagraph("One other thing to notice in boxmodel3.html is the link. This was placed inside a paragraph and there was some text before and after it. By displaying the link as a block element, we have effectively turned one block element with an embedded inline element into three block elements. Essentially, the browser starts to display this paragraph as a block element, it encounters the link which is now also a block element so it displays it on a new line and then starts a new line and displays the rest of the paragraph. If we turn things around completely and display the paragraph as an inline element, we then have effectively an inline element followed by a block element followed by another inline element. Both of these elements are surrounded by block elements, so without the background colours, it would be impossible to tell whether they were block or inline elements, at least by looking at them in the web page. It really only makes sense to display block elements as inline elements if you are doing that to change the flow of the page, remember that block elements flow vertically and inline elements flow horizontally."));
main.append(addParagraph("Another point to consider is that there is a difference between the width of a container and whether it is a block or an inline element. The height of both inline and block components is determined by the height of the content. The width is different. For an inline element, it is also determined by the width of the content, but for a block element, it is determined by the width of the container. In our examples, this means that the width of a block element is the same as the width of the viewport."));
main.append(addParagraph("These are defaults, and don't take into account whether you set a width for the container. I have changed the CSS so that the last three elements (two paragraphs and a heading) all have a width of 100 pixels and also, changed the width of the third paragraph (the one containing the link) to 100%. We can see what this looks like in boxmodel4.html."));
main.append(addParagraph("Notice that the last three elements now occupy a much smaller width. But they are still being displayed as block elements so the next element starts on a new line. On the other hand, the third paragraph now looks like a block element in that it displays some of the properties of block elements, notice that the width is now determined by the largest width of the three components of the block and we can see this in boxmodel5.html. Notice that although it is displaying as a mini-block element, it is still displayed inline and it looks more like a cohesive single element than it did in boxmodel4.html. I have removed the width attribute that had been added earlier, but I'm going to put it back on and set it to 300 pixels. This makes it a little clearer that the width of the element is no longer tied in with the width of the content since each part of the element is now wider than the content. We can take this to the extreme by giving it a width of 100% and now it looks like a block element again in that it doesn't seem to be affected by the components around it. This is not really correct, since it is still being displayed to some degree as an inline element, but an inline element that just happens to occupy an entire line as we can see in boxmodel6.html."));
main.append(addParagraph("One other type of inline element I want to mention is <span> which I haven't really used before. It's similar to a <div> element, but it is displayed (by default) as an inline element. This makes it quote useful for marking up a bit of text within another element so that you can style it differently or use it with JavaScript. To give an example of this, consider the following paragraph."));
main.append(addParagraph("My favourite colour is red."));
main.append(addParagraph("If I wanted the word red to actually appear in red, I could put it inside a made-up element such as <red> and then either style that element or give it a class or id that I can use to style it. The result of doing this is as follows."));
main.append(addParagraph("My favourite colour is red."));
main.append(addParagraph("Alternatively, I can use a span element and then use that to style. Again, I can choose to use an element selector or give it a class or id and use that. In this case, I will give it a class, red, and use that as a class selector."));
main.append(addParagraph("My favourite colour is red."));
main.append(addParagraph("The result is similar in both cases, but using span has changed the font-family and size attributes. Obviously, <red> has inherited these properties from its parent element. In the CSS for the site, I have used a selector of article p to effectively set some default font attributes for all paragraphs. I guess that because <red> is not a recognised tag name, it doesn't have any default properties so it inherits everything whereas <span> does not. I hadn't anticipated that but I think that it illustrates an important point that is applicable to pretty much all of the CSS and HTML that we write."));
main.append(addParagraph("Comparing the two methods, there is a lot to recommend for using your own tag names. You can use your own descriptive name and style it as required and can then use that to style other fragments of text in the same way without having to do additional styling. This is a little simpler than using a more generic element such as <span> and also is less likely to cause conflict with other styles such as font-family."));
main.append(addParagraph("However, it is worth bearing in mind that if we use a <span> element with a class, for example, we can also copy the other attributes for the paragraph into a declaration block for that class and the result is then the same. We can also very easily style other bits of text in the same way using another <span> element with the same class."));
main.append(addParagraph("So the question is whether there is any benefit to this extra bit of work that makes it worthwhile and the answer lies in semantics. For a browser parsing the HTML, either method will allow the browser to style our bit of text in the way we would like, but it won't know why we have added this extra element. On the other hand, it will be able to recognise a <span> element. This is also true for a human reading the code."));
main.append(addParagraph("It's important to remember that HTML is responsible for content and CSS is responsible for presentation, but it is important to code your HTML in a way that is meaningful and conveys your intentions as well as your content. Another example of this is where we took a block element, displayed it as an inline-block element and then styled it so that it looked like a block element again. The resulting output is the same whether we change the display property or not, but if we do, someone else reading the CSS might wonder why we did that since there is no obvious benefit."));
main.append(addParagraph("To avoid problems like this, the best approach is always to use the HTML that makes the most sense, semantically, and then use the CSS to define how it is displayed."));
main.append(addSubHeader("The Box Model Properties"));
main.append(addParagraph("A couple of interesting points relating to margin. In the longhand version where each side is specified individually, for example"));
main.append(addInsetCodeListing(["p {", " padding: 5px 10px 5px 10px;", "}"]));
main.append(addParagraph("The order always starts at the top and then goes clockwise so we have padding-top, padding-right, padding-bottom and padding-left."));
main.append(addParagraph("In this example, we have used the same units (pixels) for each dimension but these don't have to be the same. For instance, we could mix pixels with ems"));
main.append(addInsetCodeListing(["p {", " padding: 5px 1em 5px 1em;", "}"]));
main.append(addParagraph("If you are using a reset or something similar to remove defaults values, margins will, in most cases, have a value of 0 unless you specify a value yourself. If not, and you want to specifically set a value to 0, you can do that by specifying 0 with whatever unit you like such as pixels, but obviously the units don't really matter when you are specifying 0 (0 pixels is the same as 0 ems or 0%), so you can omit the units entirely."));
main.append(addInsetCodeListing(["p {", " padding: 5px 0 5px 10px;", "}"]));
main.append(addParagraph("The shorthand for border specifies border-width, border-color and border-style but these can be expressed in any order. The width can be expressed in any length unit or you can use a keyword with the possible values for these being thin, medium and thick. There are a number of possible values for the border-style including none which will remove it. The border property can get a bit complicated so it is worth looking at the documentation for it which you can find here."));
main.append(addSubHeader("Debugging the Box Model"));
main.append(addParagraph("I mentioned earlier that we can see the various components of the box that an HTML element sits in by using the browser's Developer Tools. I am going to do that now to look at the CSS for an element in the page boxmodel6.html. I will right click on the paragraph with the green background and select Inspect. The output is shown below."));
main.append(addImageWithCaption("./images/inspect1.png", "Figure 1 - inspecting an element with the Firefox web developer tools."));
main.append(addParagraph("This is in Firefox so we have three columns by default but the image only shows the centre and right-hand columns since these are the columns that display our CSS. It may be worth mentioning that if we have selected the wrong element, we may not see exactly what we expect, but we can simply select the right element from the HTML in the left-hand column or use the Pick an Element Tool in the top right by clicking on it to activate and then clicking on the element we want to view in the web page. We can also use this tool in Chrome."));
main.append(addImageWithCaption("./images/inspect2.png", "Figure 2 - inspecting an element with the Chrome web developer tools."));
main.append(addParagraph("Figure 2 shows the same element being viewed in the Chrome Web Developer Tools so we only have two columns with all of the CSS being shown in the right-hand column which is the column shown in the image."));
main.append(addParagraph("We're seeing the same information in both versions of the Web Developer Tools, so I don't want to worry about the differences between browsers. More importantly, we can see the box dimensions. For example, the size of the content is shown as 1984 x 54 and there is no padding and no border so this is also the height of the box. There is a top and bottom margin of 16 pixels, but this is not included in the element's dimensions since the margin is the space between elements. Note that in the demo page, you should see a gap of 16 pixels between elements, vertically. You may expect this to 32 pixels, which it would if you added the margin at the bottom of one element to the margin at the top of the next, but vertical margins don't work that way. There is no overlap so if we had, for instance, a 16 pixel margin at the top and an 8 pixel margin at the bottom of every element, the total margin would be 16 pixels. This type of behaviour is often referred to as margin collapsing and note that it affects top and bottom margins, but not left or right margins."));
main.append(addParagraph("If you want to experiment with your CSS, the easiest way to do that is to edit the CSS in the browsers Developer Tools. You can use these Developer Tools to disable a rule by unchecking it or re-enabling it by checking it again, you can edit the values or you can add new properties. This doesn't have any effect on your CSS files so if you reload or refresh the page, it will revert to the original CSS."));
main.append(addParagraph("Another useful feature in the developer tools is where you hover over an element in the HTML column. Assuming you can see the web page at the same time, you will see elements being highlighted in the webpage as you hover over them in the HTML. Similarly, if you hover over the box model (it is labelled box model in the Firefox tools but not in the Chrome tools - this is the box showing the element, padding border and margins) such as the margin, you will see it highlighted (if there is one) in the webpage and this may be particularly useful when you don't have different colour backgrounds to show you where the margins are. Of course, you could temporarily add a background in the developer tools if it makes it easier to see them. This is a really useful debugging tool."));
main.append(addSubHeader("Paddings, Margin and Border"));
main.append(addParagraph("There are a couple of peculiarities you may find with inline elements. The first is that they don't have a top or bottom margin. To illustrate this, we have an HTML file as follows (body only)."));
main.append(addInsetCodeListing(["<body>", " lt;p class=\"first\">Block</p>", " <p class=\"second\">Block</p>", " <span>Inline</span><span>Inline</span>", "</body>"]));
main.append(addParagraph("So, we have two paragraphs, which are block elements, and two span elements which are inline. There are no resets so we have browser defaults for margins, padding and so on. As a matter of interest, for the paragraphs, there is no padding and we have margins at the top and bottom of 16 pixels. The span elements don't have padding or margins."));
main.append(addParagraph("We can see this in boxmodel7.html, and you should pay particular attention to the spacing. This may be clearer if you inspect the elements in the browser developer tools. If we inspect one of the paragraphs, we can see there is no padding, there is a border of 1 pixel which I have applied in CSS, and there are top and bottom margins of 16 pixels but no left or right margins. Looking at the web page, that does look about right but there is a definite margin to the left and right. If we look at an ancestor element, and the obvious one body, we will see that there is a left and right padding of 8 pixels so this is being inherited by everything inside the body."));
main.append(addParagraph("We want to change the padding to see how this affects how the page is displayed and we will start by removing the padding from the bottom of the paragraph elements."));
main.append(addInsetCodeListing(["p {", " padding-bottom=0;", "}"]));
main.append(addParagraph("If we refresh the page, you'll notice that the gap between the two block elements doesn't change. This is because of the behaviour we referred to as margin-collapsing so there is no longer a margin at the bottom of the first paragraph, but there is still a margin of 16 pixels at the top of the second paragraph so the gap between the two is still 16 pixels. However, since there is no margin around our span elements, removing the bottom margin from the paragraphs means that there is now no vertical space between the bottom of the second paragraph and the inline elements and we can see this in boxmodel8.html."));
main.append(addParagraph("Let's take this a step further and set the margins all around a paragraph to 0. The result is shown in boxmodel9.html. Now, we can see that there are no margins between the paragraphs and the span elements or between the paragraphs themselves."));
main.append(addParagraph("I was surprised to see that we do still have margins to the left and right as well as a margin between the top of the viewport and the first paragraph, given that we have set all of the margins around the paragraphs to 0. Actually, we have already seen an explanation for this in that these margins are a property of the body element. The CSS for the p selector overrides this. However, the body is a container and it is very important to remember that. So, we have a scenario where the paragraphs have no margins, but these are contained inside the body element and so there are no margins between these elements and the body. Indeed, when we look at the elements in development tools, this confirms that there are no margins. However, if we select the body in the HTML, we will see that this is a box in itself containing the other HTML elements and there are margins between the body and the edges of the viewport. This is a crucial point because it is important to remember that margins exist between elements within a container. Potentially, almost any HTML element is a container and that certainly includes body so really, by setting all margins to zero, we have actually removed all margins between elements inside the body container, but the margins between the body and the viewport are still there so we can still see a gap around the edges of our viewport."));
main.append(addParagraph("If we concentrate now on those inline span elements, let's see what happens if we put a margin of 16 pixels around the edges of these elements. The result is shown in boxmodel10.html. This may look a little strange because we can see the horizontal margins but not the vertical margins. We can inspect one of these elements in the browser tools and we can see, there, that the element has a margin of 16 pixels on all sides. The reason we don't see this, certainly in terms of the top margin, is because vertical margins are ignored with inline elements. If we set the display property for span to inline-block, we now do see these margins all around as you can see in boxmodel11.html"));
main.append(addParagraph("If we remove the display property and margins from the span elements, there is something a little bit stranger and harder to explain here, as we can see in boxmodel12.html. We have removed all of the margins inside the body element, and as a result, we don't see any gap between the paragraphs or between the paragraphs and the inline elements. We do, however, still see a gap between the two inline elements. We can look at either of these and this will confirm that there are no margins. However, this comes from a line feed character in the HTML. I actually tried putting these on the same line with some spaces between the two elements which made no difference but when I removed the spaces between them, the gap in the web page also disappeared. This suggests, to me at least, that this is actually not a line feed but rather is any white space. In any case, we can fix it by ensuring that there is no white space between the elements. Unfortunately, while this does seem to remove that gap, it really does so at the expense of readability, which is probably why we would want them on separate lines. Another possible solution is to use a negative left margin to push the element over to the left a bit. If we do that using a type selector, this is going to move both of the inline elements over to the left which breaks the flow of the page a little bit and so is perhaps not the best solution. Having said that, another option might be to add a class attribute to the second inline element and use that to set the left margin to a negative value and that would work pretty well. It may also be worth noting that you cannot give a negative value like this to padding."));
main.append(addParagraph("Another solution is to set the font-size on the parent element to zero. On the face of it, this may seem like you should set the font-size of the body to zero, which would probably work but may have unintended side effects. A better approach would be to create, let's say, a div element and put our inline elements inside of that. We can then give it a class, which we will call margin, and we can then use this as a class selector to set the font-size to zero."));
main.append(addInsetCodeListing([".margin {", " font-size: 0;", "}"]));
main.append(addParagraph("This removes the gap, but the font-size is an inheritable property so the font inside the <span> elements now also has a size of 0, but we can set this back to an appropriate size by overriding the property."));
main.append(addInsetCodeListing(["span {", " font-size: 16px;", "}"]));
main.append(addParagraph("We can see the results in boxmodel13.html. You may have noticed that this gap was only visible because of the elements background colour and would have been impossible to distinguish otherwise, so in this example, the only reason for removing it is to make the display a little neater and you might even decide that it is better to keep it. There are some situations in which this technique can be useful such as where you have inline elements with a specific width inside a container which also has a specific width. However, we now have better layout techniques to handle this kind of situation and we will look at those later."));
main.append(addSubHeader("Margin and Layouts"));
main.append(addParagraph("Previously, we used a negative margin to make a slight adjustment to an elements positioning. It is possible to use much larger negative values which can push an element completely out of the normal flow, but this is generally considered to be bad practice because it's an indication that there is something wrong with your HTML, so reordering the HTML is a better option."));
main.append(addParagraph("Essentially, margins are not intended to be used to create your layout, but there is one way in which they can be really useful in helping to create an attractive layout. Consider the following HTML."));
main.append(addInsetCodeListing(["<section>", " <h2 class=\"sectiontitle\">Margin and Layouts</h2>", " <p>Previously, we used a negative margin to make a slight adjustment to an elements positioning. It is possible to use much larger negative values which can push an element completely out of the normal flow, but this is generally considered to be bad practice because it's an indication that there is something wrong with your HTML, so reordering the HTML is a better option.</p>", " <p>Essentially, margins are not intended to be used to create your layout, but there is one way in which they can be really useful in helping to create an attractive layout. Consider the following HTML.</p>", "</section>"]));
main.append(addParagraph("You can see this without any styling at margin.html. This is just a copy of the previous two headers and we have the elements stacked in the usual manner. Now, we will do a little bit of styling to make this a little fancier like this"));
main.append(addInsetCodeListing(["section {", " background: #03191E;", " color: #59F8E8;", " width: 800px;", " margin: 0 auto;", "}"]));
main.append(addParagraph("We are adding these styles using the type selector, section. The font colour has been changed to Turquoise Blue and the background to Rich Black. I have set a width of 800 pixels for section and applied margins of 0 to the top and bottom and auto to the left and right. The result of applying these styles can be seen in "));
main.append(addParagraph("Since the width of section is quite a bit less than the viewport width, the auto margins to the left and right are each using half of the remaining width and the result is that our content is centred right in the middle of the page. That's a useful layout technique, but it does give us one problem, at least in this scenario. Since the background colour has been added to section and section doesn't cover the entire width of the page, we have a block in the centre of the page with white space all around it. That is, the background colour doesn't extend to the edges of the screen."));
main.append(addParagraph("One way to solve this might be to add the background colour to the <body> and this would mean that the entire background in the viewport would be this Rich Black colour. Let's assume for the moment that this is just the first section in our web page and we actually want the colour background only in this part of the display - but we want it to extend right across the page. A simple solution that would achieve that would be to put our section inside a <div> element, like this."));
main.append(addInsetCodeListing(["<div>", " <section>", " <h2 class=\"sectiontitle\">Margin and Layouts</h2>", " <p>Previously, we used a negative margin to make a slight adjustment to an elements positioning. It is possible to use much larger negative values which can push an element completely out of the normal flow, but this is generally considered to be bad practice because it's an indication that there is something wrong with your HTML, so reordering the HTML is a better option.</p>", " <p>Essentially, margins are not intended to be used to create your layout, but there is one way in which they can be really useful in helping to create an attractive layout. Consider the following HTML.</p>", " </section>", "</div>"]));
main.append(addParagraph("We can now amend our CSS so that it looks like this."));
main.append(addInsetCodeListing(["div {", " background: #03191E;", "}", "", "section {", " color: #59F8E8;", " width: 800px;", " margin: 0 auto;", "}"]));
main.append(addParagraph("The <div> element does extend the width of the page and the section is centred in the <div> so we do see the colour being applied in the margins, as seen in ."));
main.append(addParagraph("As a quick aside, I have used the <div> element several times but I don't think I have ever mentioned anything about it. It is a really useful tag because it has no semantic meaning. This sounds like something of a contradiction in terms of what we have previously said about the need to ensure that your HTML is as semantically correct as possible. However, there are some situations where you need to put some elements inside a div just to give you a kind of hook where your CSS can be applied. In that sort of situation, having an element that has no semantic meaning is actually the best option since the element isn't intended to convey any meaning, it's just a useful container for other elements. In this case, it simply allowed us to add colour to the background so that we could set margins for the elements we were interested in without affecting the background."));
main.append(addSubHeader("Project: Adding Content Wrappers"));
main.append(addParagraph("We want to change the resume now so that our content is centred in the page, so we will have margins down each side, but we also want the background colours to extend to the width of the page. To do this, we will take each section in turn and put all of the content from that section inside a div which we will use for styling. For example, the content in the header section is inside the <header> element so it looks something like this."));
main.append(addInsetCodeListing(["<header>", " <h1>Christina Truong</h1>", " <h2>Tech Educator + Front-end Developer</h2>", " <p>As a developer, I specialize in creating modular and scalable front-end architectures. As an educator, I focus on creating inclusive learning environments, instructor training and curriculum development.</p>", " <p>I’m also exploring more creative pursuits designing tee shirts and accessories for <a href="http://teethang.com" target="_blank">Nuthin’ But a Tee Thang</a>, an online store I’m running with my husband.</p>", "</header>"]));
main.append(addParagraph("So we have two headings and two paragraphs inside the <header> element. We want to put all of these inside a <div> element which will be inside the <header> element so really, we are just adding another level to the DOM."));
main.append(addInsetCodeListing(["<header>", " <div class=\"content-wrap\"", " <h1>Christina Truong</h1>", " <h2>Tech Educator + Front-end Developer</h2>", " <p>As a developer, I specialize in creating modular and scalable front-end architectures. As an educator, I focus on creating inclusive learning environments, instructor training and curriculum development.</p>", " <p>I’m also exploring more creative pursuits designing tee shirts and accessories for <a href="http://teethang.com" target="_blank">Nuthin’ But a Tee Thang</a>, an online store I’m running with my husband.</p>", " </div>", "</header>"]));
main.append(addParagraph("As you can see, the <div> acts as a container for the rest of the HTML in this section and it has a class of content-wrap which we will use to apply our styling. Note that we are using <div> because this container doesn't add any meaning to the content, actually, the <header> element provides that. We have added similar <div> elements to the other sections, but they all have the same class so we can style all of the sections with one class selector and one declaration block. Since this CSS is being applied to the whole page, we will put it in the global section in our CSS."));
main.append(addInsetCodeListing([".content-wrap {", " width: 800px;", " margin: 0 auto;", "}"]));
main.append(addParagraph("So that gives us a width of 800 pixels and the auto margin causes the content to be centred on the screen. Just as a reminder, the background colour is set with a type selector of header (for this section or something similar for the others) so adding the new <div> element allows us to keep this style separate from the styling used to create the margins, so in this case, we didn't need to do anything additional to ensure that the background colour still spans the whole page."));
main.append(addParagraph("A quick aside here, in the video, Christina mentioned that if you are writing HTML in Atom, it has a really handy feature which allows you to type just the name of the tag and press tab. Atom them adds the angle brackets and a closing tag where required. It also automatically inserts some attributes for certain tags. For example, if you type div and press tab, you get this"));
main.append(addSyntax("<div class=""></div>"));
main.append(addParagraph("Similarly, if you type link and press tab, you get this"));
main.append(addSyntax("<link rel="stylesheet" href="">"));
main.append(addParagraph("or if you press img and tab, you get this"));
main.append(addSyntax("<img src="" alt="">"));
main.append(addParagraph("I don't use Atom, but I do have it installed so I tried it out and it works really well. I use Dreamweaver and it provides a similar feature although it doesn't give you a class attribute with div. You can find a list of these auto-complete shortcuts for Dreamweaver on GitHub here. There is also some information on Dreamweaver auto-complete and code completion on the Adobe website. There are some Dreamweaver course on LinkedIn training but I would advise you to be cautious with these because, in my experience, Dreamweaver tends to change quite rapidly so you really do have to ensure that any course is up yo date and I am not sure if there are any at the moment. Having said that, Dreamweaver CC Essential Training by David Powers which was published in 2017 is quite long at more than 8 hours and it probably contains a lot of information that is useful in the current version. Designing a First Website with Dreamweaver CC by Paul Trani is a bit more up to date, having been published in September 2019 but it seems to be more on the basics of designing a website rather than specifically using Dreamweaver."));
main.append(addParagraph("From looking at the contents, I can't see anything to suggest that either would cover these auto-complete options in much detail (I don't think this is really necessary in any case but it would be nice to see some more information on it), but this does make me wonder if there is anything else about Dreamweaver that I could do more easily if I knew more about the product."));
main.append(addParagraph("For example, I display a lot of HTML code in my web development pages and until now, the normal method I have used to do this is to type it directly into the code if I only needed one or two tags using the HTML entities, < and > in place of the tags angle brackets. For more complex code, I copy this into a Word document and do a global find and replace to convert all of the angle brackets to HTML entities that can be displayed on a page. However, I noticed today that if you type your code into the Design pane either in Split or Design mode, it automatically converts these for you so that will make things easier for me."));
main.append(addParagraph("For this reason, I think the courses may very well be worth completing because Dreamweaver is a complex product so it is useful to know as much about it as possible. There is, of course, the additional benefits that you can add it to your LinkedIn profile so it is also demonstrating to employers that you have knowledge of Dreamweaver."));
main.append(addParagraph("Going back to the project, we can look at the page and it looks pretty much as we would expect, but there is still a margin around the edges and this is something I discussed in the previous section. The margin that we can still see is the default margin for the <body> element. We can fix this by adding a margin of 0 to the body selector in the global section of our CSS. Although not required, it is also normal to set the padding for the body to zero at the same time since it wraps around all the content on the page and this makes it easier for to control where everything goes since you don't need to worry about any default styles being applied by the browser."));
main.append(addParagraph("You can see the revised version of the resume here or you can click the button at the bottom of the page to see any version of the resume. The blank areas to the left and right have now gone since we removed the margins, but we still see some blank space between the sections and between the top of the page and the top of the header as well as the bottom of the page and the bottom of the footer. In the next section, we will look into removing these spaces."));
main.append(addSubHeader("Project: Margin and Padding"));
main.append(addParagraph("We have seen hat there are still some spaces between the elements and because these are blank spaces (for instance, the space between the top of the page is white rather than the dark-blue background colour of the header) suggests that these spaces are the result of a value being set for margin somewhere. Elsewhere on the page, there does also seem to be gaps between the elements so this is the likeliest cause."));
main.append(addParagraph("We removed both padding and margins from the body, so the gap at the top is probably coming from the header. If that's the case, one option to remove these would be to remove the margins from all <h1>, <h2> and <p> elements. I have done just that and we can see the results in resume6.html."));
main.append(addParagraph("This has achieved the desired effect but because each of the elements has content which runs to the edges of the container, the result is that everything seems to be squashed together so this is not really a very good option. I have removed the CSS that was used to zero these margins and we will try a different solution, namely to add some padding to the containers for each section. You may recall that we used a class of content-wrap, and we can add our rule to add padding to the declaration block associated with this selector like this."));
main.append(addInsetCodeListing([".content-wrap {", " padding: 60px 0;", "}"]));
main.append(addParagraph("I can see that this has removed the gaps at the top and the bottom of the page, but it is less clear whether the gaps between the elements have been removed. However, using the browser developer tools, I can select various elements and it is clear from this that all of the gaps have disappeared. In addition, rather than the squished up appearance of resume6.html, we can now see that each element has plenty of space and looks well spaced out."));
main.append(addParagraph("It's not immediately clear to me why changing the padding should make these gaps disappear since these are caused by margins - so in essence, adding more space inside the elements has removed the space around the elements and this can be super-confusing. To get a better handle on this, we will go back to the browser developer tools and we will start by inspecting our container, the <header> element and we can see that there is our padding of 60 pixels, top and bottom and a margin of zero, top and bottom."));
main.append(addParagraph("If we look at the <h1> element, we can see more or less the opposite. We have 0 padding all round and a margin of 21.44 pixels, top and bottom. Bear in mind that the <h1> element is inside the <header> element. This means that the top margin, for example, is between the top of that <h1> element and the top of the <header> element. If we add padding of 60 pixels around the contents of the <header> element, that means that the margin is now inside this element (when there is no padding, the top of the <h1> element is also the top of the <header> element which means the margin is outside of it and as a result, we see the gap - in other words, the margin is visible."));
main.append(addParagraph("My expectation was that if the padding were reduced to a low enough size, say 10 pixels, since the margin is then larger than the padding, we would see some margin at the top of the element but this isn't the case."));
main.append(addParagraph("Even if the padding is reduced to 1 pixel, I can still an appreciable gap between the top of the content and the top of the <header>, but the margin between the top of the <header> and the top of the viewport is not there. I think that what is happening is that the padding is causing a separation between the <h1> and the header elements so the margin which is on the <h1> element is now between the top of the <h1> element and the top of the <header> element. Without the padding, the margin is between the top of the <h1> element and the top of the viewport. If we set padding at the top to 1 pixel, how have a separation of the <h1> and <header> elements so essentially from the top of the page you have, ignoring the horizontal dimensions for a moment, the top of the viewport then the top of the <header> with no padding or margin to separate them. You then have 1 pixel between the top of the <header> and the top of the <h1> which is the padding, then you have the margin which is now between the top of the <header> and the top of the <h1> and which is 21.44 pixels giving you an effective dimension for the padding of 22.44 pixels."));
main.append(addParagraph("If that is right, when we set the padding at the top to 60 pixels, the gap at the top is actually 81.44 pixels so this is equivalent to setting the margin on the <h1> to zero and setting the padding to 81.44. To test this theory, I have the page, resume7.html open and it is using a value for the padding-top of 60 pixels and a margin at the top of the <h1> of 21.44 pixels. Directly on the web server, I have edited the CSS file to set the padding to 81.44 pixels and the margin to 0 and refreshed the page and there is no change. So I think that I can say with some certainty that by having a positive value for padding on our wrap-content class, which is essentially the <header> element means that the gap we see at the top is going to be completely inside wrap-content and therefore will have its background colour set to dark blue, but the amount of the gap is calculated based on the size of the padding plus the size of the margin."));
main.append(addParagraph("Personally, I would be tempted to go ahead and remove the margins from the <h1>, <h2> and <p> elements and then set the padding to the desired value because this gives you more control over the amount of padding. For example, if we did that and set the value of our padding to 60 pixels, we will see a gap of 60 pixels around the inside of wrap-content. If we don't we might inspect the element and see that the padding is 60 pixels, but we would then have to look at the <h1> element to see that it has a margin of 21.44 pixels to know how much padding we really have."));
main.append(addParagraph("That being said, I don't think that you could look at this gap and tell by eye that it is 60 pixels or 81.44 pixels, so if you take the approach that you don't really care how much padding there is as long as the page looks code, you could argue that it doesn't matter since you will simply increase the padding if it looks too small or decrease it if it looks too big and this is a very pragmatic and sensible approach to web development so it may be that either method is perfectly fine to use."));
main.append(addParagraph("One difficulty that is presented by the fact hat we have left the margins and just added padding is that, as we saw, the amount of space between the elements is now governed by the margin that was already there and the padding we added. However, this will only give us consistent spacing if all of the relevant margins are the same size and this doesn't, in fact, seem to be the case. If we look at the Projects section in the developer tools, we can see the margin of 60 pixels is in place. If we select the first element inside of content-wrap, which is an <h2> heading,it has a top margin of 16 pixels, so this means that there is a little space at the top of the element although it is not particularly noticeable."));
main.append(addParagraph("The last element in content-wrap is an anchor tag and it has a bottom-margin of 0 pixels, so there is even less space at the bottom of projects and that is much more apparent. In addition, the button seems to be overlapping with the area at the bottom. To fix this so that he have the same amount of space between at the top and the bottom of the projects section, there are two things we need to do. First, we will remove the margin from the <h2> element so we will set that to zero. To fix the bottom, recall that inline elements don't align vertically when padding and margins are applied and this is why it is overlapping with the padding at the bottom."));
main.append(addParagraph("To fix that, we will add a display property to the link. You might remember that the links in the projects section were styled to look like buttons, so in the Projects section of the CSS, we will locate the selector .projects .btn and we will add a display property with a value of inline-block."));
main.append(addParagraph("We can save this and refresh the page and the spacing at the top and bottom of the Projects section looks much more consistent. We can also use the developer tools to look at the button at the bottom of the section and we no longer see the overlap."));
main.append(addParagraph("It may also be worth mentioning the fact that our resume page doesn't use any resets and this means that we do have the possibility, as we saw here, of different default margins appearing in the page. Christina mentioned that she prefers not to use a reset because she feels that it is better to set her own defaults, but I don't really agree with this. I think that it is easier to set your own defaults if you have a reset in place because then, for the most part at least, the only styles being applied will be the styles you have defined yourself."));
main.append(addParagraph("There is one thing that this exercise does demonstrate, for me at least, and I think this is also true whether or not you are using resets, is that a critical part of the process of developing your CSS is viewing the website and determining which parts need to be restyled to correct any problems. I do think that if you apply styles consistently, you are more likely to have an attractive design, but there will be times when even the most consistently applied CSS will not look quite right. So the sort of process Christina followed in deciding how to fix the problem here is a useful skill to have as a web developer."));
addSidebar("webdev");