Selectors

There are 4 different types of selectors and 2 different ways to combine selectors in a single rule.  Below is a nice description copied from mozilla’s website.

  1. Simple selectors: Match one or more elements based on element type, class, or id.
  2. Attribute selectors: Match one or more elements based on their attributes/attribute values.
  3. Pseudo-classes: Match one or more elements that exist in a certain state, such as an element that is being hovered over by the mouse pointer, or a checkbox that is currently disabled or checked, or an element that is the first child of its parent in the DOM tree.
  4. Pseudo-elements: Match one or more parts of content that are in a certain position in relation to an element, for example the first word of each paragraph, or generated content appearing just before an element.
  5. Combinators: These are not exactly selectors themselves, but ways of combining two or more selectors in useful ways for very specific selections. So for example, you could select only paragraphs that are direct descendants of divs, or paragraphs that come directly after headings.
  6. Multiple selectors: Again, these are not separate selectors; the idea is that you can put multiple selectors on the same CSS rule, separated by commas, to apply a single set of declarations to all the elements selected by those selectors.

Lets look at each of of these below.


Simple Selectors

When the name of an element is used as a selector all of the elements of that type in the web page are stylized.  We saw this earlier when we used p as the selector.

p {
    font-family:Verdana;
    font-size: 24px;
 }

We can also stylize a single element in a HTML page.  To do so, we use #identifier as the selector where identifier is the value of the element’s id attribute.  For example if we have declared an element with the id attribute set to “nav_bar” then we can stylize that element using the following syntax.

#nav_bar {
    /* style declarations */
}

Recall that more than one element can belong to the same class.  We can apply a set of style declarations to all of the elements belonging to a particular class by using .class_name as the selector where class_name is the value of the class attribute for a set of HTML elements.

.keypad_button {
    /* style declarations */
}

Attribute Selectors

Attribute Selectors select elements based on whether or not they have a specific attribute or dependent on the value of an attribute.

There are 7 different types of attribute selectors. Each is defined within braces [ ].

Has Attribute
[attr] selects all elements that have an attribute named attr.
Has Exact Value
[attr=val] selects all elements that have an attribute named attr whose value is set to val.
Has Exact Value or Starts With Language Coded Substring
[attr|=val] selects all elements that have an attribute named attr whose value is set to val or begins with val-.
Contains Substring (may not include spaces)
[attr~=val] selects all elements that have an attribute named attr whose value contains val, where val is a string that does not include spaces.
Contains Substring (may include spaces)
[attr*=val] selects all elements that have an attribute named attr whose value contains val, where val is a string that may include spaces.
Begins with Substring
[attr^=val] selects all elements that have an attribute named attr whose value begins with val.
Ends with Substring
[attr$=val] selects all elements that have an attribute named attr whose value ends with val.

Example

Lets examine the example given in the mozilla documentation.

file.html

Ingredients for my recipe: <i lang="fr-FR">Poulet basquaise</i>
<ul>
  <li data-quantity="1kg" data-vegetable>Tomatoes</li>
  <li data-quantity="3" data-vegetable>Onions</li>
  <li data-quantity="3" data-vegetable>Garlic</li>
  <li data-quantity="700g" data-vegetable="not spicy like chili">Red pepper</li>
  <li data-quantity="2kg" data-meat>Chicken</li>
  <li data-quantity="optional 150g" data-meat>Bacon bits</li>
  <li data-quantity="optional 10ml" data-vegetable="liquid">Olive oil</li>
  <li data-quantity="25cl" data-vegetable="liquid">White wine</li>
</ul>

file.css

[data-vegetable] {
    color: green;
}

[data-vegetable="liquid"] {
    background-color: goldenrod;
}

[lang|=fr] { 
    font-weight: bold; 
}

[data-vegetable~="spicy"] {
    color: red;
}

[data-vegetable*="not spicy"] { 
    color: green; 
}
[data-quantity^="optional"] {
    opacity: 0.5;
}

