Learn CSS in 45 Minutes (Part 2)

This lesson expands upon the previous CSS lesson and focuses on learning CSS selectors and some more CSS effects.

To begin, you may remember that in our last CSS lesson we touched upon using the element tags in order to apply CSS. While this is not a bad approach at all, it runs into problems when we want to include more than one of a particular HTML element on a page, without necessarily having to style them the same way. The solution is to use CSS selectors.

As you may have noticed from previous lessons, or from looking at other HTML on your own that many HTML elements contain attributes such as id, class, name, and so on. While these attributes may serve as a way to tell the developer what the HTML element is for, more often they are used as CSS selectors in order to apply the proper CSS styles.

To see an example of this, suppose we had the following code. We want to have the first paragraph be green and the second paragraph to be blue. Any idea how we can accomplish this?

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>My First Website</title>
</head>
<body>
<p>My first paragraph</p>
<p>My second paragraph</p>
</body>
</html>
One solution, which was mentioned in the previous CSS tutorial is to use inline styles for each of the paragraphs, which specifies which color should be used for that specific paragraph. However, this gets tedious very quickly. Suppose we added a third paragraph and wanted that, too, to be blue. If we chose to use inline styles, we would have to go in and manually add that style. The better solution, which makes use of either an internal or external style sheet, is to use CSS selectors, like below:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>My First Website</title>
<style>
.greenPar{
  color: green;
}
.bluePar{
  color: blue;
}
</style>
</head>
<body>
<p class="greenPar">My first paragraph</p>
<p class="bluePar">My second paragraph</p>
</body>
</html>

My first paragraph

My second paragraph

As you can see, we have added a few things to the code. First, we have changed the paragraphs to include a class attribute. For the first paragraph, we have assigned its class to be 'greenPar'; for the second paragraph, we have assigned its class to be 'bluePar'. Then, in our internal stylesheet, we have added .greenPar{ color: green; } and .bluePar{ color: blue; }, which changes the text color of each paragraph. As you might have guessed, the paragraph with class 'greenPar' will now be colored green and the paragraph with class 'bluePar' will now be colored blue.

Exercise 1:

Suppose we now wanted to add a third paragraph, like we talked about above, and we wanted it to be blue. Without changing or adding any CSS code, how could we make sure that it will be blue?

Since we now have the CSS in place that changes any element with class 'bluePar' to have blue text, we can simply add a new <p class="bluePar"> element, like below.

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>My First Website</title>
<style>
.greenPar{
  color: green;
}
.bluePar{
  color: blue;
}
</style>
</head>
<body>
<p class="greenPar">My first paragraph</p>
<p class="bluePar">My second paragraph</p>
<p class="bluePar">My third paragraph</p>
</body>
</html>

My first paragraph

My second paragraph

My third paragraph

As you can see, the class attribute is useful since it allows us to apply the same styling to a number of different elements, without relying on that element type. For example, we could use the 'bluePar' class on more than just <p> elements -- we could have <h1 class="bluePar">, or <div class="bluePar">, or even <form class="bluePar">. In all these cases, any text within the scope of the specified element will follow the rules specified as part of our attached CSS: in this case, making the text color blue.

Now suppose that we wanted all of a particular type of element to have blue text, but we wanted one particular element to have larger font. (For now, we'll continue our use of <p> as the example element, but these examples apply to almost any element you choose.) The easiest way to apply a style to all of a particular type of element is, as you saw in the last CSS lesson, is to invoke the CSS on that element type, itself.

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>My First Website</title>
<style>
p{
  color: blue;
}
</style>
</head>
<body>
<p>My first paragraph</p>
<p>My second paragraph</p>
<p>My third paragraph</p>
</body>
</html>

My first paragraph

My second paragraph

My third paragraph

Great! Now anytime we create a new paragraph, we know it will have blue text. But suppose we wanted the second paragraph to have larger text than the other two paragraphs, like we mentioned. How would this be accomplished? We could use a class like we did previously. In fact, this is probably what we should do if we wanted to reuse this styling on a number of different elements. However, if we wanted specific styling dedicated to only a single element, we would be better of using the id attribute, as shown below.

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>My First Website</title>
<style>
p{
  color: blue;
}
#bigText{
  font-size: 200%;
}
</style>
</head>
<body>
<p>My first paragraph</p>
<p id="bigText">My second paragraph</p>
<p>My third paragraph</p>
</body>
</html>

My first paragraph

My second paragraph

My third paragraph

The advantage of the id attribute over the class attribute in this case is that, in proper HTML, there will never be two elements on the same HTML page with the same id. Think of it like your real life ID (identity/identification). Just like your ID tells everyone who you are in such a way that you cannot be mistaken for someone else, so, too, does the id attribute tell the CSS which specific element to apply styles to, without fear of the style being applied to more than one element.

