CSS Selectors

Simple Selectors (Element Selectors)

here’s an example of a CSS rule:

em {
    color: red;
    font-weight: bold;
}

and here’s some HTML to which it can be applied:

<p>
   My two favourite kinds of ice cream are <em>chocolate</em> and
   <em>strawberry</em>.
</p>

here we are interested in selectors, the part that comes before the { of the rule

in this example, em is the rule’s selector

it means that the style that follows should be applied to all em elements on a page

so in the example, both “chocolate” and “strawberry” appear red and in bold

Class selectors

any HTML element can be given a class attribute

for example, here we add class="favourite to the second em element:

<p>
   My two favourite kinds of ice cream are <em>chocolate</em> and
   <em class="favourite">strawberry</em>.
</p>

if you view this HTML with the style rules from above, then it looks the same

you can apply a style to all elements with a class="favourite" attribute with this CSS rule:

.favourite {
    background-color: yellow;
}

note the . in front of the name favourite

that . is what indicates this is a class selector

the .favourite selector selects all element with class="favourite"

the elements do not have to be the same, for example:

<p>My two favourite kinds of ice cream are <em>chocolate</em>  and
<em class="favourite">strawberry</em>.</p>

<p>Here are some foods I like:
    <ul>
        <li>carrots</li>
        <li>cheese</li>
        <li class="favourite">watermelon</li>
        <li>cookies</li>
    </ul>
</p>

both an em element and an li element have class="favourite"

both of those then get the style .favourite style applied to them

Multiple Classes in an HTML Element

you can give an HTML element multiple classes by separating class names with a space like this:

<em class="favourite food">strawberry</em>

this em is in both the favourite class and the food class

Good Class Names

generally, you should use class names with a clear semantic meaning

for example, class names like “important”, “warning”, “note”, etc. are useful names

such names describe the purpose of the class, not the visual look and feel (which is set within the CSS rule)

ID Selectors

every HTML element can be given an id attribute that assigns a unique name to that element

an id must be unique on the page: no two elements on the same page should have the same id

for example, here we have added two id attributes:

<p id="startpara">My two favourite kinds of ice cream are
<em>chocolate</em>  and <em class="favourite">strawberry</em>.</p>

<p>Here are some foods I like:
    <ul id="foodlist">
        <li>carrots</li>
        <li>cheese</li>
        <li class="favourite">watermelon</li>
        <li>cookies</li>
    </ul>
</p>

to apply a CSS style rule to an element with a particular idea, put a # in from of the idea name in the selector, e.g.:

#startpara {
    border: 1px solid black;
}

#foodlist {
    background-color: green;
}

The Universal Selector

If you want a style to be applied to all HTML elements, use the selector *, e.g.:

* {
    border: 1px dashed red;
}

this puts a red dashed line around all the HTML elements on a page

this might actually be useful for debugging, i.e. it shows you the sizes and positions of all the boxes on the page

Combinators

CSS has some special selector symbols called combinators that let you select elements in more subtle ways

the combinators we’re going to look at are ,, space, >, +, and ~

here is the HTML that following examples refer to:

<section>
  <p>Everyone loves sand castles!</p>

  <h2>How to Make a Sand Castle</h2>
  <pre>SC = Sand Castle</pre>
  <p>Find a nice sandy beach.</p>
  <p>Bring a pail and shovel.</p>

  <div>
    <h2>Details</h2>
    <p>Pour water onto the sand.</p>
    <p>Scoop it into your pail with the shovel.</p>
  </div>

</section>

to help understand the following selectors, draw the DOM tree of the above HTML — it makes things much clearer!

, applies a style to 2 or more elements, e.g.:

/* both h2 and p elements get the style */
h2, p {
    color: green;
}

/* all header elements get the same style */
h1, h2, h3, h4, h5, h6 {
    font-family: helvetica, 'sans serif';
}

space selects all elements embedded within an element, e.g. this styles all p elements in the section element:

section p {      /* space combinator example */
  color: blue;
}

> selects immediate children of an element, e.g. section > p styles the first two p elements (the p elements in the div are not styled by this because they are not immediate children):

section > p {    /* child selector example */
  background-color: yellow;
}

+ selects the first following element at the same hierarchical level, e.g. this styles the first p element that occurs after the “Details” h2 element:

h2 + p {        /* adjacent sibling selector */
  text-transform: uppercase;
}

~ selects all following elements at the same hierarchical level, e.g. this styles all the p elements:

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

as mentioned above, the best way to understand how these selectors work is to draw the DOM tree for the HTML

Attribute Selectors

attribute selectors let you apply styles to elements based on their attributes or values

attribute selectors are recognized by their []-brackets

for example, suppose you have this HTML:

<ul>
    <li data-amount="3" status="ok" onloan="1">shoes</li>
    <li data-amount="2" status="needmore dirty">socks</li>
    <li data-amount="5" status="lots clean">shirts</li>
    <li data-amount="1" status="ok clean">hats</li>
    <li data-amount="5" status="lots dirty">gloves</li>
    <li data-amount="0" status="ok">bow ties</li>
</ul>

then you can assign styles by selecting on attributes as follows:

/* All elements with the attribute "onloan" have a border on the left*/
[onloan] {
    border-left: 1px dashed;
}

/* All elements with the attribute "data-amount"
   with the exact value "0" is made red, bold, and shadowed */
[data-amount="0"] {
    color: red;
    font-weight: bold;
    text-shadow: 1px 1px 2px black;
}

/* All elements with the attribute "status", containing the value "ok"
  (even if there are others) is green. */
[status~="ok"] {
    color: green;
}

there are also substring attribute value selectors that give you even more control, but we won’t do anything more than mention them

Pseudo-classes

pseudo-classes are selectors that let you select elements based in part on the state of the element

for example, consider this HTML:

<p>
    I like <a href="https://en.wikipedia.org/wiki/Cookie">Cookies</a>
    and <a href="https://en.wikipedia.org/wiki/Ice_cream">ice cream</a>.
</p>

you can change the style dynamically when the mouse pointer hovers over an a element using the :hover pseudo-class:

a:hover {
    text-shadow: 1px 1px 2px black;
}

you can also change the style for links that have been visited, e.g.:

a:visited {
    color: brown;
}

there are many other pseudo-classes that we will use on occasion

Pseudo-selectors

pseudo-selectors are similar to pseudo-classes, but they begin with :: instead of :

for example, this style rule will dynamically add a ! to the end of the body text of a elements when the mouse hovers over it:

a:hover::after {
    content: "!";
}

there are man pseudo-selectors, and you can look them up in a CSS reference if you want to learn what others can do