DEV Community

Salma Alam-Naylor
Salma Alam-Naylor

Posted on • Originally published at whitep4nth3r.com

What's the difference between : and :: in CSS?

I spent years Googling “the difference between : and :: in CSS” before the information stayed in my brain. Sound familiar? Then this post is for you.

First up: if you need a quick answer to the title of this blog post then look no further!

  • : refers to pseudo-classes, such as :visited or :hover
  • :: is for pseudo-elements, such as ::first-of-type or ::after

And if you want a more detailed explanation, let’s dive into some examples.

What does “pseudo” mean?

The English definition of the word pseudo is “fake” or “not real”. So what on earth do we mean by fake classes and fake elements? Pseudo-classes and pseudo-elements are not manually written into HTML and don’t appear in the DOM (or document tree), but instead are created by CSS!

What’s a pseudo-class?

Pseudo-classes allow you to select elements in CSS based on information outside of the HTML written on the page, such as user interaction or information stored in the browser. Pseudo-classes are accessed by a single colon (:) followed by the pseudo-class name.

You can use pseudo-classes to style an element based on its state. You might often see links you’ve visited on a page appear as a different colour. This is achieved by targeting the :visited pseudo-class of an anchor tag (a) in CSS to style it.



a:visited {
  color: #c58af9;
}


Enter fullscreen mode Exit fullscreen mode

You can observe this in action on Google’s search engine. Head on over to google.com and search for something you know you’ve visited. Open up the browser dev tools, and find the a:visited selector in the CSS inspector.

Screenshot of dark mode google search results showing the link to the top site I have visited is purple, and the second site in the list which I have not visited, which is blue. Dev tools is open and shows the anchor visited styles coming from the stylesheet.

As well as being affected by browser information such as visited links, pseudo-classes can also be affected (added or removed) by user actions on the page, such as hovering over or focussing on elements. Here’s the :hover pseudo-class in action on Google search results.



a:hover {
  text-decoration: underline;
}


Enter fullscreen mode Exit fullscreen mode

Screenshot of google search results showing I am hovering over the top result, which is adding an underline to the link. Dev tools are open showing the style applied using the hover pseudo class.

To read more about the different types of pseudo-classes available to target in CSS, you can check out the extensive documentation on MDN.

What’s a pseudo-element?

Pseudo-element selectors allow you to use CSS to style a specific part of a DOM element. Pseudo-elements are accessed by a double colon (::) followed by the pseudo-element selector. Unlike pseudo-classes, pseudo-elements cannot be used to style an element according to its state.

Here’s an example. Often, article-based websites use “drop caps”, a print convention that has existed for thousands of years, which uses a very large single letter to mark the start of a block of text. You can achieve this by targeting the ::first-letter pseudo-element in CSS.



p::first-letter {
  font-size: 300%;
}


Enter fullscreen mode Exit fullscreen mode

Here’s a visual example showing how drop caps would look on my blog posts.

A blog post on my site showing a large uppercase letter E at the start of a paragraph

You can also choose to target the first line of an element, using the ::first-line selector.



p::first-line {
  font-size: 300%;
}


Enter fullscreen mode Exit fullscreen mode

Other common pseudo-element selectors you might use in your CSS files include:

  • ::before
  • ::after
  • ::first-of-type
  • ::last-of-type
  • and ::placeholder.

Read more about the different types of pseudo-elements available to target in CSS on the official MDN documentation.

And that’s it! May this be the last time you google the difference between : and :: in CSS!

Top comments (15)

Collapse
 
abhinav1217 profile image
Abhinav Kulshreshtha

Just to add on, :before and :after, :first-letter and :first-line are also valid due to their legacy usage, since they were introduced way back before the definition was finalized. But it is highly recommended that for newer code, we should follow proper convention.

Collapse
 
ankush981 profile image
Ankush Thakur

Thanks! My brain was going in a tizzy thinking about these. Damn, is CSS a mess?!

Collapse
 
abhinav1217 profile image
Abhinav Kulshreshtha

It is not a mess if you look at the history with a border perspective. The big reason for all these messes is the fact that web was originally designed for documents. Then we sprinkled some dynamic elements on those documents. The current web is more like a platform, with payment api, device api, system api, some that were needed to improve web, some that were added by big corps purely for their own purposes and no relation to web at all. And a primary goal of web is to never break backward compatibility, so even though some things (like definition of psudo-elements and psudo-classes) were needed to change, they had to adopt it to make sure none of the past pages break.

There is an interesting post with CSS working group on their mistake list that they now realize but cannot change until time machine is invented. Do give it a read, you would enjoy it.

Collapse
 
whitep4nth3r profile image
Salma Alam-Naylor

Indeed, that’s why I didn’t mention it 😉

Collapse
 
kolja profile image
Kolja

And you can combine them 😉

Collapse
 
jessica89079831 profile image
Jessica • Edited

In CSS, ::after creates a pseudo-element that is the last child of the selected element. Right?

Collapse
 
whitep4nth3r profile image
Salma Alam-Naylor

No it’s not the last child, because it’s a fake element! 😁

Collapse
 
asafagranat profile image
Asaf Limi Agranat

Not only its not the last child - it is not a child at all, but placed in the DOM at the same node level. Meaning that the selected element and its ::after pseudo-element share the same direct parent element.

Collapse
 
raguay profile image
Richard Guay

Thanks. I keep getting them mixed up myself.

Collapse
 
jlrxt profile image
Jose Luis Ramos T.

No estás solo, me pasa lo mismo.🤣😀🤣

Collapse
 
monicafidalgo profile image
The Coding Mermaid 🧜‍♀️

Great article Salma! Simple and right on point💪😊

Collapse
 
whitep4nth3r profile image
Salma Alam-Naylor

Thank you!

Collapse
 
jlrxt profile image
Jose Luis Ramos T.

Gracias excelente articulo. Ahora repetiré en mi cabeza : define una seudo-clase y : : define un seudo-elemento. Listo ya lo tengo.

Collapse
 
whitep4nth3r profile image
Salma Alam-Naylor

De nada! 😎

Collapse
 
jonosellier profile image
jonosellier

A good rule is : is for the state of the element itself and :: is for a pseudo-element