~/ Practical Applications of Pseudo Elements and Classes
A note about browser support:
There's some pretty crazy stuff going on in this post. The support for pseudo classes and elements is quite good, and you can start using them in production now. The code examples in this post show properties without vendor prefixes for readability purposes. If you're not using Compass or Autoprefixer to deal with vendor prefixes, you can always reference Can I Use to see which vendor prefixes, if any, are required.
Understanding what pseudo classes and pseudo elements are used for can be a bit confusing at first.
What are they? Why are they pseudo?! You're probably already familiar with a few of them. In any introductory CSS class, the :hover
state for anchor links is a popular example.
Here are some practical use cases for these pseudo web things:
-
Pseudo Classes
-
Pseudo Elements
Pseudo Classes
:active
The :active
pseudo class is useful for representing skeuomorphic behavior in web interfaces.
I've used a button in this example and transformed the translateY()
to offset the box shadow. It has the visual effect of the button being pressed or clicked.
button{
transition:all .2s ease;
position:relative;
box-shadow:0 10px 0 #8DC63F;
}
button:active{
transform:translateY(9px);
box-shadow:0 1px 0 #8DC63F;
}
:checked
One cool use of the :checked
pseudo-class is custom radio buttons or checkboxes. Given the following markup:
<label>
<input class='ps-checked' type='radio' name='radio'>
<div>
Custom Radio Content
</div>
</label>
We can pull off totally semantic custom radio buttons without having to use JavaScript.
Notice how the label wraps both the input and the custom radio content? Doing this
allows us to use the adjacent sibling selector. Anytime the label is clicked, the
input takes on the checked
property. Then, we apply the styles to an div that's
adjacent to the checked
input.
label input{
visibility:hidden;
}
label div{
box-shadow:8px 8px #8DC63F;
position:relative;
transition:all .2s ease;
}
label input:checked + div {
transform:translate(7px, 7px);
box-shadow:1px 1px 0px #8DC63F;
color:#fff;
}
If we hide the radio button input with visibility:hidden
, we are free to style
the contents of the <label>
container as we please.
This is an elegant solution for toggle states in web applications. Instead of toggling a class, or worse, changing the CSS via JavaScript (jQuery included), we can maintain styles that reflect state changes in the DOM all in one place.
:first-child and :last-child
A popular use case for the first and last children of a container is the widget. Here's some markup:
<div class='widget'>
<h1>The Widget Title</h1>
<p>A brief summary of the what The Widget Title is all about.
Maybe it's even the opening paragraph.</p>
<p>Often there will be more than one paragraph in a widget</p>
</div>
In our widget, we want to have equal padding for the widget
container, but ignore the margin-top of the <h1>
and the margin-bottom of the <p>
.
This is a common design pattern, where the container has equal spacing all around the
elements. If the h1
or p
were to retain its margin when directly next to
the widget's container, it would look a bit funky.
See the Pen qzhfI by Jesse Shawl (@jshawl) on CodePen
.widget{
padding:1em;
}
.widget :first-child{
margin-top:0
}
.widget :last-child{
margin-bottom:0
}
:nth-child
Alternating colors! It's an effective technique that takes a very small amount of code:
- Item One
- Item Two
- Item Three
- Item Four
- Item Five
li:nth-child(2n){
background:#8DC63F;
}
Before :nth-child
was available, you'd have to either hardcode classes into
the alternating rows or use a JavaScript solution to color the odd-numbered rows.
Using a CSS solution allows us to keep styles together, which ultimately decouples
our front end code.
:target
The :target
pseudo class is useful for highlighting hash-linked sections
on web pages. This is a great usability technique. Normally the page will jump
to the anchor on click and position the element with the corresponding ID at the
top of the page. If the linked-to element is towards the bottom of the page, and there
isn't enough room at the bottom for the element to be all the way at the top of the
page, the only way to identify what was linked to will be to use the :target
pseudo class to highlight the important info.
Clicking on this link will make the window jump to the anchor, and will highlight the linked-to line.
:target{
animation:target 2s ease;
}
@keyframes target{
0%{
background:#B4D88B;
}
100%{
background:#fff;;
}
}
Here are some other examples of using the :target
pseudo selector:
The difference between pseudo-classes and pseudo-elements
When both use the :
syntax to denote pseudo-ness, it's difficult to remember
the difference between a class and an element. The CSS3 spec provides a syntax
for distinguishing between pseudo classes and pseudo elements: :class
and ::element
.
Pseudo classes are used to select elements which cannot be selected using a class or id. I like to think of pseudo elements as being able to add content to a node in the DOM without adding more markup, like all the cool things on one-div.com.
Most of the examples in this post reference pseudo classes, but Chris Coyier has a great round up of all the cool things you can do with pseudo elements over at CSS Tricks.
:before and :after
My most frequent use of the :before
pseudo element is the micro clearfix. In Sass,
you can extend a clearfix place holder:
Micro Clearfix adapted from Nicholas Gallagher.
%clearfix{
:after{
content: ' ';
display: table;
clear: both;
}
}
:first-letter
There's no need to use images or hard code div's with a class if you want to pull off the drop cap technique:
Jesse Shawl is a Front End Developer at nclud - whose focus intersects web performance and cutting edge browser interactivity. He's an open source advocate who enjoys building tools for the web with third party API's and mesmerizing CSS animations.
p:first-letter{
font-size: 5em;
height: .75em;
display: block;
float: left;
padding-right:.125em;
line-height: 1;
font-weight:bold;
color:#B4D88B;
text-shadow:4px 4px 0 #8DC63F;
}
~/ Posted by Jesse Shawl on 2013-12-12