March 11, 2016
•Last updated November 5, 2023
Advanced CSS Selectors you never knew about
CSS is awesome. It paints the web with designs we all know and love. Often times content behind the scenes gets targeted by adding a simple id
or class
to an element to target for styling. This is all well and good, but what if for some reason you can’t get your hands on the code to add the id
or class
?
Thankfully some dynamic selectors are available to you in the event that the only way you can target an element is by prefix, suffix or anything in between depending on how HTML is generated.
First thing is first
While the following advanced selectors I’m about to talk about work, I would try your absolute best to use unique ids
and classes
from the start. Much like JavaScript, CSS has to traverse the DOM to find the associated element. If the element is harder to find the amount of time it takes to find it obviously increases. Sometimes you can’t get around this if for some reason you don’t have access to the source code or it is being generated dynamically (It’s rare but it happens).
Partial Selectors
Ends With ($=)
Selecting an element with CSS that has a repetitive suffix would look like this:
div[id$=“_myDiv”] {
// cool CSS stuffs
}
The first thing to note is the div
with the brackets surrounding the id$
attribute. The div
tag can be any element in the DOM
from input
to span
and so on. This is awesome if you’re trying to target a specific element that has a dynamic prefix like this:
<!-- HTML -->
<div id="0125_LoginPanel">
Some sample content
</div>
So to target this div
just use the selector like before and write:
div[id$="_LoginPanel"] {
margin: 0 3em;
padding: 1em;
}
Since we are targeting the specific suffix you would use the $
following the id
attribute within the brackets. Then within quotes add the suffix of the element you are trying to target.
div[id$=“myDynamicDiv”] {
// cool CSS stuffs
}
You can do it for any element (div, span, img, etc...), and any common attribute (id, name, value, etc...).
Begins with (^=)
Much like the "ends with" section above you can target elements with specific prefixes. The only difference than before is what character you add to the selector following the =
sign.
<!-- HTML -->
<div class="myPanel_1435">
<h1>My custom panel</h1>
</div>
Then the selector would look like this:
div[class^="myPanel_"] {
// cool CSS stuffs
}
Simple enough right? All we did that’s different than the ends with ($=)
selector is target the prefix by adding a ^
symbol in front of the =
sign. You may also notice this time I used a class
instead of an id
. CSS is flexible enough to pretty much let you target anything as I stated earlier.
Contains (*=)
What if your have both a dynamic prefix and suffix? Well, luckily you can target an element that simply contains a parameter.
<div class="1gdug_logoutPanel_4828fde">
<h1>My Custom Logout Panel</h1>
<form>...</form>
</div>
Targeting this could look like:
div[class*="logoutPanel"] {
// cool CSS stuffs
}
So essentially any div
that contains the text logoutPanel
can be selected like the example above.
Equals (=)
Not that you’d ever need to use equals it is another way to select an element with a specific id
, class
, name
, value
, etc...
<!-- HTML -->
<div class=“3453_mydynamicdiv”>
<h1>My Dynamic Div</h1>
</div>
Targeting this div
directly can happen using the =
partial selector or just the traditional way you are already more familiar with.
/* 1st way - selects only this name */
div[class="3453_mydynamicdiv"] {
/* cool CSS stuffs */
}
/* 2nd way selects all classes with this name */
.3453_mydynamicdiv {
/* cool CSS stuffs */
}
Quick Review of Partial Selectors
=
equals$=
ends with^=
begins with*=
contains
Pseudo-class selectors
Simply put, pseudo-class selectors are CSS selectors with a colon preceding them. Many of these are commonly used for links or interactive types of elements.
a:hover {}
a:active {}
a:focus {}
a:visited {}
:checked {}
:first-child {}
:last-child {}
These bad boys come in handy when accessing specific elements as well as focusing on element states which is what makes interaction on the web an art form in itself. I won’t be reviewing them all as you can read Chris’s article for that but I will be pointing out some that are pretty neat workarounds for otherwise hard scenarios with traditional CSS and HTML.
:not(x)
The :not(x)
pseudo-class selector removes any elements within a matched set based on the parameter you pass. This is useful for styling all elements expect one type.
<ul class="nav">
<li>Blog</li>
<li>About</li>
<li>Videos</li>
<li class="highlight">Music</li>
<li>Merch</li>
</ul>
With the pseudo class selector you can target all but the class of highlight
like this:
.nav li:not(.highlight) {
margin: 0 1em 0 0;
padding: 5px 16px;
display: inline-block;
}
You can even go as far as selecting an attribute if you so desire:
input:not([disabled])
::first-letter
Drop caps are pretty slick when it comes to reading and authoring content for the web. These were made famous with print and have now become a nice trend in the blogging world. With pseudo class selectors you can target the first letter of a paragraph by simply writing:
p::first-letter {
/* drop cap styles */
}
You probably don’t want to target every paragraph so to work around this you can actually chain together pseudo selectors
p:first-child::first-letter {
/* drop cap styles for only the first paragraph of text. */
}
This is so useful and saves you from having to use JavaScript or something more hacky to style up your content nicely.
:first-of-type
:first-of-type
is one I use all the time which allows you to select the first of any type of elements inside a parent and target it via CSS.
article:first-of-type {
margin-top: 0;
}
:last-of-type
You can’t have :first-of-type
without :last-of-type
. This selector works the opposite way of :first-of-type
if you hadn’t already guessed.
article:last-of-type {
border-bottom: none;
margin-bottom: 0;
}
Finish line
There you have some advanced CSS selectors that you may have never tried, heard of before, or simply are just now discovering. Whatever the case I recommend discovering what else is available as I have not covered them all but more or less some of my favorites. Check out the CSS-tricks Almanac for a long list of all things CSS and an article specifically on pseudo class selectors to learn more.
Categories
Products and courses
-
Hello Hotwire
A course on Hotwire + Ruby on Rails.
-
Hello Rails
A course for newcomers to Ruby on Rails.
-
Rails UI
UI templates and components for Rails.