Wait a minute...

Now, before we get too far, I want to see if you've been paying close attention. Have you noticed anything funny about our CSS so far? If so, good! You may have noticed that when we wanted to apply styles to a type of element (e.g. <p>), our CSS code was preceded by the element type: p{ ... }. For the cases where we wanted to apply styles to a particular class of elements (e.g. <class="bluePar"), our CSS code was preceded by a period followed by the class name: .bluePar{ ... }. Finally, when we wanted to apply styles to an element with a particular element using its id (e.g. <id="bigText"), our CSS code was preceded by a pound/hashtag followed by the id name: #bigText{ ... }. What is the reasoning behind this?

Selecting CSS elements

To learn about all of the possible ways in which to select a CSS element, feel free to check out w3's documentation here. This document gives explanations and examples for each type of CSS selector, while this lesson only touches on those that are the most popular.

The simple answer to this question is that the CSS uses these to determine which types of elements to apply the appropriate styles to! So all HTML elements can be styled by using their element type as the CSS selector:

p{
  ...
}
h1{
  ...
}
div{
  ...
}

Likewise, all HTML classes can be styles by using their class name, preceded by a period as the CSS selector:

.greenPar{
  ...
}
.bluePar{
  ...
}
.myNewClass{
  ...
}

And, as you should now expect, all HTML ids can be styled by using the specified id, preceded by a pound/hashtag as the CSS selector.

#bigText{
  ...
}
#myNewId{
  ...
}
#yourOldId{
  ...
}

Furthermore, you are not limited to just an element type, class, or id as a CSS selector, these just happen to be the most common types of selectors in use. In fact, you can use any HTML element attribute as a CSS selector. Consider the following HTML:

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>My First Website</title>
<style>
[name=myPar]{
  color: red;
}
</style>
</head>
<body>
<p>My first paragraph</p>
<p name="myPar">My second paragraph</p>
<h1 name="myHeader">My header</h1>
<p>My third paragraph</p>
</body>
</html>

My first paragraph

My second paragraph

My header

My third paragraph

In this case, we changed the color of all elements with a name attribute equal to 'myPar' (and ignored the <h1 name="myHeader"> element, since its name did not equal 'myPar'). To do this, we simply preceded the appropriate CSS with square brackets and, within the square brackets, specified the attribute we wanted to apply styles to (i.e. name) and the value of that attribute (i.e. myPar). This guarantees that only those elements that have a name attribute and whose name attribute is equal to 'myPar' have the styles applied. Suppose, however, that we didn't care what the name attribute's value is; rather, we only care whether or not an element has a name. In order to apply this style, we simply need to remove the equality check from the CSS.

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>My First Website</title>
<style>
[name]{
  color: red;
}
</style>
</head>
<body>
<p>My first paragraph</p>
<p name="myPar">My second paragraph</p>
<h1 name="myHeader">My header</h1>
<p>My third paragraph</p>
</body>
</html>

My first paragraph

My second paragraph

My header

My third paragraph

Now, any HTML element that has a name attribute will have its color set to red, regardless of the name attribute's value (we now include the <h1 name="myHeader"> element).

Great, right? But suppose we now only wanted to apply the CSS to those elements that were paragraphs and had the name attribute. Again, this is easily accomplished from within the CSS.

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>My First Website</title>
<style>
p{
  color: blue;
}
p[name]{
  font-size: 200%;
}
</style>
</head>
<body>
<p>My first paragraph</p>
<p name="myPar">My second paragraph</p>
<h1 name="myHeader">My header</h1>
<p>My third paragraph</p>
</body>
</html>

My first paragraph

My second paragraph

My header

My third paragraph

We've now excluded the <h1 name="myHeader"> element again, because, although it contains a name attribute, it is not of element type p.

Exercise 2:

The answer to the first question is that we could use the following CSS selector: .myClass[name=myName]. As you can see, you can mix the CSS selectors amongst themselves just like you can mix HTML elements. However, this isn't the only solution. Another solution might be to reevaluate exactly why you want that CSS selector in the first place. Perhaps it would be better to simply make a new class attribute and apply styles on that class only.

Remember: It's important to consider why you are approaching a problem a certain way. Is it because it's the only way? Or because it's the best way? Or simply because it's the only way you have thought of so far?

