How To Make a CSS Shine Effect Animation

Marilena

By Marilena

15 min read
Bookmark this post

Welcome to this post! Today, I will share with you how to create a fascinating CSS shine effect animation. To make it more interesting and attractive, I have already prepared an avatar (using only HTML and CSS) and added the animation to it. If you’re curious about how I made the avatar, you can find the complete avatar code at the end of this post. Please feel free to enclose it in your animation if you wish. Remember, the most important thing is to have fun and let your creativity shine. 😉 ✨

For the moment, let’s focus on making this astonishing animation!

HTML structure

To begin, we need to create the base for our project by adding the HTML structure. We’ll start by creating our avatar-container , which will serve for our manipulations. I will carefully guide you through the following steps to achieve the desired results. Once we have a good structure in place, we can build upon it our CSS shine effect.

<div class="avatar-container">
 ... Here goes my avatar
</div> <!-- end of avatar-container -->
HTML

CSS basic structure

Moving forward, let’s focus on organizing our project’s visual appeal by adding the CSS structure. Our first step will be to center the avatar-container on the screen, therefore, we can take advantage of the display: flex property of the body element. This will help us align it along the horizontal and vertical axes, creating a perfectly centered layout. With this basic structure in place, we can then proceed to add styles and create everything we have in mind. 😊

$body-color: #6e87ef;

* {
  margin: 0;
  padding: 0;
  box-sizing: border-box;
}

html,
body {
  height: 100%;
}

body {
  width: 100%;
  display: flex;
  align-items: center;
  justify-content: center;
  background: $body-color;
}
SCSS

CSS avatar container

In order to place the avatar inside the container, it is essential to set it position: relative. Then we can place the components we want to include for our avatar, just by adding position: absolute to them.

.avatar-container {
  position: relative;
  min-width: 320px;
  height: 320px;
  background-color: transparent;
  box-shadow: inset 0 0 20px;
  border-radius: 50%;
} /* end of avatar-container */
SCSS

CSS Shine Effect

All the necessary preparations have been completed. Let’s now move forward and make the shine 🥳 effect.

Create the shine

  • Firstly, we use :before pseudo-element which allows styling specific parts of an element without adding extra content to HTML. It behaves as a child of the chosen CSS element. In our case, avatar-container takes extra data only by using :before CSS property.
  • Next, we set width: 30% and height: 100% as this is a proper space in our example.
  • We also set background-color: rgba(255, 255, 255, 0.4) as it is the most suitable for the CSS shine effect.
  • We continue with z-index which overlaps the stack order of an HTML element. In simple words, it manages which HTML element should appear on top of others. The higher the stack order, the higher the element will be placed at the top of the stacking order. A really useful CSS property that is responsible for layering. To achieve the desired effect over my avatar, I have specified a z-index: 4 as my avatar has multiple layers. Without multiple layers applied to it (in simple words without the avatar), z-index CSS property is not necessary. It’s good practice when we use z-index to count close numbers. We can set positive and negative integer values.
.avatar-container {
    position: relative;
    width: 320px;
    height: 320px;
    background-color: transparent;
    box-shadow: inset 0 0 20px;
    border-radius: 50%;
    overflow: hidden;
    &:before {
      position: absolute;
      content: "";
      width: 30%;
      height: 100%;
      background-color: rgba(255, 255, 255, 0.4);
      transform: skewX(-20deg);
      left: -120px;
      z-index: 3;
    } /* end of before */
  } /* end of avatar-container */
SCSS

The image below displays a preview of the code mentioned above.

Transform the CSS shine effect

  • Afterward is necessary to add overflow: hidden to avatar-container, as we want to hide the content that flows over our container’s bounds.
  • We continue with transform: skew as a way to add inclination to our shine.
  • Finally left: -120px keeps our effect in the appropriate place, -120px left out of the avatar-container , in order to be invisible. As we previously used, overflow: hidden anything outside of the avatar-container is not visible, that’s why in this pick, below, we can’t see our effect. It’s still there though! 😄

HINT

💡 Well, maybe at this point it might be a good idea to temporarily disable the CSS property overflow: hidden and observe the current position of the effect. By doing so, one can see if the effect is working as intended and make any necessary adjustments. The effect is now positioned -120 pixels to the left, as this is the starting point from where the effect will begin to move.

Create an animation for the CSS shine effect

  • To finalize my work, firstly, I’m adding the animation CSS property animation: <animation-name> <animation-duration> <animation-iteration-count> which is responsible for the way our animation behaves.
  • Secondly, I add CSS @keyframes which is used to control the style of the animation at different points in time. In this post, we want our shine to move rightwards, starting from -120px left to 350px left and then turning back to -120px left again.
  • By combining these 2 properties we end up having the desired animation result, that is, moving our shine every 5 seconds, forever (infinite), from -120px to 350px and back.

