Introduction to CSS Selectors

In this chapter, we're going to be looking at and using CSS Selectors to apply specific styles to specific elements. We'll overview the advantages these have over one another, and some example ways of using them in your code.

CSS Selectors are the methods used to select the element to which our styling will be applied to. There are five ways to do this[7], and these are element, class, ID, attribute and pseudo. These can be used to section off styles, and then apply them to HTML elements further down the line. We will discuss them in further details in each of their sections below.

Element Selector

Element selectors always use the element name. For example, when wanting to select a <div> element, you would use the div CSS selector. The only real caveat to this selector is that it will select every <div> element on the page, and apply styling to them all.

  1. div { text-shadow: 1px 1px 3px #000000; }

There is a way to narrow down the selection, and hierarchical styles will help with this. For example, if you want to apply styling to every <p> element inside every <div> element, you would use the div p CSS selector. That space between div and p is important, it essentially means select every 'p' element that is inside every 'div' element.

  1. div p { font-size: 12pt; }

There is another way to select multiple elements. For example, the following block of code can be compressed.

  1. h1 { font-size: 14pt; }
  2. h2 { font-size: 14pt; }
  3. h3 { font-size: 14pt; }

As you can see, each of these three element selectors have the exact same styling applied to them: setting the font size to 14 points. When noticing common styling between selectors, you can compress them by separating them with commas, like below:

  1. h1, h2, h3 { font-size: 14pt; }

This single line is the exact same as the block of code above, however the commas separating each element selection is the same as saying select every 'h1', 'h2' and 'h3' elements. If you omitted the commas, it would be saying select every 'h3' element that is found in every 'h2' element that is found in every 'h1' element, meaning it'll only apply in the following circumstances and will only style the innermost element.

  1. <h1>
  2. <h2>
  3. <h3>Only this element will by styled. Also, don't do Headings this way.</h3>
  4. </h2>
  5. </h1>

In addition to the method of selecting multiples above, and also selecting all child elements within an element, these can be paired together to produce effects along the lines of Select every 'a' and 'p' elements inside every 'div' element. This utilises comma separated and space separated element selectors, as below:

  1. div a, p { background-color: #DEDEDE; }

ID Selector

ID selectors are based on element ID Attributes. This works well, because it means you can apply styles to specific elements by its ID, rather than "every element". The "every element" rule is still applied though. If you mistakenly use the same ID on multiple elements, the styling will be applied to all elements with that ID. However, a major rule of thumb when writing HTML pages is that no two elements should have the same ID[8]. ID's are supposed to be unique Identifiers[9]. This is a caveat to the ID Selector, however when used with other selectors, it narrows down your selection drastically.

ID's are added to elements using the id attribute. As stated above, ID's have to be unique, only one per element, and each one different. As CSS Selectors, they can be accessed with the # symbol, followed by the value given in the ID attribute. Written like the following:

  1. <h1 id="my_id">Some Heading</h1>
  1. #my_id { font-size: 24pt; }

ID's can also be combined with other selectors. For example, if you want to select every <a> element inside a <div> with the ID of main, you can use the following:

  1. #main a { color: deepskyblue; }

Since you can only have one ID per element in each page, this can help narrow down your selection to a specific area of you page. For example, on this page, if we have a <div> element with the ID of main. The above block of code will select every <a> element within it, but it will ignore all of the <a> elements elsewhere on the page.

Class Selector

Class selectors are very similar to ID selectors, as in that they are set by using element attributes, however classes can be applied to multiple elements at once. When using the selector, the same applies to every element with 'classname' applies, but this works best when wanting to style a block that will repeat over and over. For example: styling tables that you plan on using repeatedly.

As CSS selectors, they can be accessed with the . symbol, followed by the value given in the class attribute. Written like the following:

  1. <h1 class="my_class">Some Heading</h1>
  1. .my_class { background-color: #DEDEDE; }

Again, similar to above, you can use combinations of selection methods to select specific elements according to their hierarchy. Additionally, you can omit the space between the element selector, and class selector, which will imply a select all elements with the class of 'my_class'. Although the same can be done with ID selectors, it's easier to understand with class selectors. For example: The code to execute select all 'p' elements, and all 'a' elements with the class 'my_class', that are contained in every 'div' element will look like:

  1. <div id="my_id">
  2. <p>A paragraph is here</p>
  3. <a class="my_class" href="page1.html">Page 1</a>
  4. <a href="page2.html">Page 2</a>
  5. </div>
  1. #my_id p, a.my_class { background-color: #80081E; }

This CSS selection will select the element on line 2, and line 3, but not on line 4. Note the lack of space between a and .my_class. If there were a space between them, it would say select every element with the class of 'my_class' inside every 'a' element, along with every 'p' element that is contained within every element with the ID 'my_id'. This rule would make the <a> element not be styled, but if there was an element inside the <a> element that had the class .my_class, that would be styled instead.

In addition to the above selection rules, you can apply multiple class selections to the same element by separating the class names with spaces in the attribute value, like the following block of code.

  1. <div class="pretty_box hidden">
  2. <!-- This a comment, some stuff can go in this box. -->
  3. </div>
  1. .pretty_box {
  2. border: 1px dotted #60AFFE;
  3. border-radius: 25px;
  4. }
  5. .hidden { display: none; }

The above code will apply both the .pretty_box and .hidden styling to the same element. This situation is ideally used with a scripting language like JavaScript where you can add and remove classes that apply different styles from the same stylesheet.

Attribute Selector

Attribute selectors can be used to select elements based on their attributes, allowing you to style every element that has a certain attribute or attribute value. For example, styling every hyper-link that starts with "https://" to let you add a little padlock by it, showing the link is secure. There are various methods to using Attribute selection, because you're mostly dealing with strings, you can make selections based on if an attribute starts with something, or ends with something, or contains something.

This is an example of the attribute selection, that will select elements based on attributes.

  1. [target] {
  2. background-color: #FEF1F0;
  3. }

The above code will select every element that has the target attribute in it. The target attribute is often used in <a> elements to tell browsers how to deal with a link, by opening it in a new tab or window, or in the current window, or in a specified <iframe> element. This can be used with other selectors, to select elements that have a target attribute, but only if they're inside a div with the id of "main", and so forth.

Attribute selectors can also be used to select things depending on the attribute value too.

  1. a[href^="https"] {
  2. color: green;
  3. }

For example, this code will select every <a> element that has a href attribute that starts with "https". As you may already know, the HTTPS protocol is the secure one through SSL, and this code will colour each link green that uses HTTPS. The ^= operator here is the section that says If the attribute value starts with this, select it.

There are other operators which have different meanings. Here's a list all of them.[10]

  • = Is Equal To EG: [target=_blank] Selects: <a target="_blank">...
  • ~= Space Separated EG: [title~=previous] Selects: <a title="next and previous">...
  • |= Hyphen Separated EG: [lang|=en] Selects: <html lang="en-gb">...
  • ^= Starts With EG: a[href^="http"] Selects: <a href="">...
  • $= Ends With EG: a[href$=".zip"] Selects: <a href="">...
  • *= Contains EG: a[href*="google"] Selects: <a href="">...

Pseudo Selector

Pseudo selectors are the most interesting. They are selectors that are extremely specific, or only happen under certain circumstances. Some of the more common ones are hover, visited and link. Pseudo selectors are accessed with the : and :: symbol, and commonly come after another selector, as in the examples below:

  1. a:link { background-color: #AFFE60; }
  2. #my_id:hover { padding-left: 4px; }
  3. .my_class:visited { color: #6600FF; }
  4. p::first-letter { font-size: 20pt; }

When placed directly next to another selector, it implies that selection in addition to the previous selection. For example, the :hover selector will only apply the styling if the cursor is hovering over the element. Because it is 'bound' to the .my_class selector, it will only apply the styling when you hover the cursor over an element that has the class .my_class.

There are Pseudo selectors for a variety of selections[11], and a good one for use across pages is the :target selector. This often doesn't need to be 'bound' to another selector, it can be standing alone like all other selectors. This selector is special in that it will only respond to # links in the URL address bar. A prime example of using this is when you click a citation link on one of these pages. It will direct you to the Bibliography page, and show you the citation by applying a pale blue background. This uses :target to know what is selected in the URL address bar.

Another good use is to use :nth-child(odd/even) selector. This is ideally used for lists or tables, where you would like every other line to have a different coloured background. For example, the following code will make the background slightly lighter than the global background for the element, but only for odd selections:

  1. table {
  2. background-color: rgba(128, 128, 128, 1.0);
  3. color: white;
  4. border-collapse:collapse;
  5. }
  6. td {
  7. padding: 4px;
  8. border: 1px solid black;
  9. }
  10. tr:nth-child(odd) { background-color: rgba(255, 255, 255, 0.4); }
Row 1, Col 1Row 1, Col 2
Row 2, Col 1Row 2, Col 2
Row 3, Col 1Row 3, Col 2
Row 4, Col 1Row 4, Col 2

There are also Pseudo selectors ideal for <form> elements too. With :enabled and :disabled which can style elements based on if you can interact with them, :checked to make checkboxes and radio buttons appear differently when checked, and :valid and :invalid to change style if the user inputs (in)valid data. Quite a few of these Pseudo selectors are designed around this interactivity that web pages have, with a lot of the newer Pseudo selectors only being available since CSS3.

Continue to Chapter 3 - CSS Hierarchical Styling