CSS: Understanding the Important Basics. (CSS Selectors and Combinators)

Codesader
6 min readFeb 19, 2023

--

Photo by Jeffrey Leung on Unsplash

Check out PART ONE here.

CSS Selectors and Combinators

  1. Child combinator ( > )
  2. Descendant combinator ( )
  3. Adjacent sibling combinator ( + )
  4. General sibling combinator ( ~ )
  5. Universal selector ( * )
  6. Type selector ( any HTML tag e.g div, p, section etc)
  7. Id selector ( # )
  8. Class selector ( . )

As I mentioned in the previous part of this five series article, this is another critical basics of CSS that must be learned religiously in order to truly demystify or grasp CSS.

Note: Although this series is for anyone who is interested in learning CSS, it is rather geared towards people who have a basic understanding of CSS but still find it somewhat challenging.

Selectors in CSS is how we target or select specific element on the webpage.

Combinators help you select or target certain element(s) based on its relationship with another element.

Without this capability, it is impossible to uniquely style individual element in CSS.

Yes, we all know and use class selector, but using classes only in our HTML, at a certain point, creates certain challenges. Namely,

  1. unnecessary cluttering of our HTML,
  2. name conflicts,
  3. codes which are difficult to manage etc

Again, I know you are most likely familiar with class, type and id selectors but are you truly harnessing the real power of CSS if you are neglecting the crucial CSS selectors and combinators?

Well, there is only one way to find out.

Without further ado, let’s get into it.

Universal Selector

The universal selector selects every HTML elements on the webpage. This is denoted using the asterisk symbol ( * ).

<div>
<header>The banner</header>
<main>
<h1>Title</h1>
<p>paragraph</p>
<article>
an independent article
</article>
</main>
<footer>
copyright 2023
</footer>
</div>
* {
border: 1px solid green;
padding: 5px;
margin: 1rem;
}

The above code gives every element on the page, including the body and html tags, a border, padding and margin properties.

Child combinator ( > )

A child combinator selector makes it easy to target the direct child or children of an element. i.e any element(s) which is directly nested in another element is considered the child(ren) of that element.

A child combinator is denoted using a greater than symbol ( > ) between the elements we want to target. e.g div > p

Consider the code below. The h1 and p tags are directly nested in the div tag which automatically makes them children of the div

<div>
<h1>A cool title</h1>
<p>hello world!</p>
</div>
div > p {
font-size: 3rem;
color: blue;
}

In the above code, although both the h1 and p tags are direct children of the div element, only the p tag is targeted. If we have more than one p tags as the children, the properties will be applied to them all. And if we were to target all the children of the div tag. It would look as below:

div > * {
font-size: 2rem;
color: blue;
}

Both the h1 and p tags will be targeted because the * symbol is a general selector which will target all the children of the div

Descendant combinator.

Unlike child combinator selector, descendant combinator gives us more freedom to select descendant elements that may or may not be the direct child(ren) of that element. In other words, any element that is directly nested, or element(s) nested inside another nested element etc can be selected.

A descendant combinator is denoted using a space between the elements we want to target. e.g div p

<div>
<h1>A cool title</h1>
<p>Paragraph 1!</p>
<section>
<h2>Another title<h2>
<p>Paragraph 2!</p>
<article>
<p>paragraph 3!</p>
</article>
</section>
</div>
div p {
font-size: 2rem;
color: blue;
font-weight: 700;
}

As you can see from the example code above, even though the p tag nested inside the sectiontag and articletag are not a direct child of the divthe styling properties got applied to all the p tags on the webpage nonetheless. The level of nesting does not really matter so long it is a descendant of the element.

Adjacent sibling combinator ( + )

There are instances where you might need to target element which is immediately next in line to another element (adjacent element). In other words, using a sibling element to target another sibling that is directly below it. Knowing this combinator makes targeting sibling elements — without having to rummage through hundreds or thousands of code to identify that particular element — easy.

Adjacent sibling combinator is denoted using a plus symbol ( + ) between the elements we want to target. e.g button + p

<article>
<h2>Another title<h2>
<button>submit</button>
<p>Paragraph 2!</p>
</article>
button:hover + p {
background-color: red;
}

The p tag gets a background of red once we hover on the button tag as it is immediately next in line to the button. This is so because the articletag is the parent to h1 , button and p elements, which makes the three siblings.

General sibling combinator ( ~ )

Unlike adjacent sibling combinator, this particular combinator gives you more freedom to target as many siblings as you want regardless of whether they are next in line to each other. This means you can use one sibling to target several other sibling elements at a go.

General sibling combinator is denoted using a tilde symbol ( ~ ) between the elements we want to target. e.g button ~ p

<section>
<h2>Another title<h2>
<button>submit</button>
<p>Paragraph 2!</p>
<article>I am just a piece of article</article>
</section>
button:hover ~ article {
border: 1px solid red;
}

Note: You can only target elements downwards not upwards for both adjacent sibling and general sibling combinators. i.e only sibling(s) down below another sibling element can be targeted. i.e in the code above you can use button to target p or article because they are below button, but you cannot use button to target h2 because h2 is above button . However, h2 can target button .

Type selector (any valid HTML tags)

This is perhaps the most straightforward of the selectors. It targets any type of element in the html document as long as it is a valid tag or element. Put the name of the tag and write out any styling you wish to apply to it.

<div>
<section>
<p>section paragraph</p>
<p>second paragraph</p>
</section>
<article>
<h1>Article Heading</h1>
<p>article paragraph</p>
</article>
</div>
p {
color: red;
font-size: 12px;
}

article {
padding: 1rem;
background-color: #eaeaef;
width: 200px;
}

section {
padding-inline: 2rem;
padding-block: 1rem;
margin-block-end: 1rem;
background-color: #ddd;
}

The above code example targets all the selected elements p ,section ,article on the webpage and applies the specified properties to each of them.

Id selector ( # )

Id is an attribute which can be given to any valid HTML element. Id selector lets you create a unique element on the document by targeting the element with its id attribute. Once an element is given an id, no other element on that webpage can be given that same id. In other words, they are unique.

An id selector is created by preceding the name of the id with a hash sign ( # ) e.g #hero-section

<div>
<header id=hero-section>This is a header</header>
<main>
<section>
<p>main content comes here</p>
</section>
</main>
<footer>
<p>copyright 2023</p>
</footer>
</div>
#hero-section {
background-color: red;
font-size: 3rem;
text-align: center;
padding: 2rem;
color: #fff;
}

The code example above targets that particular element with the unique id, in this case hero-section, and gives it the properties specified in the css code.

Class selector ( . )

This is another attribute which can be given to any valid HTML element. Any element given class attribute can be easily selected or targeted. The name of the class can be any identifier you choose to give to it.

We select the element by preceding the name of its class with a period ( . ) e.g .first-paragraph

<div>
<h1>A cool title</h1>
<p class="first-paragraph">hello world!</p>
<p class="second-paragraph">Paragraph 2!</p>
</div>
.first-paragraph {
border: 1px dashed red;
font-size: 16px;
font-style: italic;
padding: 1rem;
}

Thank you for taking the time to read.

If you find this article useful please share it with your friends. While at it, please drop a comment. Your feedback is really important.

--

--