🚫 It is required to connect these two properties. We do so by giving a name to the @keyframes and putting the same name on the animation property. In our case, this name is “shine”.

.avatar-container {
  ...
  &:before {
    ...
    animation: shine 5s infinite;
  } /* end of before */
} /* end of avatar-container */
  
  
/* My animation */
@keyframes shine {
  0% {
    left: -120px;
  }
  50% {
    left: 350px;
  }
  0% {
    left: -120px;
  }
}
SCSS

💡 If you want to see the whole move of the CSS shine effect you can once again disable the CSS property overflow: hidden to avatar-container and observe the effect. Isn’t it great? 😄


🔖 Please be informed that you have the flexibility to modify the background-color: rgba(..., ..., ..., ...) CSS property at any point to adjust both the color and opacity of your shine effect. In this context, I have chosen to generate a grey shine, as this shade is widely recognized and utilized.

Below, I add some examples with different shades. You are free to try them, or you can experiment and create some from scratch! 🛠

Yellow shade -> background-color:rgba(255, 255, 0, 0.2)

🧨 Blue shade -> background-color:rgba(100, 100, 250, 0.5) always remember to make contrasts. Avoid using the same color for backgrounds and shades.

You can also try to change both the container’s and shades’ background-color.

Pink shade -> background-color:rgba(238, 130, 238, 0.3)

Container’s color -> background-color: #c4c0c0 (grey)

Complete avatar code

Below, I include my HTML and CSS avatar code.

<div class="avatar-container">
  <div class="hair-long"></div>
  <div class="face">
    <div class="ear ear--left">
      <div class="earing earing--left"></div>
    </div>
    <div class="ear ear--right"></div>
    <div class="hair-front"></div>
    <div class="eyebrow eyebrow--left"></div>
    <div class="eyebrow eyebrow--right"></div>
    <div class="eye eye--left">
      <div class="eyelash eyelash--left"></div>
      <div class="eyelash eyelash--left1"></div>
      <div class="eyelash eyelash--left2"></div>
      <div class="eyelash eyelash--left3"></div>
      <div class="eyelash eyelash--left4"></div>
    </div> <!-- end of left eye -->
    <div class="eye eye--right">
      <div class="eyelash eyelash--right"></div>
      <div class="eyelash eyelash--right1"></div>
      <div class="eyelash eyelash--right2"></div>
      <div class="eyelash eyelash--right3"></div>
      <div class="eyelash eyelash--right4"></div>
    </div> <!-- end of right eye -->
    <div class="nose"></div>
    <div class="lips"></div>
  </div> <!-- end of face -->
  <div class="body-avatar">
    <div class="neck"></div>
    <div class="t-shirt"></div>
    <div class="dungarees">
      <div class="pocket"></div>
      <div class="strap strap--left">
        <div class="button button--left"></div>
      </div>
      <div class="strap strap--right">
        <div class="button button--right"></div>
      </div>
    </div> <!-- end of dungarees -->
  </div> <!-- end of body -->
