New Feature: Playlist Center! Pick a topic and let our playlists guide the way.

Easy-to-follow video tutorials help you learn software, creative, and business skills.Become a member

Pseudo-element selectors

From: CSS: Core Concepts

Video: Pseudo-element selectors

Pseudo-elements are similar to pseudo- classes in many ways, as they allow you to access content beyond the normal capabilities of the DOM. For example, using pseudo-element selectors, you could target the first line or first letter of an element. Pseudo-element selectors also allow us to create what is known as generated content, that is, actually place content on the page that is not contained in the structure of the document. Now let's take a closer look. I have the pseudo-element.htm file opened from the 02_17 folder, and the first thing I want to do is just take a look at this in a browser, just so we can see what the page structure looks like.

Pseudo-element selectors

Pseudo-elements are similar to pseudo- classes in many ways, as they allow you to access content beyond the normal capabilities of the DOM. For example, using pseudo-element selectors, you could target the first line or first letter of an element. Pseudo-element selectors also allow us to create what is known as generated content, that is, actually place content on the page that is not contained in the structure of the document. Now let's take a closer look. I have the pseudo-element.htm file opened from the 02_17 folder, and the first thing I want to do is just take a look at this in a browser, just so we can see what the page structure looks like.

And you can see that it's very similar to what we have been doing. We have h1 with a couple of paragraphs underneath that, and then we have another paragraph with a link in it down here that's linking to an outside article. If I go back in my code, just to review the structure, inside our main article we have one section. Inside that section, we have a h1, followed by two paragraphs, and then we have a second section inside that article that just contains a paragraph with a link to that outside article. So the first thing I want to do is style our paragraphs so that the first line of the paragraphs has some unique styling, and also create a drop cap.

Now in the past, if you wanted to do that, we had to use a lot of extraneous markup--a lot of span tags, a lot of class attributes, a lot of a class styles--but through the use of pseudo- element selectors, we don't have a resort to those anymore, and we can do that sort of really specific targeting without any additional markup. I am going to go right up to my styles and inside my styles, we are going to write our first pseudo-element selector. So here I am just going to p::first-line, open up a curly brace. And before we add our properties, I want to talk about the syntax.

Now, Aptana is trying to tell me, no, no, you can't do that, and the reason that it's giving me an error on that particular line is because the syntax. It's these two colons right here. So let's talk about that. So pseudo-elements have been around for a while, and in the CSS 2.1 specification, syntax-wise were no different than pseudo-class selectors. So it is perfectly acceptable to write them just like that. In the CSS Level 3 Module the syntax of the double colon has been added, and it's really just to sort of differentiate a pseudo-element selector from a pseudo-class selector.

So which one should you use? Well, the CSS3 syntax is the syntax that the W3C would like you to use going forward, but one of the problems with it is that older browsers, specifically browsers like Internet Explorer 8, don't recognize this syntax. So if you want to make sure that older browsers can process and render this correctly, you might just want to use the single colon. Now I am just going to, in this title, use the dual colon because that's sort of the accepted syntax in CSS3, but when you're testing it in your pages, if the pseudo-element selectors don't target correctly, if they don't render properly, one of the first things that you can do is go remove that extra colon and see if that works in the browsers that you're targeting.

So I am just going to go ahead and give this some formatting instructions. I am going to type in font-family, and we will just do Georgia. And then on the next line we will do font- style, and we will do italic. So I am going to save this. I am going to go back out to my browser, refresh the page, and I can see that sure enough, the first line, we have a different font and the text is italicized. Excellent! So now I'm going to go about creating a drop cap, so I am going to go back into my code, and this time I am going to use the pseudo-element selector first letter.

So on the next line I am going to do p::first-letter, and inside that, what we are going to do is we'll do font-size. We will crank the font-size up a little bit, so we will 3ems. On the next line we will continue to do font-family as Georgia, although we really don't need to, because the previous selector is doing that for us. I guess this is just what I call being thorough. We are going to do a float to the left. We haven't talked about the float property yet. We are really going to discuss that in another title, the CSS page layout title a little bit more, but it will come into play when we talk about the box model a little bit later on this title as well.

