Selectors
In order to style something, you need to be able to refer to it. You need to be able to tell the browser "style those things like that, and those other things like this."
Selectors is how do this. It is a way of 'selecting' elements of the page which the browser applies your formatting instructions to. You can be simple (eg every paragraph in the page), or more expressive (eg only the first paragraph inside the footer).
Element selectors
Element selectors allow you to style every element of a particular kind. This corresponds to the HTML element name. For example, you could style every level 2 heading (H2
) in a certain way, every image (IMG
) and so on.
h2 {
color: red;
}
img {
border: 1px solid black;
padding: 1rem;
}
Class selectors
Any HTML element can be assigned one or more classes, using the class
property.
Here, we assign the class 'thumb' and 'profile' to an IMG
tag:
<img class="thumb profile" src="123.jpg">
To select based on class names, we use the period (.
) prefix:
img {
padding: 0.5em;
}
.thumb {
height: 200px;
width: 200px;
}
.profile {
padding: 1em;
}
In the above example, we have three blocks of CSS. The first applies to any and all IMG
elements. The second block styles anything with the "thumb" class assigned, and likewise the third styles anything with a "profile" class.
All images will thus have a padding of 0.5em, but profile images will have a padding of 1em - the more specific class selector overrides the element selector.
Classes should ideally be semantic, meaning they relate to the role of the class or element(s), rather than its styling.
Eg, lets say you want to mark an error message in red. One approach might be to define a class called "brightRed" that colours the text. But what if you change your mind about how errors should be coloured? In other parts of your code when you assign the class, it might be easy to lose track of which class to use. Instead, you would define a class called "error", which semantically matches the role of the styling - to mark something as an error.
There are a few rules about how you name classes. No spaces, and generally you want to make them human readable. Eg: error
, hero-image
.
The same class name can be used for multiple classes, or even different kinds of elements. In your CSS, you can style things accordingly. In the below example, anything with the warning
class takes on a background and border, but H1
headings are also capitalised.
.warning {
background-color: lightgoldenrodyellow;
border: 1px solid orange;
}
h1.warning {
text-transform: uppercase;
}
Id selector
Any HTML element can have an id
attribute which uniquely identifies it. You set the id yourself, and ideally should be something meaningful. There are some rules about what ids are valid. As with class names, don't use spaces, strange characters, or begin with a number.
Here's an element with an id:
<div id="loginBox">
...content here...
</div>
To style this element, we use the id of the element prefixed with a pound sign (#
):
#loginBox {
border: 1px solid black;
padding: 1em;
}
Remember that we don't use the # sign in the HTML id
attribute, only when we refer to it in a selector.
You could, in principle, put an id on everything and style it that way, but it is a nightmare to maintain. Rather, you want to lean on the semantic structure of your HTML document when styling (in terms of choosing the right elements and organising your hierarchy) so that the document is self-describing. There are a few other reasons why over-using ids is a bad idea, but in general it boils down to ids being inflexible and difficult to maintain. If you find yourself adding ids to every element to style them you probably need to re-think your approach.
Combining selectors
You can combine selectors to be more specific. For example, you might use the class 'names' to refer to the use of names in your document. There will be some commonality with how these elements are styled, but in some uses, you want a different result.
To do this, add the class selector after the element selector, without a space.
.names {
color: blue;
}
button.names {
color: darkblue;
}
This means that all elements with the 'names' class will have blue text, but BUTTON
elements with that class will be dark blue instead.
Hierarchy
CSS selectors can also be based on the tree structure of your DOM. Eg, maybe you want to style A
elements that are inside of a FOOTER
differently than other A
elements.
A space between selectors means the tree structure is traversed. In the below example, the selector first matches the FOOTER
, and then matches A
elements that exist within it.
footer a { color: black; }
<a href="#">Link</a>
<footer>
<a href="#">menu1</a>
<a href="#">menu2</a>
</footer>
Another example. Lets say we have a multiple level ordered list (OL
element)
<ol class="names">
<li>Mary</li>
<li><ol>
<li>Sue
<li>David
</ol>
</li>
</ol>
We can style each list item within ordered lists with class names
as follows:
ol.names li {
line-height: 2em;
}
But what if we didn't want Sue and David styled, only Mary? If you want to restrict your selector the the immediate children of a selector use the angle bracket (>
):
ol.names>li {
line-height: 2em;
}
This will match the Mary list item (because its hierarchy path is ol.names>li
), but not Sue or David because their paths are: ol.names>li>ol>li
- Read more on combinator selectors with Codrops
Multiple selectors
You can reuse a set of rules and apply them to multiple selectors by simply listing the selectors with commas.
Below, the first block sets H1, H2 and H3 headers to red. The second block sets H1
and elements with the 'title' class to have a font size of 2em.
h1, h2, h3 {
color: red;
}
h1, .title {
font-size: 2em
}
Tip
It can help to figure out selectors by right-clicking on an element and selecting Inspect, or browsing for it in the browser's developer tools. You'll see a path which represents the element.
Below, we see 'html - body - div.thumbnails - div', for example:
Read more
- Attribute selectors (Codrops)
- Combinator selectors (Codrops)