How to use CSS ::before and ::after to create custom animations and transitions

How to make a smooth animated transition on a website without using special libraries? A tutorial on using CSS pseudo-elements to create effects: from an animated button to a profile card. Suitable for beginners.

To put into practice the methods from the article, you need:

  • Basic understanding of HTML

  • Basic understanding of CSS

  • Code editor and browser

What are pseudo elements

Pseudo-elements are selectors css , which are used to insert content that is not in the source code, they are used to style a specific part of the selected element. They start with a double colon: ::before, ::after, ::placeholder, ::first-letter. This article will focus only on the use ::before And ::after.

Pseudo element ::before inserts content before the element.

h1::before {
  content: "😀";
}

Pseudo element ::after inserts content after the element.

h1::after{
  content: "";
}

What is the difference between a pseudo element and a pseudo class?

Pseudo-elements and pseudo-classes are sometimes confused because they sound similar, but in fact they are completely different phenomena.

Pseudo elements add content. In contrast, pseudo-classes are selectors that select elements that are in a certain state. Example – pseudo class :hoverwhich allows CSS rules to be applied to an element only when hovering over the element.

Syntactically, a pseudo-class starts with a colon, and a pseudo-element starts with a double colon.

How to create animation using pseudo-elements

Chances are you are already familiar with many CSS properties. Just in case, here we will first look at some of them.

  • transform

  • transition

  • positioning

  • z-index

If you already know enough about them, go straight to the instructions.

Transform and Transition

In this project we use the properties transform And transitionso you need to understand what they do and what they are for.

Transform initially allows you to move, rotate, scale and skew the element.

.box-1 {  
 transform: translate(100px, 100px);
}
.box-2 {  
 transform: rotate(60deg);
}
.box-3 {  
 transform: scale(2);
}
.box-4 { 
  transform: skew(-30deg);
}

Property transition sets the duration of the changes so that the animation is smooth.

Positioning with relative and absolute

There are several CSS properties that help control the flow of a document and the position of an element within a document. In this article, we will only be interested in relative And absolute.

relative value

Relative allows you to control the position of an element relative to itself in the document flow. For example, you can move an object using its original position as a reference point:

.box-2 {
  position: relative;
  right: 150px;
  top: 0;
}

As you can see, the second box is shifted to the right by 150 pixels from its original position, but this does not affect the flow of the document, because the space specified in the layout does not change.

absolute value

When we set an element to absolute, CSS removes the element from the normal flow of the document, overlapping other elements. Element with value absolute positioned relative to the block with the position value relative – parent container.

When there is no such block nearby, the body of the document is used as the starting point.

.parent-container {
  position: relative;
}
.box-1 {
  position: absolute;
  left: 20px;
  top: 20px;
}
.box-2 {
  position: absolute;
  right: 50px;
  bottom: 40px;
}

Controlling the stacking order of elements using z-index

Property z-index allows you to stack elements one on top of the other and change the stacking order. If the element is higher in the stacking order, it will appear before the element with the lowest value:

.box-1 {
  z-index: 1;
}
.box-2 {
  z-index: 2;
}
.box-3 {
  z-index: 3;
}
.box-4 {
  z-index: 4;
}

Z-index only works on elements that have been positioned with a property position. If two elements have the same z-indexthe last one in the HTML markup will be on top.

Creating Animations with Pseudo-Elements

Let’s start the first project by creating a simple animated button to understand how to use pseudo-elements for animation.

Create an anchor tag that will later be applied to the button.

<a href="#" class="btn">Hover Me</a>

Here’s what will come out:

Go to the CSS file and style the link to look like a button.

.btn {
  text-decoration: none;
  border: 2px solid #764abc;
  color: #764abc;
  padding: 10px 20px;
  border-radius: 25px;
    transition: all 1s;
  position: relative;
}

The code should cook for itself – we removed the default underline, added a two-pixel border and recolored the button in the text color. We also added padding to separate the text from the frame, and rounded the edges of the button with a border radius. Added a transition duration of 1 second. That is, any button change will last for a second, smoothly. Finally set the value relative, because inside the button we will place a pseudo-element. The button will become a parent container, relative to which the position of the element with the value will change absolute. Here’s what happens:

It’s time to create a pseudo-element in the button.

.btn::before {
  content: "";
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  background-color: #764abc;
  transition: all 1s;
}

We have created a pseudo element with an empty property contenti.e. there is nothing inside. Positioning it with a value absolutewhich removes the element from the normal document flow so that it overlaps the button, and sets the coordinates top And left zero. So the empty pseudo-element is attached to the button exactly in these places.

Then we set the width and height of the empty element to 100% of the parent element, the button.

As a result, we recolored the background of the pseudo-element in the color of the button and once again added a second transition. Here’s what happens:

As you can see, the pseudo-element overlaps the button – due to the value absolute properties position.

