CSS Tricks: Before and After!

Deviation Actions

pica-ae's avatar

Literature Text

No, this is not about a tv show in which I take a CSS and make it prettier ;)
It is about the pseudo-elements ::before and ::after.

They are similiar for example to the :hover element, meaning that it is not necessary (or possible) to add them to the HTML, but can be controlled purely by writing CSS. They are always there, but whether they are visible depends on whether you code them or not.

::before and ::after are almost self-explanatory pseudo-elements. They define what happens either before or after a regular HTML element. They can be applied to any element.

Let's get right going!

So in the first simple example we are going to add guillemets, also known as French quotation marks, to direct speech in our text. The usefulness of this may stand to debate, you could easily just type it out, but it is a nice and easy way to get started with explaining ::before and ::after.

We will take advantage of the i HTML class for this. Opposed to em it will not add emphasizis to the content, but an indication of different semantic meaning to the rest of the text; direct speech is what we are aiming for.

<i>Lorem ipsum.</i> he said. <i>Lorem ipsum!</i>

Lorem ipsum. he said. Lorem ipsum!

Because i renders text in italics, I will change the font-style to normal. Below that you can see content being added to the :before and :.after elements. You only require one line, which tells what to render, in this case guillemets before and after the direct speech. They will use the same font and text settings as the containing box, unless we specify new ones.

