CSS Normalization and Resets
We saw, previously, how browsers have some default styles so if you create a webpage without any CSS, when the user views the page, they will still see some styling. Both resets and normalization represent techniques to remove these defaults so that the only styling is whatever the developer creates - so essentially, we are starting with a clean slate and we don't have to worry about conflicts between the default styling and our own.
You can write your own reset sheet by creating a stylesheet that sets these styles to 0 (for example, you can reset all of the heading styles so that the browser doesn't render them in different size) or you can get a stylesheet from the Internet. The latter can either be by including that CSS stylesheet in your own project or linking externally to the sheet so that every time the page is opened, an external call is made to the website hosting the stylesheet so that it can be applied to your site.
The original reset sheet was created by Eric Meyer and you can get some information on this from EricMeyer.com and you can download it from here.
If you want to incorporate this into your own site by linking to the original file, you would do that with a normal CSS link like this.
<link rel="stylesheet" type="text/css" href="http:/meyerweb.com/eric.tools/css/reset/reset.css">
Another reset sheet which is a little more up to date can be found on the HTML5 Doctor site. This omits some of the deprecated HTML elements from Eric's site and adds a few more modern elements. Tim Murtaugh's reset sheet can be downloaded from GitHub and this is based on the sheets from Eric and the HTML5 Doctor and adds some of his own.
These reset sheets can, and perhaps should, be seen as a starting point and you can adapt them as required. For instance, rather than remove the defaults, you might want to replace them and, as an example, provide your own default styles for headings so that you are still starting out with default styles, but they are your own defaults.
Another approach is to normalize the CSS. This is not a completely different approach to resets and is actually sometimes referred to as the new reset. It doesn't try to reset the styling for all HTML elements, but tried to be a bit more targeted in that it only resets the defaults that the developers think are least useful. It is still based on a stylesheet and you can download this from necolas.github.io. As with resets, this should be used as a starting point and you can tailor it to your own requirements.
You can use any of these in your own projects, but you shouldn't combine them because that could lead to duplicate or conflicting styles. The best approach is probably to pick the one which does the best job for you off the bat and then customize it if you want to include your own defaults.
Working with Fonts
When working with fonts, there are four most commonly used properties and these are
font-family
font-weight
font-style
font-size
Let's say we want to set values for these to style the text in paragraphs. A typical block of rules might look like this.
p { font-family: "Times New Roman", Times, serif; font-weight: bold: font-style: italic; font-size: 14px }
They seem fairly straightforward, but it is worth looking at each of these in turn.
font-family
This is probably the most confusing, it lists three fonts and this is actually a prioritized list so the font used will be the first one in the list that the browser recognizes. The last one, serif, instructs the browser to use the system default if none of the others are available.
font-weight
This is perhaps a surprisingly complex property and there are two ways to specify a value for font-weight. You can use a descriptive term such as normal or bold or use a numerical value, 100, 200, 300 and so on up to 900 - as you might expect, the higher the number, the bolder the font. You can get a full list of these values on the w3.org website under CSS Fonts Module Level 3
font-style
This is a little more straightforward, having only three values, normal, italic or oblique. It is important to remember that not all fonts will support all possible values for any of these properties. Where it doesn't, the browser will try to provide the best possible solution. With font-weight, that would usually mean that it would use the closes possible available weight but with font-style, if you want italics but the font doesn't support it, the browser will often try to italicize your text by simply tilting it. This may be acceptable but it is probably going to be a case of trying out to see whether the effect works or not.
font-size
Specifies the font size!
Fonts are normally organized in two groups, system fonts and web fonts. These are fairly straightforward and probably available on any machine today. You can see a list of web-safe fonts that you can use with more or less complete confidence in the fact that they will be available to users.
You can also use a font-that is not installed on the client's machine by specifying a web font. There are several ways to do this but the one offering the best cross-browser support is probably font-face you can get more information on this on the CSS Tricks website. This is added to your stylesheet before any other styles and looks like this.
@font-face { font-family: 'MyWebFont'; src: url('webfont.eot'); /* IE9 Compat Modes */ src: url('webfont.eot?#iefix') format('embedded-opentype'), /* IE6-IE8 */ url('webfont.woff2') format('woff2'), /* Super Modern Browsers */ url('webfont.woff') format('woff'), /* Pretty Modern Browsers */ url('webfont.ttf') format('truetype'), /* Safari, Android, iOS */ url('webfont.svg#svgFontName') format('svg'); /* Legacy iOS */ }
Essentially, this creates a font-family called MyWebFont which you can then apply to an element list any other font.
body { font-family: 'MyWebFont', Fallback, sans-serif; }
You can also use the CSS @import rule which allows you to import style from other stylesheets. This method is not recommended because it is not particularly efficient but you can check out the documentation on MDN.
You can also incorporate web fonts by a linking to a stylesheet or by loading the font via JavaScript. The latter of these is quite common nowadays, particularly when working with services such as Google fonts or Typekit.
When it comes to Web Development, Typography is a pretty large subject and there are complete courses dedicated to it such as CSS: Advanced Typographic Techniques by James Williamson. The course is from 2013 so it may be a little dated now but it does cover some very useful techniques for working with text.
Understanding the Box Model
The box model is fundamental to the layout of web pages. It describes the rules relating to the physical properties of HTML elements.
Let's say we have a <p> element such as this one, Now, imagine that there is an invisible rectangle surrounding the element. It has a number of properties including margins, borders, padding and content width and height. The border is the invisible rectangle but it can be styled so that it becomes visible. Sometimes, when I am developing a site, I will make these borders visible when when I don't want them to appear in the final version of the page, because making some of the elements visible in this way can be a huge help when you are trying to work out if all of the elements of the page are where they should be. You wouldn't do this with elements as small as a paragraph, but with much broader elements such as the header, sidebar or other major components of the page layout.
It is important to remember that these properties don't just have an impact on the element itself, but also on how it related to the other elements around it. There is a good description of this on the W3 Schools website.
From the inside out, the properties are:
content - this is the actual text contained within the element padding - the gap between the content and the border - the main properties associated with the border are border-width, border-style and border-color border - the container, in effect, for the text margin - the gap between the border and surrounding elements
When calculating the height and width of the element, this is the height and width of the box defined by the border, so it doesn't include the margin but does include any padding. However, the width of the margin does need to be taken into account when determining how much space the element takes on the page. As a result, the total width of an element is given the width of the left border + the width of the left padding + the content width + the width of the right padding + the width of the right border. Similarly, the total height is given by the content height plus widths of the top and bottom borders and the top and bottom padding.
The box sizing property can help avoid problems with this. Consider the following rules.
.box { width: 300px; padding: 10px; border: 1px solid block; box-sizing: content-box }
Normally. the width property defines the content-width and that is the case here. This gives us a total width (the left and right borders have a width of 1 pixel and the width of the left and right padding is 10 pixels on either side) of 322 pixels. On the other hand, with the following rules
.box { width: 300px; padding: 10px; border: 1px solid block; box-sizing: border-box }
the only change is to the value of the box-sizing property which is now set to border-box. This has the effect of stating that the width property should now apply to the width of whole box, including the padding and borders. So now, the total width is 300 pixels and if we subtract the widths of the borders and the padding from this, we get 278 pixels and this is now our content width.
The box model is very useful, but there are a few pitfalls to be aware of.
If a property is not declared, this doesn't necessarily mean that it has a property of 0. Remember that there may be defaults styles or even inherited styles which set the a value for the margins, padding and so on.
You can set the width of an element to a percentage, so let's assume that you have a percentage of 100%. If you have used the box-sizing property with a value of border-box, this would give you a total width of 100%. However, if you have a value of content-box, the total width is going to be more than 100%. This is often not a major issue, but it can cause problems with your layout.
There is more to the box model, but these properties will be sufficient to control the total width of the elements on your page.
Just a quick aside here, in this section, the height property seems to be overlooked on occasion. As a general rule, any principle applicable to width will also apply to height, and that includes the box-sizing property.
Margins and Padding
We can either specify padding as individual properties like this
p { padding-top: 10px; padding-right: 10px; padding-bottom: 10px; padding=lef:10px; }
Please do bear in mind that if you don't specify a value for padding, this does not automatically mean that it will have a value of 0 pixels.
An alternative to specifying each margin is to use a shorthand version. In the example above, we set each of the margins to 10 pixels. We can do this with a single rule.
p { padding: 10px 10px 10px 10px; }
The order doesn't matter too much here since we are specifying 10 pixels for all of them, but the order is top, right, bottom, left.
If we omit one of these values
p { padding: 10px 12px 10px; }
The order is top, left/right, bottom. So in this example, the first parameter sets padding-top to 10 pixels, the seconds sets padding on both the right and left to 12 pixels and the third sets padding-bottom to 10 pixels.
Since the top and the bottom values are the same, and the left and right values are the same, we can also do this with two parameters.
p { padding: 10px 12px; }
The order is top/bottom and left/right so this sets padding on both the top and bottom to 10 pixels and to both left and right to 12px.
Finally, if all four values are the same, we only need one parameter so
p { padding: 10px; }
Will set the padding for top, bottom, left and right to 10 pixels.
There are a couple of things that you need to be aware of with respect to padding. Most elements are block level elements so if you don't specify a width, the element will expand to fill the width of its parent. If you don't specify a width, this can lead to an unexpected value for the height because the element may be stretched to fit the parent width. As was mentioned earlier, if you specify a width of 100%, the padding can cause the element's width to be more than 100% of the width of the parent, unless we use the box-sizing property with a value of border-box.
One feature of margins that you should be aware of is that vertical margins collapse whereas horizontal margins do not. What this means is that if you have two elements, one on top of the other, and let's say the upper element has a bottom margin of 10 pixels, and the lower element has a top margin of 10 pixels, these will overlap giving a total distance between the two of 10 pixels, rather than the 20 pixels you might be expecting.
Borders and Backgrounds
As with padding and margins, you can set properties for each edge of the border individually or you can use the same shorthand. For example, if you want to set the colour for the top and bottom to darkblue and the left and right to black, you can do it like this.
p { border-color: darkblue black; }
If you want to set all three of the main properties for each border edge, there is a shorthand for that. Let's say you want to set the top border to a width of 1 pixel, solid and black. You can do that with.
p { border-top: 1px solid black; }
If you want to do this for the whole, border, that is you want all four edges to have a width of 1 pixel, a style of solid and a black colour, you can do that with
p { border: 1 pixel solid black; }
There are 10 possible values for border style, including none and hidden and you should bear in mind that the border width can be taken into account when calculating the total width of an element. It may be important to remember that some of these styles require a border width of more than 1 pixel.
Another possibly useful feature of border is that you can use it to effectively create a frame around some text since you can set it's colour independently from the foreground or background colours of its element.
Outlines are similar to borders but there are a few differences. Unlike borders where each edge can be styled independently of the others, an outline can only be styled as a single entity. So, all sides will have the same width, colour and so on.
It is also not part of the box model so it doesn't have any impact on positioning, either for the element it surrounds or for adjacent elements. It is less commonly used than borders, but it is useful from a semantic perspective to indicate a relationship between the elements it contains and this can be helpful for accessibility reasons.
The background property is quite useful for producing some interesting visual effects. The background is not really part of the box model, but it may be helpful to describe it in those terms. The background of an element is basically everything within the border so it does include the area created by the padding property. It should be noted that most HTML elements, by default are transparent, so if you add a background, such as a solid colour, the contents of the element will be displayed on top of that background (which you probably could have guessed based on the name)!
As well as a single colour block, a background can also be an image or a gradient.
If you have an image as the background, you can control certain aspects of the way in which it is displayed such as the position, whether it repeats horizontally pr vertically and whether it should be clipped within the background area.
Since the image doesn't necessarily fill the element, you can create some nice effects by, for instance, specifying a background colour and a background image. Background images are layered on top of the background colour so this means that the colour will fill in the part of the element not covered by the image. And remember that the elements contents will go on top of both, if it has any.
For a nice demonstration of how a background image can be useful, check out the home page for WordPress (this will open in a new tab). At the top of the page, we have a header with a black background. Actually, although this seems to be, at first glance, white text on a black background, it's actually an image with the WordPress Logo. If we inspect this element, we can see that it is inside a <h1> tag and has a background image with a URL pointing to the logo. The element itself is shown below.
<h1><a href="//wordpress.org">WordPress.org</a></h1>
There is some text in the heading, but it isn't visible in the webpage and we can see why this is if we look at the CSS for that element. This is shown below.
#wporg-header h1 a { display: block; background: url(//s.w.org/style/images/wporg-logo.svg?3) center left no-repeat; -webkit-background-size: 290px 46px; background-size: 290px 46px; height: 88px; text-indent: -9999px; }
The interesting points for now are the background property and the text-indent. The text indent has a value of -9999px which is well outside the viewport, meaning that the text will never be visible. This could have been omitted and the effect, visually, would be the same. However, including the content can be useful for accessibility purposes in that it tells the browser what this heading actually is. So that's a neat demonstration where we can have some text in the heading which will be recognized by the browser, but visually, the site is going to display the logo rather than the text.
Working with Colour
In CSS, working with colours will often mean working with background colour, border colours or colours (that is, the colour for an element which usually sets the font colour - this is sometimes referred to as the foreground colour).
There are several options you can use when specifying a colour such as the predefined CSS keywords, white, black, red and so on which map to a specific combination of RGB values. You can also use a 6 digit hexadecimal number to represent the colour with #000000 representing black, #FFFFFF representing white and so on. There is also a shorthand version of this for websafe colours which you can use when you have three pairs of identical digits so, for example, #000000 can be expressed as #000, #0088FF as $08F and so on. In this scenario, if you have a three digit number, you just need to repeat every digit (that is #08F becomes #0088FF and so on.
An alternative notation to RGB is HSL which specifies the hue, saturation and lightness. The hue is specified as a number between 0 and 360 which represents degrees in a colour wheel. For example, green is 120, blue is 240 and red is 360. Both saturation and lightness are expressed as a percentage. A saturation of 0% would effectively give you greyscale since there is 0% of the specified colour and 100% would gives you the colour fully saturated. Similarly, with lightness, 100% will give you bright white and 0% will give you black.
With the introduction of CSS3, both RGB and HSL offer an alpha option which is essentially a fourth value which can be between zero and one and it allows you to define transparency settings for any colours (backgrounds, borders or foreground colours). Note that although the alpha parameter seems to have a small range of potential values, it is in effect also a percentage value. For example, if you set the value to 0.5 on an element, that element will be 50% transparent.
One final point to make is that you don't necessarily have to calculate the different values to achieve the desired colour, in most cases, you can use some sort of colour picker. Most web development tools such as Dreamweaver, allow you to select a colour in this way when setting a colour value. If you are developing your CSS using a text editor such as Notepad++, Sublime or even Vim, you can use an online colour selector which will allow you to do this. An example of this is on the W3 Schools website. You can use this to pick a colour and the site will generate the appropriate RGB and HSL values matching that colour. If the colour matches one of the CSS keywords, it will also give you that.
The W3 Schools website provides a lot of information on colours for websites and provides some other tools for selecting colours. A very useful too is the Complementary Color Schemes tool which provides a colour wheel. In theory, colours on diametrically opposing sides of the wheel should complement each other. If you pick a colour, let's say yellow, there is a little display which shows a colour scheme incorporating your selected colour and the opposite colour so that's a nice tool to help decide on a cohesive scheme.
Another really cool feature on the W3 Schools website is 'Color Trends' which shows you some of the most fashionable colours of the year from 2016 up to 2021. The colour scheme for my web development pages is based on The Hottest Spring/Sommer Colors 2021.
Units of Measurement
There are several ways to specify the dimensions of an element and we have already seen several examples where dimensions, usually width but occasionally height, was expressed in terms of pixels. This is a fixed size (that is, 10 pixels may be different on various devices but it is always 10 pixels) so it is an absolute definition.
You can also specify dimensions in relative terms, particularly in the form of ems. As an example, let's say that your browser's default font-size is 16 pixels, if you define the font-size of an element as 50%, this would be 8 pixels. This is expressed as a multiple of ems like this
p { font-size: 0.5ems; }
The main advantage of this approach is that the default font size can change depending on the platform or whether the user has changed the default font size. If your font sizes are expressed as ems, the relative sizes of the various elements will stay the same. For example, if the font size for <p> elements is 0.5 ems, 1.0 ems for <h2> elements and 2.0 ems for <h1> elements, regardless of the actual sizes, <h1> elements will always be twice as large as <h1> elements and these will be twice as large as <p> elements. Note that for ems, the default size is the font-size of the parent element.
Similar to ems is rems (or root ems) which are also relative sizes. However, where the default font size for ems is taken from the parent element, the default font size for rems is taken from the root element. This can mean having more control over the relative sizes of the fonts in your site. There is some debate as to which of these methods is best, but ultimately the best approach is probably to be consistent in their use.
Another option is to specify sizes as a percentage but this is usually used with block elements. For example, you might specify the width of your navigation bar to be 100% which should mean that it fills the width of any viewport. There is a more detailed video on these measurements, Understanding units of measures in CSS which is part of the course, CSS Positioning Best Practices by Bill Weinman. Note that this course may be interesting for a quick watch, especially as the lectures are given by Bill, but it was published in 2009 so it would probably be a little out of date now.
Vendor Prefixes
Vendor prefixes allow us to specify new CS properties that are not supported by all browsers. Essentially, a vendor prefix for a particular browser is put at the front of the property name so that when the CSS is being parsed by a browser, it will ignore any rules that specify the vendor prefix for a different browser. Let's take the transition property as an example.
-webkit-transition: all 0.1s ease-in-out; -moz-transition: all 0.1s ease-in-out; -ms-transition: all 0.1s ease-in-out; -o-transition: all 0.1s ease-in-out; transition: all 0.1s ease-in-out;
Note the syntax, there is a hyphen at the start and end of the vendor prefix followed by the property. The video is quite short and not very detailed, but I would assume that this is a bad example because it looks like the same property is being applied on all browsers but I would guess that we might specify this for only the browsers we want to apply the rule. Another possibility is that we might apply the rule in a certain way, with specific options depending on the browser and perhaps another rule specified without a prefix to be applied for all other browsers.
We looked at caniuse.com earlier and this can be extremely useful when determining whether vendor prefixes are required. Since most modern browsers offer very good support for CSS, vendor prefixes are less common nowadays so it probably not a very important topic, but more information can be found on the ThoughtCo.com website.
You may well see vendor prefixes in older code so it is worth being aware of them and it can be useful to know what the prefixes are for each vendor. For reference, these are
-webkit- Android browsers, iOS, Safari and Chrome -moz- Firefox -ms- Internet Explorer -o- Opera
Challenge
The challenge, here, is similar to the previous challenge in that we will start with a simple unstyled webpage which you can find here (opens in a new tab).
The unstyled sheet can be seen . Clicking the link will open the page in a new tab.
As before, we will add some CSS styling to this page, but this time we will do it by way of an external stylesheet, which I have called solution3.css. The styles to be applied are as follows.
For both the header and the footer 1. Set the wrapper width to 70% 2. Set the background colour to purple 3. Set colour to white 4. Apply padding of 30 pixels on all sides For the middle section, set a border 1. Add a top and bottom margin of 10 pixels 2. Set a border, solid black with a width of 1 pixel
Solution
There are essentially two sets of rules here, the border around the middle section and the rules relating to the header and the footer. The middle section just needs a border. The first thing I want to do is to set the width to 70%. I can do that for the top and bottom sections, but I don't want the middle section to stretch out beyond the others, especially since it has a visible border, so I will apply the width to the wrapper.
wrapper { width: 70%; }
The middle section is styled like this.
section.content { border: solid black 1px; margin: 10px 0px; padding: 30px; }
The remaining rules relate to both the header and footer, which have classes of header and footer respectively. Both of them are contained within the <div> with class wrapper, as is the middle section. To keep things simple, I will just use the class names. The rules for both are the same so I can use one set of rules for both as follows.
.header, .footer { width: 70%; background-color: purple; color: white; padding: 30px; }
The completed solution can be seen in the Solution, here.