And then we are going to do padding. This is a syntax that we are going to study a little bit later on. So right now just do 10px 5px 0 0, and that's shorthand notation that allows us to differentiate padding on all of the four sides of the element itself. So, if I save this and once again go back out to my browser and refresh this, you can see there is our drop cap. We are getting the size that we need. We are getting the spacing around it that we want.

There is one thing going on here, though. This is occurring for every single paragraph in my document--probably not what I am going for, specifically not down here in this link. What I would really want to happen is really only the first paragraph within this section is what I want affected. Now there is a couple of different ways to do this. One of the easiest ways is just use one of the combinators that we used earlier. So what we are going to do is go back to my code, and on each of these I am going to use the adjacent combinator with the h1. So I am going to h1+p and do the same thing here, h1+p. So that's going to limit these pseudo-element selectors to only when the paragraph immediately follows an h1.

So if I save this, preview this again in the browser, you can see it only occurs to the top paragraph, so we are limiting the formatting to exactly where we want it. Before we write the styles for this, I want to flip over to the CSS 2.1 specification. You can find this at This is our generated content. I've browsed through the TOC and found the content property, and it's actually in a section called The :before and :after pseudo-elements. Now this is what we are going to use in just a moment.

So what generated content allows us to do is to create content to place on the page. Now there are a couple of things that you need to know about this. You can use :before and :after, and what it'll do is it'll take the generated content that you created and place it either before the element that you're targeting or after the element that you're targeting. The second thing that you need to know about it is that this content is not observable by the Document Object Model, meaning that it does not show up in the Document Object Model's tree. Scripting cannot find it. It cannot access it.

It can't apply any behaviors to it or modify it in anyway. The only time that this shows up is visually on the page as the CSS is being processed. In order to work with :before and :after, you use a property called content. If I scroll down a little bit, I can see what is available to us in content. We can do string, which is we just pass in whatever literal value we want to show up on the page that's a string of text. We have URI, which essentially is an external resource like an image.

So if you wanted an icon to show up before or after content, you could point it towards the image that you wanted to show up. We have counters. Counters are a great way of generating content for chapters, and you could say chapter 1, chapter 2, chapter 3, and the counter would keep track of that for you. We also have open and close quotes. So if you were using block quotes, for example, you could place an open quote on one end of it and a close quote on the other end. We also have this really cool little feature that we are going to use here in just a moment called attribute. You can go into the element that you're targeting, find an attribute value, and then actually display that attribute value on the page, either before or after the element.

Let's go into our code and experiment with doing that. I am going to switch back to my page preview so that when we come back to my browser all I'd to do is refresh this to see our generated content. So I am going to go back to our code, and I am just going to go down, and we are going to talk about the element that we are going to target. So we are going to target this link right here, where it says Article reference. So I am going to generate some content either before or after that. The first thing we will do is we will just generate the literal string so you can see what that looks like. Then we are going to take advantage of the fact that you can also grab content out of one of the attributes and display that as well.

I am going to go back up my styles and just below the h1 + p::first-letter style, I am going to type in a::after. Now once again this is the same syntax. You can either do the single or dual colon, it's totally up to you. Open that up, and then what we are going to do is we are going to do the content property. Inside the content property, what I am going to do is quotation marks. So the quotation marks means that I am going to pass a literal string. It means that this content really doesn't have any value that needs to be evaluated; it's just a series of characters.

So if you want whitespace, you have to add whitespace within the quotation marks. So I am going to do whitespace, or just a space, and then in parentheses I am going to type in outside link. Go ahead and add a semicolon to the end of that and save it. So I am going to go back to my browser and refresh it, and you can see exactly what's going on here. It places that content outside the link and because I did a little bit of whitespace, I've got space between article reference and outside link. Now you're not limited to just displaying the content; you can also format the generated content within the same rule.