[data-quantity$="kg"] {
    font-weight: bold;
}

The above code produces the following HTML:

Ingredients for my recipe: Poulet basquaise

  • Tomatoes
  • Onions
  • Garlic
  • Red pepper
  • Chicken
  • Bacon bits
  • Olive oil
  • White wine

Pseudo-classes

A CSS pseudo-class filters a set of elements (selected with another selector) selecting only those that are in a particular state.  The filter is defined by appending a colon (:) after a selector, followed by a pseudo-class keyword. Pseudo-classes allow us to select, for example, elements that are

  • :hover – selects elements under the cursor in the selected set
  • :first-child – selects the first element in selected set
  • :last-of-type – selects the last element in the selected set
  • :nth-child(n) – selects the nth element in the selected set

Note that many of the pseudo-classes in the Mozilla list are experimental and are not yet implemented in all browsers.  Check the compatibility tables before using.

Example

Consider the following HTML and CSS:

Homepage: <a href="https://n0code.net">n0code.net</a>
a:hover {
    color:red;
    font-weight:bold;
}

The above code produces the following HTML:

Homepage: n0code.net

Pseudo-elements

Pseudo-elements create “pseudo” elements with the specified styles that are inserted into existing elements.  They are defined by appending a colon (:) after a selector followed by a pseudo-element keyword.  Below are the most commonly used pseudo-elements.

Append as Last Child
::after { … }
Insert as First Child
::before { … }
Apply to First Letter of First Line of Block Element
::first-letter { … }
Apply to First Line of Block Element
::first-line { … }

Example

Consider the following HTML and CSS:

<p>of the United States, in Order to form a more perfect Union, establish Justice, 
insure domestic Tranquility, provide for the common defence, promote the general Welfare, 
and secure the Blessings of Liberty to ourselves and our Posterity, do ordain and 
establish this Constitution for the United States of America.</p>
p::before {
    content:"We the People ";
    font-size:24px;
    font-weight:bold;
}

The above code produces the following HTML:

of the United States, in Order to form a more perfect Union, establish Justice, insure domestic Tranquility, provide for the common defence, promote the general Welfare, and secure the Blessings of Liberty to ourselves and our Posterity, do ordain and establish this Constitution for the United States of America.


Combinators

Combinators allow for the selection of nodes based on the ancestry of the nodes in the DOM.  There are four types of combinators.

Descendents
elm1 elm2 { … } stylizes all elements of type elm2 that are descendants of elements of type elm1.
Direct Children
elm1 > elm2 { … } stylizes all elements of type elm2 whose parent element has type elm1.
Next Siblings
elm1 + elm2 { … } stylizes the all elements of type elm2 that are the next sibling of an element of type elm1.
All Siblings that Follow
elm1 ~ elm2 { … } stylizes all elements of type elm2 that are siblings that follow an element of type elm1.

Note: elm1 and elm2 can be defined by any of the selectors discussed above. As an example, see the last two rules in the example below.  

Example

Consider the following HTML and CSS from the mozilla documentation.

file.html

<main>
    <h1>Heading 1</h1>
    <p>Paragraph 1</p>
    <p>Paragraph 2</p>
    <section>
        <h1 id="heading2">Heading 2</h1>
        <p>Paragraph 3</p>
        <p class="second">Paragraph 4</p>
    </section>
</main>

file.css

main p {
    width: 150px;
    color: blue;
}

main > p {
    background-color: yellow;
}

h2 + p {
    text-transform: uppercase;
}

h2 ~ p {
    border: 1px dashed black;
}

#heading2:hover ~ [class=second] {
    font-weight:bold;
}

#heading2:hover ~ p::after {
    content:"!";
}

The above code produces the following HTML:

Heading 1

Paragraph 1

Paragraph 2

Heading 2

Paragraph 3

Paragraph 4


Multiple Selectors

Multiple selectors allow us to apply the same rule to multiple sets of elements.

Multiple Selectors
selector1, selector2 { … } stylizes all elements selected by selector1 and selector2.