</div> <!-- end of avatar-container -->
HTML
Expand
$body-color: #6e87ef;
$skin-color: #fac8b9;
$hair-color: #36272a;
$hair-ombre-color: linear-gradient(#36272a 50%, #1616ee);
$eyebrow-color: #36272a;
$eye-color: #6d84c0;
$eye-base-color: #f1f1f1;
$eyeline-color: #472a2a;
$eyelash-color: #171616;
$iris-color: #000;
$earing-color: red;
$nose-color: #2b2a2a;
$lips-color: #f50000;
$t-shirt-color: #2c171b;
$dungarees-color: #6d84c0;
$strap-color: #6d84c0;
$button-color: #2d2c2c;


* {
  margin: 0;
  padding: 0;
  box-sizing: border-box;
}

html,
body {
  height: 100vh;
}

body {
  width: 100%;
  display: flex;
  align-items: center;
  justify-content: center;
  background: $body-color;
}

.avatar-container {
  position: relative;
  min-width: 320px;
  height: 320px;
  background-color: transparent;
  box-shadow: inset 0 0 20px;
  border-radius: 50%;
  overflow: hidden;

  .hair-long {
    position: absolute;
    width: 130px;
    height: 170px;
    border-radius: 44% 44% 10px 10px;
    top: 30px;
    left: 50%;
    transform: translate(-50%);
    background: $hair-ombre-color;
    filter: drop-shadow(0 0 3px);
  }

  .face {
    position: absolute;
    width: 100px;
    height: 110px;
    border-radius: 100% / 50% 50% 160% 160%;
    background-color: $skin-color;
    top: 58px;
    left: 50%;
    transform: translate(-50%);
    z-index: 2;
    box-shadow: 0 0.5px 2px darken($skin-color, 10%);
    .ear {
      position: absolute;
      width: 10px;
      height: 22px;
      background-color: $skin-color;
      border-radius: 40%;
      top: 40px;
      z-index: 3;
      &--left {
        left: -6px;
        transform: rotate(-8deg);
        &:before {
          content: "";
          position: absolute;
          width: 6px;
          height: 12px;
          background-color: $skin-color;
          border-radius: 40% 40% 50% 50%;
          box-shadow: -1px -1px 1px darken($skin-color, 10%);
          top: 3px;
          left: 2px;
        }
      }
      &--right {
        right: -6px;
        transform: rotate(8deg);
        &:before {
          content: "";
          position: absolute;
          width: 6px;
          height: 10px;
          background-color: $skin-color;
          border-radius: 40% 40% 50% 50%;
          box-shadow: 1px -1px 1px darken($skin-color, 10%);
          top: 3px;
          right: 2px;
        }
      }
      .earing {
        position: absolute;
        width: 4px;
        height: 4px;
        background-color: $earing-color;
        filter: drop-shadow(0 0 1px);
        border-radius: 50%;
        transform: rotate(4deg);
        &:before {
          content: "";
          position: absolute;
          width: 2px;
          height: 16px;
          background-color: $earing-color;
        }
        &:after {
          content: "";
          position: absolute;
          width: 6px;
          height: 6px;
          background-color: $earing-color;
          border-radius: 50%;
        }
        &--left {
          top: 15px;
          left: 4px;
          &:before {
            top: 3px;
            right: 1px;
          }
          &:after {
            top: 15px;
            left: -1px;
          } 
        }
      } // end of earing
    } // end of ear
    .hair-front {
      position: absolute;
      width: 104px;
      height: 30px;
      top: -2px;
      left: -2px;
      border-radius: 5px;
      background-color: $hair-color;
      &:before {
        content: "";
        position: absolute;
        width: 28px;
        height: 6px;
        background-color: $hair-color;
        border-radius: 50%;
        top: 34px;
        left: -11px;
        transform: rotate(-90deg);
      }
      &:after {
        content: "";
        position: absolute;
        width: 28px;
        height: 6px;
        background-color: $hair-color;
        border-radius: 50%;
        top: 34px;
        right: -11px;
        transform: rotate(-90deg);
      }
    }  // end of hair-front

    .eye {
      position: absolute;
      width: 20px;
      height: 20px;
      top: 39px;
      background-color: $eye-base-color;
      border: 2px solid $eyeline-color;
      border-radius: 85% 10%;
      transform: rotate(45deg);
      &:before {
        content: "";
        position: absolute;
        width: 10px;
        height: 10px;
        top: 50%;
        left: 50%;
        transform: translate(-50%, -50%);
        background-color: $eye-color;
        border-radius: 50%;
        box-shadow: inset 1px 1px 1px 1px #17460d;
      }
      &--left {
        left: 17px;
        box-shadow: -1px 0 2px darken($eyeline-color, 50%);
      }
      &--right {
        right: 17px;
        box-shadow: 0 -1px 2px darken($eyeline-color, 50%);
      }
      &:after {
        content: "";
        position: absolute;
        width: 4px;
        height: 4px;
        top: 50%;
        left: 50%;
        transform: translate(-50%, -50%);
        background-color: $iris-color;
        border-radius: 50%;
      }
      .eyelash {
        position: absolute;
        width: 1px;
        height: 5px;
        background-color: $eyelash-color;
        &--left,
        &--left1,
        &--left2,
        &--left3,
        &--left4 {
          transform: rotate(90deg);
        }
        &--left {
          top: -2px;
          left: 1px
        }
        &--left1 {
          top: 1px;
          left: -2px
        }
        &--left2 {
          top: 5px;
          left: -5px
        }
        &--left3 {
          top: 9px;
          left: -6px
        }
        &--left4 {
          top: 13px;
          left: -6px
        }
        &--right {
          top: -2px;
          right: 14px;
        }
        &--right1 {
          top: -5px;
          right: 10px;
        }
        &--right2 {
          top: -7px;
          right: 6px;
        }
        &--right3 {
          top: -8px;
          right: 2px;
        }
        &--right4 {
          top: -8px;
          right: -1px;
        }
      }  // end of eyelash
    }  // end of eye

    .eyebrow {
      position: absolute;
      width: 35px;
      height: 7px;  
      border: solid 4px $hair-color;
      border-color: $hair-color transparent transparent transparent;
      border-radius: 50%/10px 10px 0 0;
      top: 32px;
      &--left {
        left: 7px;
      }
      &--right {
        right: 7px;
      }
    } // end of eyebrows

    .nose {
      position: absolute;
      width: 2px;
      height: 18px;
      border: 2px solid $nose-color;
      border-left: 0px;
      border-top-right-radius: 80% 40%;
      border-bottom-right-radius: 80% 60%;
      top: 50px;
      left: 46px;
      &:before {
        position: absolute;
        content: "";
        width: 1px;
        height: 3px;
        background-color: $nose-color;
        top: 19px;
        transform: rotate(-30deg);
      }
      &:after {
        position: absolute;
        content: "";
        width: 2px;
        height: 2px;
        border-radius: 50%;
        background-color: $nose-color;
        top: 20px;
        left: 5px;
      }
    } // end of nose

    .lips {
      position: absolute;
      width: 24px;
      height: 10px;
      border-radius: 50%;
      background-color: $lips-color;
      top: 86px;
      left: 50%;
      transform: translate(-50%);
      box-shadow: inset 0 0 7px;
      &:after {
        content: "";
        position: absolute;
        width: 0;
        height: 0;
        border-left: 6px solid transparent;
        border-right: 6px solid transparent;
        border-top: 3px solid $skin-color;
        border-radius: 60%;
        top: -1px;
        left: 6px;
      }
    } // end of lips
  } // end of face

  .body-avatar {
    .neck {
      position: absolute;
      width: 34px;
      height: 50px;
      background-color: $skin-color;
      filter: drop-shadow(0 0 2px);
      top: 152px;
      left: 50%;
      transform: translate(-50%);
      z-index: 1;
      &:before {
        content: "";
        position: absolute;
        width: 60px;
        height: 30px;
        background-color: $skin-color;
        border-radius: 50%;
        top: 35px;
        left: 50%;
        transform: translate(-50%);
      }
    }

    .t-shirt {
      position: absolute;
      width: 160px;
      height: 140px;
      background-color: $t-shirt-color;
      border-radius: 100% / 40% 40% 20% 20%;
      top: 190px;
      left: 50%;
      transform: translate(-50%);
      filter: drop-shadow(0 0 3px);
    } // end of t-shirt

    .dungarees {
      position: absolute;
      width: 100px;
      height: 100px;
      background-color: $dungarees-color;
      border-radius: 5%;
      box-shadow: inset 0 0 5px;
      top: 240px;
      left: 50%;
      transform: translate(-50%);
      .pocket {
        position: absolute;
        width: 50px;
        height: 50px;
        background-color: $dungarees-color;
        border: 1px dashed black;
        box-shadow: 0 0 5px;
        top: 25px;
        left: 50%;
        transform: translate(-50%);
      }
      .strap {
        position: absolute;
        width: 10px;
        height: 64px;
        background-color: $strap-color;
        box-shadow: inset 0 0 5px;
        top: -47px;
        .button {
          position: absolute;
          width: 5px;
          height: 5px;
          background-color: $button-color;
          border-radius: 50%;
          top: 52px;
          &--left {
            left: 50%;
            transform: translate(-50%);
          }
          &--right {
            left: 50%;
            transform: translate(-50%);
          }
        } // end of button
        &--left {
          left: 5px;
          border-radius: 6px 0 10px 0;
        }
        &--right {
          right: 5px;
          border-radius: 0 6px 0 10px;
        }
      } // end of strap
    } // end of dungarees
  } // end of body-avatar
} // end of avatar-container
SCSS
Expand

🌼 Hope you found my post interesting and helpful. Thanks for being here! 🌼

DigitalOcean Referral Badge
guest
0 Comments
Inline Feedbacks
View all comments

Continue reading

Front, Programming

Learn How to Select Only the CSS First Child

Front, Programming

The CSS nth-of-type Selector – How To Target Elements By Type

Front, Programming

What You Need to Know About CSS nth child Selector – A Practical Guide

Front, Programming

CSS Selectors nth-child VS nth-of-type And How To Use Them Correctly

Front, Programming

Coding Made Easy With CSS Selectors: An Ultimate Guide

Front, Programming

How to Center in CSS Using Different Ways

Front, Programming

What You Need to Know About CSS Color Methods

Programming

Most Common Typescript Errors and How to Solve Them

Front, Programming

Make Your Work Easier by Using Variables in CSS

Front, Programming

CSS Rainbow Text: How To Make Astonishing And Vibrant Fonts

Front, Programming

Most Useful HTML Elements for Maximizing Better Results

Back, Programming

Environment Variables 101: Secure Your Secrets Like a Pro

Subscribe to our newsletter

Dive into the Fun Side of Tech! Posts, News, and More Delivered to Your Inbox!

Intuit Mailchimp