So, if I go back to my generated rule, I could do color, do something like #666, which is a gray, and you can even do the font-size. So I can do font-size and make it a little bit smaller. I can do .9ems. Now if I save and test this, you can see that now our outside link is formatted a little bit differently from the rest of the link, and that content is being generated and formatted and put into place. Now as I mentioned before, there are other things that you can do with generated content. So I could go ahead and bring in an image from outside of the file.

I could also go ahead and take a look inside of an attribute and then put that attribute value out there, and that is extremely useful. I use this mostly in print style sheets, but I am going to show you how this works here on our page on our screen style sheet. So I am going to go back into my code and I am going to change this a little bit. I am going to change content, and I am going to do a little bit of concatenation. Before I do the concatenation, I want to show you what this looks like beforehand, okay. So I am just going to do content and I am just going to do attributes, so attr(href).

So, what it's saying is, it's saying, hey, go into this link, find the href attribute, and whatever the value of that is, go ahead and place on the page. If I save this and test it, it goes ahead and places the link, which is, right there on the page. Now I can also concatenate this together with other literal string values. So if I wanted to, right before this attribute, I could type in quotation marks, space, left bracket, and close my quotation marks, and then a space.

And then after the href, I could do the same thing. I could do quotation mark, closing right bracket, and then another quotation mark. What this is going to do is it's going to view this as a literal string that it needs to put on the page, followed by the attribute itself, followed by another closing bracket. If I save this and preview it, you can see that now I have sort of added those brackets to either side. What's really nice about this is that the link is still there if I want to click on it, and it goes to the proper page, but also, visually, I am being displayed the link itself.

Again, you can see why this is particularly helpful for print style sheets, because in a print style sheet you don't want the link to look like it's clickable; you just want to print it out. But doing this would allow the person on the printed page to at least see the link and be able type that in if they wanted to. Pseudo-elements, just like pseudo- classes, they give another set of really powerful options when targeting our content, and they really extend our capabilities through the use of generated content. If you read through the Selectors Level 3 specification, which I have been recommending in almost every single movie in this chapter, you'll see that generated content is mentioned, but just in passing, it really refers you to the CSS 2.1 specification on generated content.

You want to read up more on that by going to the CSS 2.1 specification. browsers haven't implemented pseudo- elements consistently across the board; especially remember what I said about the syntax of using the dual or single colons. Just like with anything else, make sure that you check your browser implementations and test it inside target browsers carefully before committing to using them.

Show transcript

This video is part of

Image for CSS: Core Concepts
CSS: Core Concepts

81 video lessons · 39392 viewers

James Williamson