One problem you might run into (which we saw in the previous HTML lesson) is that you might want the same style to be applied to multiple different HTML elements, but it isn't a good idea to add them to the same class. An example of this might be if you wanted each of the <table>, <th>, and <td> element types to have a border. While this could be accomplished by adding a class, having to type out class="..." for each of the table rows and table cells is a waste of time. Instead, you can simply apply the CSS to multiple elements as shown below:

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>My First Website</title>
<style>
table {
  border-collapse: collapse;
}
table, th, td {
  border: 1px solid black;
}
</style>
</head>
<body>
<table>
<caption>Caption here!</caption>
<thead>
<tr>
<th>Cell 1</th>
<th>Cell 2</th>
</tr>
</thead>
<tbody>
<tr>
<td>Cell 3</td>
<td>Cell 4</td>
</tr>
</tbody>
<tfoot>
<tr>
<td>Cell 5</td>
<td>Cell 6</td>
</tr>
</tfoot>
</table>
</body>
</html>
Cell 1 Cell 2
Cell 3 Cell 4
Cell 5 Cell 6

Applying the same style to multiple CSS elements is accomplished by using a comma to separate each CSS selector: in this case, table, th, and td.

Another useful CSS selector to know is the child selector, which requires understanding what HTML considers a child. We say an HTML element has a child, or child element, when there exists another HTML element within its scope. We say that an HTML element has children when there are more than one HTML elements within its scope.

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>My First Website</title>
</head>
<body>
<div>
<h1>My site</h1>
<p>Lorem ipsum</p>
</div>
<p>Another paragraph</p>
</body>
</html>

In the above example, the <div> element has two children: the <h1> element and the first <p> element. However, the <body> element only has one child: the <div> element. The <h1> element and the <p> element are not considered to be children of the <div> element, since they are not immediately within the scope of the <body>.

To use the child selector in our CSS, we can use the following CSS:

div > p {
  color: red;
}

My site

Lorem ipsum

Another paragraph

By applying this CSS to the prior HTML code, we can see that the paragraph within the <div> is colored red, but the paragraph outside the <div> remains black. This is because we added the greater than/closing angle bracket symbol between the div and p as part of our CSS selector. This shows that the <div> contains <p>.

Wow! We've made some great progress so far. However, there is one very important CSS selector that we are forgetting about. Suppose I had a <div> element, but wanted the background color of each of the elements to be blue. How would I accomplish this? One way might be to change the background color of the entire <div> element. While this might be want I wanted, it wasn't what I asked for (and it may not yield the result I wanted or expected!). So how do I apply the background color to each of the <div>'s children without applying it to the entire <div>, itself? The solution is the wildcard (*) operator, as seen below.

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>My First Website</title>
<style>
div > * {
  background-color: blue;
}
</style>
</head>
<body>
<div>
<h1>My site</h1>
<p>Lorem ipsum</p>
</div>
<p>Another paragraph</p>
</body>
</html>

My site

Lorem ipsum

Another paragraph

By using the wildcard, I am essentially telling the CSS to look for all elements that are children of a <div>: in this case, the <h1> element and the first <p> element. This not only saves work (rather than having to apply this style to each of the child elements individually), but also produces the intended effect.

Exercise 3:

Suppose you are given the following code.

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>My First Website</title>
</head>
<body name="myBody">
<section id="firstSection">
<p class="myText">
Welcome
</p>
</section>
</body>
</html>

More CSS examples!

Wow! Fantastic job at getting this far! Although learning about CSS selectors is essential to mastering CSS, I understand that it's probably not as much fun as actually learning about the different CSS effects that are possible. As such, I'll end this lesson with a number of different CSS examples and effects!

Margin

margin: 40px: This sets the top, right, bottom, and left margins to be 40px, which provides white space around your element.
Hello there!

Padding

padding: 40px: This sets the top, right, bottom, and left padding to be 40px, which provides white space around the content of your element.
Hello there!

Max Width

max-width: 200px: This sets the max width of your element to a particular pixel size -- in this case, 200px.
Hello there!

Line Height

line-height: 1.5: This sets the line height of your element (that is, the space between your element and other elements) to be 1.5 times the default size. (In the example below, the line-height is set to 5 to make the difference more obvious.)

Hello there!

Hello there!

Hello there!

Border

border: 1px solid blue: This sets the border of your element to be 1px wide, solid, and blue. (Alternatively, you can choose from a number of other border style options beyond solid, including dotted, dashed, and many more!)

Hello there!

Font Family

font-family: 'Times New Roman', serif;: This sets the font of your element to be 'Times New Roman', which is of type serif.

Hello there!

Exercise 4:

Now it's your turn! See what you can do with the styles you now know. Or, if you have something in mind that you'd like to do, try to find and example of it online!

Great job! Let's review what we've covered today:

Congratulations for completing this lesson! Hopefully, you are now able to apply CSS more effectively, in that you can apply repeated effects more easily and also in that you can better select single elements to apply styles to. Additionally, with the additional CSS effects included, you now have a greater array of CSS "weapons" in your arsenal, allowing for greater control over the appearance of your website. That's all for now - stay tuned for future lessons!