i {

font-style: normal;


i::before {

content: "«";


i::after {

content: "»";


Lorem ipsum.
he said.
Lorem ipsum!

The guillemets may not display on your browser, they sometimes do on mine, sometimes they don't. I cannot use the ASCII code for them either, dA does not validate the skin if I do that.

This is the most basic way of using the ::before and ::after to your advantage. The content can be any written content or nothing.
By not adding any other styling except for the content, the text inside the content will be styled the same way as the text in the element it refers to; In our example i.

If you do not add the line content: " ";, nothing will be displayed!

But we can do far more with these two pseudo-elements as they can be styled with all possible properties.

Practical Usage

There are many ways in which you can use the ::before and ::after elements to your advantage.
  • Indicators on links, f.e. here on dA you will find username icons [ pica-ae ] and external links [ ] are using the ::after element.
  • To add appearence or content to HTML elements you can only edit via CSS. This is the case for most Content Managment System based websites, on dA it means: if you are using someone else's HTML (like when creating a journal skin on dA) you cannot add HTML elements like <span> to the title of the journal.

Application of ::before and ::after

Here are some examples of how to use these pseudo-elements in your designs.

Using images in ::before and ::after

The scenario in the first example is a short paragraph with a headline. You may want to add images to the headline to highlight it further than just with a bigger font size.

<h1>Sed ut perspiciatis unde omnis</h1>
Iste natus error sit voluptatem accusantium doloremque laudantium, totam rem aperiam, eaque ipsa quae ab illo inventore veritatis et quasi architecto beatae vitae dicta sunt explicabo.

So this is how the HTML for our content could look like. I added the regular text just for demonstration purposes, we won't do anything with it.

The CSS may seem a bit more complex at first, but it can be broken down into bits that will all come together as being really simple.

The <h1> element will be blue, bold and bigger than the copy. What we want is two different images to be displayed before and after the headline.

One way of solving this issue is by using the ::before and ::after pseudo-elements.

h1 {

color: #2864ff ;

font-size: 18px;

font-weight: bold;


h1::before {

content: " ";

display: inline-block;

background: url("…/img_before.png");

height: 20px;

width: 12px;

margin: 0 0 -3px 4px;


h1::after {

content: " ";

display: inline-block;

background: url("…/img_after.png");

height: 20px;

width: 12px;

margin: 0 4px -3px 0;


And as easy as that, we have two cats facing away from our headline on each side!

Sed ut perspiciatis unde omnis.

Iste natus error sit voluptatem accusantium doloremque laudantium, totam rem aperiam, eaque ipsa quae ab illo inventore veritatis et quasi architecto beatae vitae dicta sunt explicabo.

Here's why I did what I did:

This has to be set to at least " ". Without that line, nothing will appear, no matter what else you write. Yes, I am repeating this. I have forgotten it often enough and got mad not realizing what was wrong.

In order to actually see the element, if it has no content, you will also have to tell it to be visible. I am going for inline-block, because it creates a block element BUT it does not create a whole width element.
If I was to use block, I would also have to use floats to place the element and I want to save that line of code.

height & width
They are needed to display the element as well. If they are not set, they are assumed to both be 0. It is best to set them to the exact dimensions of your image.

Vertical margin is applied to position our cats better according to the text. The surface the cats are sitting on was supposed to be at the same height as the baseline of the text. This may require some adjustments and testing out.
Horizontal margin is applied on one side only, to create a better spacing between cat and headline.

Bullet points

If you have ever wanted to change the color of a bullet point in a list, but not the color of the font, the first thing to do is go to change the bullet to an image. The problem with that is, if you decided you need the bullet in a different color, you have to change the image and the image URL. Ugh, that's annoying :stare:

<ul><li>Glomtom</li><li>Aferraron</li><li>They name the ship Titanic. Charlie left the door open. We called her "the careless car mechanic". They found the box empty. Those taxi drivers appointed him committee chairman.</li></ul>

:lightbulb: Read up on lists in my CSS Tricks: Lists article.

First thing we do is disable the default bullet points for an undordered list. I am not doing this on the list element, because I may want to display the type for ordered lists still in my CSS.

I do not have to add any CSS to the list elements, they stay default.

The ::before element will now become our bullet point replacement. We can apply any styling we want to this, and it will not be applied to the list element's text.

There is a bit of math required for all the positioning, but it's not that bad ;)

ul {

list-style-type: none;

margin-left: 14px;


ul li::before {

content: " ";

display: block;

float: left;

background: #2864ff;

height: 8px;

width: 8px;

margin: 6px 6px 0 -14px;


  • Glomtom
  • Aferraron
  • They name the ship Titanic. Charlie left the door open. We called her "the careless car mechanic". They found the box empty. Those taxi drivers appointed him committee chairman.

list-style-type: none;
This line gets rid of the bullet points. The default bullet would be a filled circle in the color of the list element's text.

Here is where the math starts. The values you use here, depend on the values you apply to the bullet point itself. In this case the value comes from the addition of width and margin-right: 8px + 6px = 14px.

Again, content: " "; is necessary to display the ::before or ::after pseudo-element.

For this example I am using display: block;, to demonstrate the different effects of using different values for display.

Because we have used display: block;, we need to use float: left; to position the bullet points before the list element, yet allowing it to be "inline" with it.

The margin helps further position the bullet point's ::before element. In the example I have applied it top and to right of the element.
You may have to adjust the margin-top depending on the size of the bullet point; margin-right is more a question of preference, as to how far away the text should be from the bullet point.
To make up for the margin-left we applied to the li element we have to add margin-left: -14px; to the ::before element if we want everything to be aligned nicely. (Which is the whole purpose of all this margin-left stuff we're doing here.)

The famous arrow & and hover effects

This is a small weak point of mine, that I like to pursue a lot :XD: It is a bit more advanced, as it not only uses ::before and ::after but the appearance actually depends on border values; we merely use ::before and ::after for where we want it to be :D

You'll also see how to code :hover behaviour on elements using ::before and ::after. It is not harder than any other hover, just needs the proper syntax. (Which tbh can be a mind bender sometimes :P )

I will create a custom button class without styling and add the link inside the button div. This I do to seperate between regular links in texts and links in buttons.

<div class="button"><a href="[URL]">I am a button with an arrow end!</a></div>

The simplicity of the HTML unfortunatley is not reflected in the CSS ;)

.button a {

background: #2864FF;

color: #FFFFFF;

display: inline-block;

height: 40px;

line-height: 40px;

padding: 0 10px 0 10px;

position: relative;


.button a::after {

content: " ";

background: transparent;

border-top: solid transparent 20px;

border-right: none;

border-bottom: solid transparent 20px;

border-left: solid #2864FF 20px;

position: absolute;

right: -20px;


.button a:hover {

background: #183d99;


.button a:hover::after {

border-left: solid #183d99 20px;


link display
display: inline-block; will make our element only as long as its content, plus margins and other horizontal elements. block would make the element full width, and we don't want that right now. Not styling this will cause our set height not to render.

link height, line-height & padding
In order to have clean results, we need to set a fixed height for our element. Applying a line-height of the same value as the height will help us center the text vertically.
Since we have a fixed height with a new line-height, we only have to set padding to the right and left of our element.

link position
Applying position: relative; here, will make it possible to position the ::after element absolute later in the CSS.

::after content
Again, again, content: " "; is necessary to display the ::after pseudo-element.

::after borders
It may come as a surprise that we can use borders to create arrow shapes :XD: But the way borders are set up makes this possible.
If you ever looked closely at a picture frame, you will have noticed how for the corners the seperate pieces of wood are cut at a 45° angle. The same thing is going on with borders in CSS. Now if you now imagine a frame that has no content, the seperate pieces of wood become basically just 4 triangles whose tips meet in the middle.
What we have to do in CSS to make this work is quite simple: The border we want to be the pointy bit has to have a border-color, while those who are on each side of our pointy site have to have a transparent border-color. The fourth side we don't need to touch, if we don't define it, it simply won't show. (I have set it to none in the given example, just to cover everything.)
All "visible" borders need to be solid and not bigger than half the height of our element; in this case they are 20px wide, half of our element's height: 40px;.
Because it is possible to set a border-color to transparent, we can create the pointy shape we want.

::after position
We are using position: absolute; to place the ::after element exactly where we need it. It will by placed right: -20px;, outside of our link. The value is the negative version of our pointy border-width we used before.

As a hover effect we will only change the background of the button link. For a, we will do it normally, simply adding on to the end of our selector .button a:hover.
In order to change the border-color of our arrow, we stick the ::after behind the regular hover: .button a:hover::after.
As normally, we only write the values we want to change, the background-color of the link and only the styling of the border for border-left.

Disclaimer: I did not come up with the idea to create arrows this way. But I can't remember where I read it for the first time. But considering the history of CSS, this method of creating arrow shapes is around for ages already. Longer than ::before and ::after I am sure.


  • ::before and ::after are always avaiable for all elements and do not require HTML code to be written.
  • When using ::before and ::after it is necessary to always add content: " "; declaration or it will not show.
  • The ::before and ::after pseudo-elements can display text, images or shapes; basically anything that can be created with CSS.

Do not hesitate to ask me questions if you don't understand anything or want clarification :)

Happy creating :peace: :heart:

Have a suggestion?

Let me know in a comment or a note. I'd love to hear what you want to know and learn. With your input and suggestions this series can continue and grow.

Covering the ::before and ::after pseudo-elements.
Learn how to add images, create custom bullet points and arrow shapes to these elements. Actually the arrow thing works with borders, but no need to be nitpicky here :P
It's a rather long tutorial in the end and may not be for beginner level. Knowing your way around CSS helps to code the pseudo-elements and it will save you some frustration :)

If there is something you want to know/learn about regarding journal skins and/or CSS/HTML, let me know and I will add it to future tutorials La la la la
I am always looking for ideas for new tutorials and by knowing what you want to learn, I can do so in a much better way :XD: 

Previous CSS Tricks

:bulletgreen: Limiting .text width

Any questions? Just ask :eager: by darkmoon3636

I hope you like this and find it helpful Heart Peace
© 2014 - 2022 pica-ae
Join the community to add your comment. Already a deviant? Log In
SquidCannonArmed's avatar
Shame we cannot use filter property here on DA Would have been nice to do some animation stuff aswell.