Expand all | Collapse all
  1. 4m 57s
    1. Welcome
    2. Using the exercise files
      4m 2s
  2. 1h 7m
    1. Exploring default styling
      4m 56s
    2. CSS authoring tools
      2m 29s
    3. CSS syntax
      4m 45s
    4. Writing a selector
      4m 10s
    5. Setting properties
      8m 40s
    6. Common units of measurement
      7m 47s
    7. Inline styles
      5m 1s
    8. Embedded styles
      5m 19s
    9. Using external style sheets
      10m 34s
    10. Checking for browser support
      8m 48s
    11. Dealing with browser inconsistencies
      5m 30s
  3. 2h 15m
    1. Structuring HTML correctly
      2m 51s
    2. Element selectors
      4m 52s
    3. Class selectors
      6m 4s
    4. ID selectors
      3m 27s
    5. Using classes and IDs
      10m 7s
    6. Element-specific selectors
      4m 35s
    7. The universal selector
      5m 42s
    8. Grouping selectors
      4m 49s
    9. Descendent selectors
      7m 32s
    10. Child selectors
      5m 7s
    11. Adjacent selectors
      5m 30s
    12. Attribute selectors
      12m 43s
    13. Pseudo-class selectors
      3m 54s
    14. Dynamic pseudo-class selectors
      8m 29s
    15. Structural pseudo-class selectors
      6m 45s
    16. Nth-child selectors
      13m 10s
    17. Pseudo-element selectors
      12m 40s
    18. Targeting page content: Lab
      8m 56s
    19. Targeting page content: Solution
      7m 59s
  4. 42m 39s
    1. What happens when styles conflict?
      4m 0s
    2. Understanding the cascade
      5m 47s
    3. Using inheritance
      6m 11s
    4. Selector specificity
      6m 55s
    5. The !important declaration
      4m 5s
    6. Reducing conflicts through planning
      3m 33s
    7. Resolving conflicts: Lab
      6m 45s
    8. Resolving conflicts: Solution
      5m 23s
  5. 1h 47m
    1. Setting a font family
      7m 10s
    2. Using @font-face
      9m 18s
    3. Setting font size
      7m 35s
    4. Font style and font weight
      6m 52s
    5. Transforming text
      3m 58s
    6. Using text variants
      2m 49s
    7. Text decoration options
      4m 26s
    8. Setting text color
      3m 2s
    9. Writing font shorthand notation
      8m 49s
    10. Controlling text alignment
      6m 33s
    11. Letter and word spacing
      9m 11s
    12. Indenting text
      4m 30s
    13. Adjusting paragraph line height
      10m 30s
    14. Controlling the space between elements
      6m 41s
    15. Basic text formatting: Lab
      8m 45s
    16. Basic text formatting: Solution
      7m 14s
  6. 2h 1m
    1. Understanding the box model
      16m 53s
    2. Controlling element spacing
      14m 29s
    3. Controlling interior spacing
      10m 49s
    4. Margin and padding shorthand notation
      6m 27s
    5. Adding borders
      8m 57s
    6. Defining element size
      10m 7s
    7. Creating rounded corners
      6m 58s
    8. Background properties
      2m 51s
    9. Using background images
      5m 10s
    10. Controlling image positioning
      10m 25s
    11. Using multiple backgrounds
      7m 5s
    12. Background shorthand notation
      5m 25s
    13. Styling container elements: Lab
      7m 55s
    14. Styling container elements: Solution
      8m 17s
  7. 47m 51s
    1. Color keyword definitions
      5m 4s
    2. Understanding hexadecimal notation
      6m 5s
    3. Using RGB values
      4m 58s
    4. Using HSL values
      5m 17s
    5. Working with opacity
      2m 23s
    6. Using RGBa and HSLa
      3m 8s
    7. Styling drop shadows
      5m 38s
    8. CSS gradients
      6m 32s
    9. Working with color: Lab
      4m 26s
    10. Working with color: Solution
      4m 20s
  8. 1m 58s
    1. Additional resources
      1m 58s

Start learning today

Get unlimited access to all courses for just $25/month.

Become a member
Sometimes @lynda teaches me how to use a program and sometimes changes my life forever. @JosefShutter
@lynda is an absolute life saver when it comes to learning todays software. Definitely recommend it! #higherlearning @Michael_Caraway
@lynda The best thing online! Your database of courses is great! To the mark and very helpful. Thanks! @ru22more
Got to create something yesterday I never thought I could do. #thanks @lynda @Ngventurella
I really do love @lynda as a learning platform. Never stop learning and developing, it’s probably our greatest gift as a species! @soundslikedavid
@lynda just subscribed to all I can say its brilliant join now trust me @ButchSamurai
@lynda is an awesome resource. The membership is priceless if you take advantage of it. @diabetic_techie
One of the best decision I made this year. Buy a 1yr subscription to @lynda @cybercaptive
guys (@lynda) is the best. So far I’ve learned Java, principles of OO programming, and now learning about MS project @lucasmitchell
Signed back up to @lynda dot com. I’ve missed it!! Proper geeking out right now! #timetolearn #geek @JayGodbold

Are you sure you want to delete this note?


Thanks for signing up.

We’ll send you a confirmation email shortly.

Sign up and receive emails about and our online training library:

Here’s our privacy policy with more details about how we handle your information.

Keep up with news, tips, and latest courses with emails from

Sign up and receive emails about and our online training library:

Here’s our privacy policy with more details about how we handle your information.

submit Lightbox submit clicked
Terms and conditions of use

We've updated our terms and conditions (now called terms of service).Go
Review and accept our updated terms of service.