Let’s solve this problem using z-indexto change the overlay context. Position the pseudo-element behind the button using a negative value z-index. Then we use translateto move the pseudo element to the left by -100%.

.btn::before {
  /*...previous code */
  z-index: -1;
  transform: translateX(-100%);
}

Here’s what happens:

Now let’s animate the pseudo-element so that it returns to its original position when the user hovers over the button. Using a Pseudo-Class :hover.

.btn:hover::before {
  transform: translateX(0);
}

Essentially, when the button is hovered over, the pseudo-element returns to the position absolute. Here is the result:

.btn:hover {
  color: #fff;
}

Since we have added translate to the button itself, the changes will take place smoothly.

Last step: applicable overflow: hidden to the button to hide any element that goes outside the container. The property will hide the pseudo-element, we will see it when it returns to its original position.

.btn {
  /*...previous code. */
  overflow: hidden;
}

Final variant:

So we’ve created an animated button using a pseudo element. Full code here.

Create Advanced Profile Animation with Lots of Pseudo Elements

Now let’s complicate the task and make a more complex animated profile card using four pseudo-elements already. Let’s make an interesting hover effect. Here is what will be in the markup.

<div class="profile-card">
      <div class="info">
        <h2>John Doe</h2>
        <p>Ceo / Founder</p>
      </div>
</div>

We have created a simple card div with user data: name and position.

Let’s go to CSS and change the style of the card.

.profile-card {
  width: 300px;
  height: 400px;
  border-radius: 8px;
  box-shadow: 0 4px 8px rgba(0, 0, 0, 0.2);
  display: grid;
  place-items: center;
  position: relative;
  background: url("/image.jpg") no-repeat center center/cover;
}

We created a card with a fixed width and height, placed the content inside and centered it using CSS Grid. Added a shadow around the edges to make everything look more realistic. Then set the card value relativeto make it the parent pseudo-element container. At the end, we added a background image in the center.

Let’s move on to creating pseudo-elements. It is not simple. You need to use four pseudo-elements, but an element can only have one pseudo-element ::before and one pseudo element ::after. To get around this limitation, we use the card itself to make two pseudo-elements, and then a block info div inside the card to make two more. Let’s start with info div.

.info::before {
  content: "";
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  background: #764abc;
  transform: skew(30deg) translateX(100%);
  opacity: 0.3;
  z-index: -1;
  transition: all 0.6s ease;
}

Because the block info div there is no fixed width and height, the pseudo-element takes the width and height of the parent card.

Then we tilt it 30 degrees and shift it 100%. The block is moved to the right. A negative index ensures that it stays behind the text. Make the block transparent.

Let’s move on to the next pseudo-element:

.info::after {
  content: "";
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  background: #764abc;
  transform: skew(-30deg) translate(90%);
  box-shadow: 0 0 20px rgba(0, 0, 0, 0.7);
  opacity: 0.3;
  z-index: -1;
  transition: all 0.6s ease;
}

We did pretty much the same as before, only reversed the direction of the slope and added a block shadow to simulate 3D.

Now let’s make it so that when you hover over the card, the pseudo-elements move inside the card. Let’s add transition for smooth animation.

.profile-card:hover .info::before {
  transform: skew(30deg) translateX(50%);
}
.profile-card:hover .info::after {
  transform: skew(-30deg) translateX(40%);
  opacity: 0.7;
}

Here’s what happens:

Now we make pseudo-elements for the card itself.

.profile-card::before {
  content: "";
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  background: #764abc;
  opacity: 0.3;
  transform: skew(30deg) translate(100%);
  transition: all 0.6s ease;
  z-index: -1;
}

Everything is already clear from the code. We repeat everything that we have already done, just move the pseudo-element ::before right 85 percent. Then we create the last pseudo-element and tilt it to the other side.

.profile-card::after {
  content: "";
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  background: #764abc;
  opacity: 0.3;
  transform: skew(-30deg) translate(85%);
  transition: all 0.6s ease;
  z-index: -1;
}

As you may have guessed, on hover, the pseudo-elements move inward. But this time the trajectory will be longer.

.profile-card:hover:before {
  transform: skew(30deg) translateX(30%);
}
.profile-card:hover:after {
  transform: skew(-30deg) translateX(20%);
}

The card is almost ready. Set the property overflow how hiddento hide anything that extends beyond the edges.

.profile-card {
 /*...previous code. */
  overflow: hidden;
}

Happened:

Change the text color to white and make it transparent. When the cursor is on the card, we remove the transparency so that the text becomes visible.

.info h2, .info p {
  color: #fff;
  opacity: 0;
  transition: all 0.6s;
}
.profile-card:hover .info h2,
.profile-card:hover .info p {
  opacity: 1;
}

Outcome:

While everything. As you can see, pseudo-elements ::before And ::after help develop animation.

Similar Posts

Leave a Reply