topic: CSS by Milos Protic relates to: Web Development, Advice, Selector on January, 01 2020
10 Useful and Hard-To-Remember CSS Selectors
Introduction
It's been a while since I wrote an article about CSS and in this article, I would like to cover some of the hard-to-remember CSS selectors which can help us pick the right element in some of the edge cases.
I like to say that everything (mostly related to styling) that can be done with CSS it shouldn't be done with JavaScript. I've seen in practice that people tend to use JavaScript when they are missing knowledge about CSS selectors to style, most commonly, dynamically created content on the web page. I will show you a couple of CSS selectors that can help you grab and style that type of content. Stay tuned!
Selectors
Below is the list of selectors that are suitable for our use case. Enjoy!
nth-child(odd|even|n)
This selector can help us find an element within a certain group. An important thing to mention here is that it selects the element among its siblings. Let's see it in action.
<ul class="list">
<li class="list-item">List item 1</li>
<li class="list-item">List item 2</li>
<li class="list-item">List item 3</li>
<li class="list-item">List item 4</li>
<li class="list-item">List item 5</li>
<li class="list-item">List item 6</li>
<li class="list-item">List item 7</li>
<li class="list-item">List item 8</li>
<li class="list-item">List item 9</li>
<li class="list-item">List item 10</li>
<li class="list-item">List item 11</li>
<li class="list-item">List item 12</li>
<li class="list-item">List item 13</li>
<li class="list-item">List item 14</li>
</ul>
Now, if we wanted to select every second (even elements) list item within the list, we could do it in one of the following ways:
ul.list > li:nth-child(even) {
color: orange;
}
/* or */
ul.list > li:nth-child(2n) {
color: orange;
}
On the other hand, what if we want to select every second element, but starting from the first one (odd elements)? We also have two ways of doing this:
ul.list > li:nth-child(odd) {
color: orange;
}
/* or */
ul.list > li:nth-child(2n+1) {
color: orange;
}
2n+1
selector tells the engine to take every second element starting from the first one. But, as you guessed, this can be modified to cover more scenarios, for example, pick every third element starting from the fifth. Pretty neat, right? The selector for this example looks as follows:
ul.list > li:nth-child(3n+5) {
color: orange;
}
article + p
This selector gives us the ability to select each paragraph placed immediately after the article element. Of course, it can be modified to select any element after any element (element + element). I've used article and p for the example's sake.
Html
<section>
<article>Article 1</article>
<p>Paragraph 1</p> <!-- this will be selected -->
<article>Article 2</article>
<article>Article 3</article>
<div>Div 1</div>
<p>Paragraph 2</p>
<article>Article 4</article>
<p>Paragraph 3</p> <!-- this will be selected -->
</section>
Css
article + p {
color: orange;
}
article ~ p
This selector is similar to the previous, the difference is that this one selects each paragraph placed after the article element. The position does not matter, what matters is that the paragraph has article elements placed somewhere before itself.
Html
<section>
<p>Paragraph 1</p>
<article>Article 1</article>
<article>Article 2</article>
<article>Article 3</article>
<div>Div 1</div>
<p>Paragraph 2</p> <!-- this will be selected -->
<article>Article 4</article>
<article>Article 5</article>
<div>Div 2</div>
<p>Paragraph 3</p> <!-- this will be selected -->
</section>
Css
article ~ p {
color: orange;
}
[attribute^=value]
The attribute selectors are quite powerful. This one enables us to select any element with a certain attribute which value starts with the given value. Let's see it in action.
Html
<ul class="list">
<li class="list-item">List item 1</li>
<li class="list-item">List item 2</li>
<li class="disabled-list-item">List item 3</li> <!-- this will be selected -->
<li class="list-item">List item 4</li>
<li class="list-item">List item 5</li>
<li class="disabled-list-item">List item 6</li> <!-- this will be selected -->
<li class="list-item">List item 7</li>
<li class="disabled-list-item">List item 8</li> <!-- this will be selected -->
</ul>
Css
ul.list > li[class^="disabled"] {
color:orange
}
[attribute$=value]
This selector does the same as the previous one, with a difference that the attribute value must end with the given value within the selector.
Html
<ul class="list">
<li class="list-item">List item 1</li>
<li class="list-item-disabled">List item 2</li> <!-- this will be selected -->
<li class="list-item">List item 3</li>
<li class="list-item">List item 4</li>
<li class="list-item-disabled">List item 5</li> <!-- this will be selected -->
<li class="list-item">List item 6</li>
<li class="list-item">List item 7</li>
<li class="list-item">List item 8</li>
</ul>
Css
ul.list > li[class$="disabled"] {
color:orange
}
[attribute*=value]
This attribute selector gives us the ability to select each element with the given attribute which value contains the given string in the selector. The position of the string within the attribute value is not important, as long as it contains it, the owner element will be selected. An example will make it easier to understand, as always.
Html
<ul class="list">
<li class="list-item">List item 1</li>
<li class="list-item">List item 2</li>
<li class="list-item-disabled">List item 3</li> <!-- this will be selected -->
<li class="list-item-disabled">List item 4</li> <!-- this will be selected -->
<li class="list-item">List item 5</li>
<li class="list-item-bold">List item 6</li>
</ul>
Css
ul.list > li[class*="item-disabled"] {
color: orange
}
p::first-line
This pseudo-class gives us the ability to select the first line of each paragraph, in our example. The selector can be modified to handle different elements. Useful when we want to highlight the beginning of the text written inside without wrapping it in another element.
Html
<section>
<p>
Paragraph 1 First Line <!-- this line will be highlighted -->
<br>
Paragraph 1 Second Line
</p>
<article>Article 1</article>
<article>Article 2</article>
<article>Article 3</article>
<div>Div 1</div>
<p>Paragraph 2</p> <!-- this line will be highlighted -->
<article>Article 4</article>
<article>Article 5</article>
<div>Div 2</div>
<p>
Paragraph 3 First Line <!-- this line will be highlighted -->
<br>
Paragraph 3 Second Line
</p>
</section>
Css
section > p::first-line {
color: orange
}
input:in-range
Before explaining it, I should mention that this selector can be applied to inputs only. It selects the inputs with value within the given range. Go look at the demo and try to type a value outside of the given range. The green border should not be applied.
Html
<input type="number" min="7" max="12" value="8" />
Css
input:in-range {
border: 2px solid green
}
input:out-of-range
The pseudo-class that enables us to select all input elements with value out of the given range. Each number
input can have its min and max properties set thus defining the numeric range. Useful for pages with calculations or some financial operations on it.
Html
<input type="number" min="7" max="12" value="8" />
Css
input:out-of-range {
border: 2px solid red
}
:target
Last, but not least, a really cool selector that enables us to pick the currently active element after clicking on the anchor tag where URL is pointing to the page element. In short, when href
attribute contains a target element id, that element will be selected by this selector after clicking the corresponding anchor tag.
Html
<a href="#home">Home</a>
<a href="#about">About</a>
<section id="home">Home</section>
<section id="about">About</section>
Css
:target {
color: #fff;
font-weight: bold;
background-color: orange
}
Demo
Conclusion
CSS is and always has been very powerful. In many cases, the CSS possibilities are neglect by the developers, therefore, losing the simplicity of their web site. I mean, just compare what JavaScript code would be required to achieve the same result as provided via these selectors and you will find that learning CSS is a well worth time investment.
If you like what you see, do share it, and consider buying me a coffee to keep me juiced up for more. Also, feel free to subscribe here, on devinduct, or follow me on twitter to keep up with the updates.
Thank you for reading and see you in the next article.
Subscribe to get the latest posts delivered right to your inbox