Tag: transform

Simple explanations and examples of CSS transform — rotate, scale, translate, and more, with practical tips you can use right away at littlecoding things.

  • Infinite Flipping Card Animation Utilizing Transform And Keyframes CSS Properties

    Infinite Flipping Card Animation Utilizing Transform And Keyframes CSS Properties

    Welcome to this article, where I will guide you through some simple steps of creating a stunning CSS infinite flipping card animation. With my easy-to-follow instructions, you’ll be able to design a beautiful and eye-catching card in no time. Don’t miss this opportunity to elevate your website and impress your audience! 😉

    Let’s proceed and direct our attention towards creating this distinctive animation!

    CSS Infinite flipping card effect animation

    The supplied HTML and SCSS (Sass) code generates a flip card that exhibits movement along both the Y and X axes. The X-axis and Y-axis represent two intersecting lines, defining the coordinates of a point in a two-dimensional space.

    Now, let’s analyze the code one step at a time:

    HTML structure

    Let’s start by examining the HTML structure. We begin by creating a container element with the class flip-wrapper. This container acts as the main hub for our animation. Inside this container, we have a special area with the class flip-card. So, now we have a parent element and a child element. The parent element is where we will build the animation while the child element is the one that determines the appearance of our animation.

    <div class="flip-wrapper">
      <div class="flip-card"></div>
    </div>
    HTML

    CSS Basic Structure

    In our CSS code example, we start by making the whole page’s background-color a shade of gray (#c3c8c3).

    Then, for the container called .flip-wrapper we decide its size by giving it a fixed width and height of 300 pixels. We also make it look circular or rounded by using the border-radius property. It’s important to mention that you can keep it square ⬛ if you prefer, but I went with the rounded look ⚫ because it helps us see clearly the effect.

    Moving on to the .flip-card element, we set its width and height to 100% as a way to cover the entire available space. We make it look nicer by giving it a linear-gradient background using white and black colors. A subtle gray shadow effect is also a nice touch, giving a sense of depth. To keep the circular style consistent, we add the inherit value to border-radius property.

    body {
      background-color: #213450; /* dark blue */
    }
    
    .flip-wrapper {
      width: 300px;
      height: 300px;
      border-radius: 50%;
      .flip-card {
        width: 100%;
        height: 100%;
        background-color: #e1b6ea; /* lavender */
        box-shadow: inset 0 0 30px;
        border-radius: inherit;
      }
    }
    SCSS

    This is what’s currently visible on our screen.

    Creating the CSS flipping card effect animation

    To achieve this captivating effect, we must employ the following two CSS properties: animation and @keyframes. Let’s dive deeper into their analytical exploration.

    To create an infinite flipping card animation it is essential to connect the animation and @keyframes CSS properties. Otherwise, it won’t work.

    Setting the animation CSS property

    In this section of the code, we’re applying the CSS animation property to the element we want to make the animation, in our case to the .flip-wrapper class. The purpose of this property is to associate the animation with the element, as we mentioned above.

    • First of all, we need a name for our animation. Here the animation is named rotation. This name acts as a reference point, allowing us to reuse and target this specific animation throughout our stylesheet.
    • Then we have to give it a duration. Our example has a duration of 8 seconds 8s. This duration defines how long the animation takes to complete one cycle, indicating that the entire animation, from start to finish, will span over 8 seconds.
    • Additionally, it’s set to repeat infinitely. This means that once the animation completes, it restarts immediately and runs continuously without a break. This creates a continuous animation effect (loop 🌪 😂).

    In summary, we are using the animation property to apply an animation named ‘rotation’ to the .flip-wrapper class, making it last for 8 seconds and repeat indefinitely, resulting in an uninterrupted, continuous animation for an element.

    .flip-wrapper {
      ...
      animation: rotation 8s infinite;
      .flip-card {
        ...
      }
    }
    SCSS

    Ways to add the @keyframes

    In the @keyframes rotation section, we define the animation behavior. It specifies a transformation that involves rotating an element around its X-axis and Y-axis. Here’s a breakdown of its key components:

    • @keyframes: This is the rule used to define the keyframes for the animation. Keyframes specify how the animation should change over time, in this case, from the starting state (from) to the ending state (to).
    • rotation: This is the name given to the animation, and it will be used to reference the animation when applying it to elements using the animation property.
    • from and to: These define the initial and final states of the animation. In the from state, the element has a rotation of 0 degrees around the X-axis, meaning it starts with no rotation. In the to state, the element is rotated 360 degrees, completing one full rotation, around the X-axis and/or Y-axis.
    • transform: The transform property is used to apply a specific transformation to the element. In rotation animations, (the specific transformation applied can vary, such as rotating, scaling, or skewing the element.) it enables the element to change its orientation.
    transform: rotateY()

    In the following CSS animation, named rotation , our animation starts from a rotation of 0 degrees (from) and smoothly transitions to a 360-degree rotation (to) around the Y-axis.

    /* ANIMATION */
    @keyframes rotation {
      from {
        transform: rotateY(0deg);
      }
      to {
        transform: rotateY(360deg);
      }
    }
    SCSS
    transform: rotateX()

    This CSS animation, named rotation rotates the element around its X-axis. It starts (from) with no rotation (0 degrees) and smoothly completes (to) a full 360-degree rotation.

    /* ANIMATION */
    @keyframes rotation {
      from {
        transform: rotateX(0deg);
      }
      to {
        transform: rotateX(360deg);
      }
    }
    SCSS

    We have the capability to create rotations along both the Y and X axis at the same time.

    transform: rotateX() rotateY()

    In this CSS animation named rotation the element is rotated in both the X and Y axes. It starts (from) with no rotation (0 degrees in both axes) and gradually complete (to) a full 360-degree rotation in both the X and Y axes. This animation can create a complex spinning effect that involves rotations in multiple directions. Cool huh!! 😎

    /* ANIMATION */
    @keyframes rotation {
      from {
        transform: rotateX(0deg) rotateY(0deg);
      }
      to {
        transform: rotateX(360deg) rotateY(360deg);
      }
    }
    SCSS

    What to avoid when making a CSS flipping card effect animation

    As a reminder, it’s important to ensure that our animation transitions smoothly. To achieve a complete rotation, we must rotate (from) 0 degrees (to) 360 degrees. In the provided animation code, the @keyframes specifies a rotation of (160 deg) for both the X and Y axes, resulting in a card flip effect. However, this setup does not create a smooth transition beyond the 180-degree point. The card abruptly returns to its initial position, giving it a characteristic stop-and-return appearance. To achieve a more natural and realistic flipping effect, we need to ensure a complete 360-degree rotation or a half 180-degree rotation.

    /* ANIMATION */
    @keyframes rotation {
      from {
        transform: rotateX(0deg) rotateY(0deg);
      }
      to {
        transform: rotateX(160deg) rotateY(160deg);
      }
    }
    SCSS

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

  • Static VS Dynamic Design With CSS – From Stillness to Action

    Static VS Dynamic Design With CSS – From Stillness to Action

    CSS in motion! Another perfect title for this post, as CSS is no longer just a language to style static pages, but also to elevate them with animations. CSS entered a new era and has grown into a clever tool that brings digital interfaces to life through movement. It began to shine, showing its full potential and ultimately becoming part of the experience, not just the look.

    CSS properties for movement

    Now, time to focus on where CSS credits its upgrade. Utilizing the following properties: transformtransitionanimation and @keyframes, elements can scaleslidefadespin and move through time all without a single line of JavaScript. Today, we’ll focus on understanding how these properties create such amazing visual feedback. We’ll take a step back from the code and examine these features from a more theoretical perspective: what they mean, how they influence behavior, and why they play such a crucial role in modern design.
    So, let’s zoom in! 🧐

    Transform CSS property

    It applies 2D or 3D transformations 🛠 to an element. It can change the sizerotation, position, and shape.
    Values:

    • scale(): Resize elements – making them smaller or bigger depending on our preferences (use unitless numbers).
    • skew(): Slant elements (use deg, which stands for degrees).
    • translate(): Move elements (use length units like: %pxrem, etc.).
    • rotate(): Spin elements (use deg, like skew).

    📌 Depending on our needs and preferences, we are free to make combinations with the above values.

    • perspective(): Creates a 3D effect, giving the elements a sense of depth.
    • matrix(): Creates 2D transformations. It provides a streamlined approach for applying scaling, skewing, translation, and rotation through a unified matrix. (a mathematical representation – transform: matrix(a, b, c, d, e, f) – that combines the first three transformations into a single matrix. If you want to include rotation as well, you would replace a, b, c, and d with the appropriate cosine and sine values for the desired rotation angle, while keeping e and f for translation.)

    Transition CSS property

    It animates changes in property values over time ⏳ and smoothens the transition between two stages (e.g. on hover, focus)
    Values:

    • transition-property: What property will animate (e.g. transformopacity)
    • transition-duration: How much time does the transition take to complete (e.g. 0.4ss stands for seconds, we are free to use ms too, for milliseconds)
    • transition-timing-function: Define the speed curve (easelinearease-inease-outease-in-out)
    • transition-delay: The time you wait before an animation starts (s and ms, similar to animation-duration). Its default value is 0s, which means the transition will start instantly.

    Keyframes CSS property

    Define intermediate states of an animation 📽 series. Breaks the animation into episodes 🎬, like “first episode, look like this,” “second episode, change to this,” “third episode, change to that,” and “final episode, finish like that.” Each episode represents a point in the timeline where the property-value changes (opacity, rotation, color, etc.).
    Values:

    • From / To : Timeline positions
    • Percentages % : Timeline positions

    📌 Each one represents a property-value pair that defines the appearance at a specific moment

    Animation CSS property

    It runs 🎞 a full animation based on the @keyframes you have defined. Unlike the transition we mentioned above, which moves from one point to another, animations can have many points ⏱ and follow more complex timing rules.
    Values:

    • name: the identifier of the @keyframes rule
    • duration: for how long it moves
    • time-function: how the speed flows
      • ease: it gives a smooth motion, starts slow, continues faster, and ends slow again (which is the default value)
      • linear: it has the same speed all the way
      • ease-in: it starts slow, then it speeds up
      • ease-out: it starts fast, then it slows down (Suitable for hover effects 😎)
      • ease-in-out: starts slow, in the middle spreads up, then slows down again
    • delay: if the animations begin immediately or with a delay
      • a value of 0s (seconds) indicates it starts as soon as it’s applied (which is the default value)
      • positive value that it will start after a set amount of time (e.g. 2s, which means it will start 2 seconds later)
      • negative value that starts straightforward but acts like it has already begun (e.g. -2s the animation won’t wait — it’ll jump in as if it had already been playing for 2 seconds. This can be very helpful if you want animations to be already in motion when the page loads. 😎)
    • iteration-count: how many times to repeat (infinite12, ech)
    • direction: in which direction the animation moves
      • normal ➡ the animation moves forward (which is the default value)
      • reverse ⬅ the animation moves backward
      • alternate ➡ ⬅ first forward, then backward
      • alternate-reverse ➡ ⬅ ➡ first forward, then backward, then again forward
    • fill-mode: shows how the element should look like before the animation starts or after it ends. You have the option to freeze the first or last frame so it doesn’t snap back (➡ forwards, ⬅ backwards). The default value is none, which means it does not apply any styles to the elements.
    • play-state: control if the animation is running or paused, like play ▶ or pause ⏸ buttons (runningpaused)

    📌 For an animation to actually play, we need to utilize only the: animation-nameanimation-duration and the @keyframe. All the other CSS properties are optional.

    When creating content for the web, even the smallest detail can significantly alter how something appears. The experience of bringing elements to life is amazing! It doesn’t need to be dramatic or complex. A simple yet well-structured and strategically placed change at the right moment can make everything more connected, useful and realistic.

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

  • Flipping Card Animation On Hover Using Transform And Transition CSS Properties

    Flipping Card Animation On Hover Using Transform And Transition CSS Properties

    Greetings! Today, I’m excited to walk you through the steps of crafting an amazing CSS flipping card animation that will activate when the user hovers over it. By following my detailed guidance, you’ll learn how to create a stunning animated card that will grab the attention of your viewers and enhance the overall appearance of your website. So, don’t miss out! 😉

    Let’s focus on making this unique animation!

    CSS Flipping card animation on hover

    The provided HTML and SCSS (Sass) code creates a flip card that moves along the Y and X axis. The X-axis and Y-axis are two lines that cross each other. They’re used to define the location of a point in a two-dimensional space.

    Let’s break down the code step by step:

    HTML structure

    To start, let’s focus on the HTML structure. We begin by creating a parent container with the class flip-wrapper. This container serves as the parent for our captivating animation. Inside this wrapper, we have a child element with the .flip-card class. This particular element is where our animation will take place.

    <div class="flip-wrapper">
      <div class="flip-card"></div>
    </div>
    HTML

    CSS basic structure

    In our CSS code snippet, we start by setting the background-color of the entire page to a deep shade of dark blue (#213450).

    Moving on to the .flip-wrapper container, we specify its dimensions, giving it a fixed width and height of 300 pixels. To create a circular or rounded appearance, we apply border-radius. It’s worth noting that, if desired, you can leave the dimensions as is to maintain a square 🟪 shape. I chose this rounded 🟣 design because it makes it easier for us to observe the effect we’re aiming for. 😉

    Next, we focus on the .flip-card element. We set its witdh and height to 100% to ensure it covers the entire available space. We also enhance its visual appeal with a soothing pastel purple (lavender) background-color and a subtle gray shadow effect. To maintain the circular theme, we add the inherit value to border-radius property.

    body {
      background-color: #213450; /* dark blue */
    }
    
    .flip-wrapper {
      width: 300px;
      height: 300px;
      border-radius: 50%;
      .flip-card {
        width: 100%;
        height: 100%;
        background-color: #e1b6ea; /* lavender */
        box-shadow: inset 0 0 30px;
        border-radius: inherit;
      }
    }
    SCSS

    This is what’s visible on our screen at the moment.

    Ways to add the hover effect

    For our effect to function as intended we have to work with both the parent and the child element. We begin with the parent element where we apply the :hover effect and change the cursor to a pointer 👆. You can check out all cursor style and pick the one that suits you best. 🤗

    .flip-wrapper {
      ...
      &:hover {
        cursor: pointer;
      }
    }
    SCSS

    Next, we’ll move on to our child element. Here, we set the transform CSS property to rotateY and specify the degree (deg) of rotation we desire.

    Afterward, we’ll define the transition CSS property. We can use it in two ways. We add it to the :hover or we can add it directly to the .flip-card class. In the first case, the effect works only when you hover in. In the second case, the effect works when you hover in, but when you hover out it turns back to its original position. Then we set the transform value and specify the duration in seconds (s). In our case, I’ve chosen 8 seconds to make the effect slow and easily observable. 😉

    transform: rotateY()

    hover-in
    .flip-wrapper {
      ...
      &:hover {
        ...
        .flip-card {
          ...
          transform: rotateY(180deg);
          transition: transform 8s;
        }
      }
    }
    SCSS
    hover-in-out
    .flip-wrapper {
      ...
      &:hover {
        ...
          transform: rotateY(180deg);
        }
        .flip-card {
          transition: transform 8s;
        }
      }
    }
    SCSS

    transform: rotateX()

    We do the same, but this time along axisX.

    hover-in
    .flip-wrapper {
      ...
      &:hover {
        ...
        .flip-card {
          ...
          transform: rotateX(360deg);
          transition: transform 8s;
        }
      }
    }
    SCSS
    hover-in-out
    .flip-wrapper {
      ...
      &:hover {
        ...
          transform: rotateX(360deg);
        }
        .flip-card {
          transition: transform 8s;
        }
      }
    }
    SCSS

    We have the capability to create rotations along both the Y and X axes at the same time.

    transform: rotateX() rotateY()

    hover-in
    .flip-wrapper {
      ...
      &:hover {
        ...
        .flip-card {
          ...
          transform: rotateX(180deg) rotateY(180deg);
          transition: transform 8s;
        }
      }
    }
    SCSS
    hover-in-out
    .flip-wrapper {
      ...
      &:hover {
        ...
          transform: rotateX(180deg) rotateY(180deg);
        }
        .flip-card {
          transition: transform 8s;
        }
      }
    }
    SCSS

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

  • How To Build Stunning Rounded Text – Handy Tips

    How To Build Stunning Rounded Text – Handy Tips

    Greetings, all! 😃 I’m excited to share an incredible CSS technique with you today. We’ll learn little by little how to create impressive and rounded text. This technique can give our text a unique and captivating appearance that stands out from the usual. Get ready to take your text to the next level! 🧨 ⚡

    Are you interested in learning how to uplevel your typography? Stick around to explore the endless possibilities of CSS and take your website to new heights! Let the game 🌀 begin and happy designing! 😊

    HTML structure

    To create a text that appears in a rounded effect we begin with the HTML structure. First, we need an HTML div with a specific class. Let’s call it .wrapper. This div will be the container where the text will be displayed. To achieve the desired effect, we also need to add a span element for each character we want to use. By doing so, it allows us to handle and move each character separately and create the shape we want. 😉

    In our example, we will use 15 letters and a star, so we need to add 16 spans. Each span represents a character. You can see the code snippet below for a better understanding.

    <div class="wrapper">
      <span class="character1">I</span>
      <span class="character2">a</span>
      <span class="character3">m</span>
      <span class="character4">a</span>
      <span class="character5">r</span>
      <span class="character6">o</span>
      <span class="character7">u</span>
      <span class="character8">n</span>
      <span class="character9">d</span>
      <span class="character10">e</span>
      <span class="character11">d</span>
      <span class="character12">t</span>
      <span class="character13">e</span>
      <span class="character14">x</span>
      <span class="character15">t</span>
      <span class="character16-emoticon"></span>
    </div>
    HTML

    CSS structure

    We move forward with the CSS. We begin by styling the wrapper HTML element with a width and height of 400 pixels. It will also have a purple background-color, an inset magenta shadow (the inset box-shadow is a clever idea 💡 to create a distinctive boundary inside our wrapper, which will help us later with the positioning), and a border-radius of 50%, giving it a completely round shape. Finally, the flex method will perfectly align our text inside the wrapper.

    Next, we will apply some styling to the spans within the wrapper. They will have a font-family: Arial (we need a really distinct font), a font-size of 40 pixels, and will be colored in a yellowish shade (#eddc42).

    🔖 Note that we won’t add spaces between characters since we will place them one by one. By avoiding spaces, we can achieve precise and accurate positioning, which allows for greater control and flexibility in our design.

    .wrapper {
      width: 400px;
      height: 400px;
      background-color: purple;
      box-shadow: inset 0 0 0px 60px magenta;
      border-radius: 50%;
      display: flex;
      align-items: center;
      justify-content: center;
    }
    
     span {
      font-family: Arial;
      font-size: 40px;
      color: #eddc42;
    }
    CSS

    Below, we can see what is generated on the screen for now. Well, 🤔 in fact, I’m not a rounded text yet! 😃 So, let’s move on!

    Preparation before starting to position the letters

    To be able to make the positioning, we set position: relative property to the wrapper and position: absolute property to the span as a way to move them freely. By doing so, all characters take the same place, but we can observe only the last one as it is on the top.

    .wrapper {
      position: relative;
    }
    
     span {
      position: absolute;
    }
    CSS

    Now, we can see what is currently shown on the screen.
    While I’m not a looping message so far, 🤪 I will be soon! Let’s proceed. 😃

    Creating the rounded shape

    Starting from the two ends and going toward the middle side is a smart tactic to divide the space equally. Remember, we have a star that we will put in the center of the circle, so we do not count it. Thus, we initiate our positioning from the letters “Ι and t”, the first and last letter of our phrase, and place them in the middle of axis-Y by setting top: 50% and transform: translate(-50%) .

    Also, we keep the letters 40 pixels away from the left and right sides, with the left and right CSS properties respectively.

    Finally, transforming our letters setting the transform: rotate() gives them a vibrant and dynamic perspective, bringing them to life in a truly inspiring way.

    .character1 {
      left: 40px;
      top: 50%;
      transform: translate(0, -50%) rotate(-90deg);
    }
    
    .character15 {
      right: 40px;
      top: 50%;
      transform: translate(0, -50%) rotate(90deg);
    }
    CSS

    Now, take a look at this sequence of characters. Notice how both the first and last letters are in their respective positions on the displayed screen. This is a good time to examine how the box-shadow CSS property helps us to count and place the characters accurately. 🟣 🤩 🟣 🤩 🟣

    We move forward with this topic by counting the remaining characters. Ι know! I know! It can be a bit tricky and confusing 🤯 because of the counting, but the result will be amazing!! ✨ 🎉 Therefore, please ensure to maintain the positioning using the same tactic consistently. Finally, I’m including the rest of the code snippet below to complete my work.

    .character2 {
        transform: rotate(-75deg);
        left: 38px;
        top: 144px;
      }
      
      .character3 {
        transform: rotate(-65deg);
        left: 42px;
        top: 113px;
      }
    
      .character4 {
        transform: rotate(-45deg);
        left: 80px;
        top: 68px;
      }
      
      .character5 {
        transform: rotate(-32deg);
        left: 120px;
        top: 42px;
      }
      
      .character6 {
        transform: rotate(-20deg);
        left: 140px;
        top: 32px;
      }
      
      .character7 {
        transform: rotate(-10deg);
        right: 208px;
        top: 25px;
      }
      
      .character8 {
        transform: rotate(5deg);
        right: 175px;
        top: 24px;
      }
      
      .character9 {
        transform: rotate(22deg);
        right: 145px;
        top: 30px;
      }
      
      .character10 {
        transform: rotate(30deg);
        right: 118px;
        top: 42px;
      }
      
      .character11 {
        transform: rotate(42deg);
        right: 90px;
        top: 60px;
      }
      
      .character12 {
        transform: rotate(65deg);
        right: 60px;
        top: 100px;
      }
      
      .character13 {
        transform: rotate(65deg);
        right: 45px;
        top: 122px;
      }
      
      .character14 {
        transform: rotate(80deg);
        right: 38px;
        top: 152px;
      }
    CSS

    As we can see, all letters are in their respective positions on the displayed screen and our text is finally taking a rounded shape. 🟣 🤩 🟣 🤩 🟣

    To finalize, it would be better if the star appears bigger so we modify the .character16-emoticon class and adjust the font-size property to 100px. Additionally, the box-shadow property needs to be updated to achieve the desired visual effect. Therefore, we will need to go back and make the necessary changes to ensure it looks exactly as we want it to.

    .wrapper {
      ...
      box-shadow: inset 0 0 30px 10px magenta;
    }
    
    .character16-emoticon {
      font-size: 100px;
    }
    CSS

    Tada! Our rounded text is ready! 🥳 💪 Enjoy! 🎊 🎊

    Complete code solution

    Below is the full code referenced in this blog post. Feel free to copy and use it in your own projects. If you have any questions or encounter any issues, don’t hesitate to reach out for assistance. You can easily copy the desired code snippet by clicking on the copy icon, located in the top-right corner of each snippet.

    <div class="wrapper">
      <span class="character1">I</span>
      <span class="character2">a</span>
      <span class="character3">m</span>
      <span class="character4">a</span>
      <span class="character5">r</span>
      <span class="character6">o</span>
      <span class="character7">u</span>
      <span class="character8">n</span>
      <span class="character9">d</span>
      <span class="character10">e</span>
      <span class="character11">d</span>
      <span class="character12">t</span>
      <span class="character13">e</span>
      <span class="character14">x</span>
      <span class="character15">t</span>
      <span class="character16-emoticon"></span>
    </div>
    HTML
    Expand
    * {
      margin: 0;
      padding: 0;
      box-sizing: border-box;
    }
    
    html,
    body {
      height: 100vh;
    }
    
    body {
      background-color: #f5f5f5;
      display: flex;
      align-items: center;
      justify-content: center;
    }
    
    .wrapper {
      width: 400px;
      height: 400px;
      background-color: purple;
      box-shadow: inset 0 0 0px 60px magenta;
      border-radius: 50%;
      display: flex;
      align-items: center;
      justify-content: center;
    }
    
     span {
      font-family: Arial;
      font-size: 40px;
      color: #eddc42;
    }
    
    .character1 {
      left: 40px;
      top: 50%;
      transform: translate(0, -50%) rotate(-90deg);
    }
      
    .character2 {
      transform: rotate(-75deg);
      left: 38px;
      top: 144px;
    }
      
    .character3 {
      transform: rotate(-65deg);
      left: 42px;
      top: 113px;
    }
    
    .character4 {
      transform: rotate(-45deg);
      left: 80px;
      top: 68px;
    }
      
    .character5 {
      transform: rotate(-32deg);
      left: 120px;
      top: 42px;
    }
      
    .character6 {
      transform: rotate(-20deg);
      left: 140px;
      top: 32px;
    }
      
    .character7 {
      transform: rotate(-10deg);
      right: 208px;
      top: 25px;
    }
      
    .character8 {
      transform: rotate(5deg);
      right: 175px;
      top: 24px;
    }
      
    .character9 {
      transform: rotate(22deg);
      right: 145px;
      top: 30px;
    }
      
    .character10 {
      transform: rotate(30deg);
      right: 118px;
      top: 42px;
    }
      
    .character11 {
      transform: rotate(42deg);
      right: 90px;
      top: 60px;
    }
      
    .character12 {
      transform: rotate(65deg);
      right: 60px;
      top: 100px;
    }
      
    .character13 {
      transform: rotate(65deg);
      right: 45px;
      top: 122px;
    }
      
    .character14 {
      transform: rotate(80deg);
      right: 38px;
      top: 152px;
    }
    
    .character15 {
      right: 40px;
      top: 50%;
      transform: translate(0, -50%) rotate(90deg);
    }
    
    .character16-emoticon {
      font-size: 100px;
    }
    
    CSS
    Expand

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

  • How CSS Became So Powerful with Animations

    How CSS Became So Powerful with Animations

    Hi there! You’re aware that the web 🕸 wasn’t always like it is today? Websites were like digital 📰 posters – just text and images. A page loads, and no changes occur. Static design had the reins. No movement, no glow! 🤹‍♀️ ✨ Everything remained visually frozen. 🧊 🥶 CSS was only a tool to decorate that static content and make some improvements, such as selecting a font, changing colors, adding a border or a margin.

    As time went on, browsers improved, and users began to expect more. That’s when CSS started to shine and show the way from static pages to fluid experiences! With features like transition, transform, animation, and keyframes, the focus shifted from how things looked to how they can pulse and move in time. Dynamic design is finally here! CSS became a language capable of transforming static HTML elements into dynamic 🧨 ones.

    Motion matters. It allows users to feel when something changes and witness how elements react. It’s a way of communication, 🔊 not just decoration. With only CSS, designers can craft these interactions. Creating animations that ‘rotate‘, ‘skew‘, scale‘ or ‘shift‘ position suggests ongoing system activity. A sliding menu, like a ‘hamburger icon‘, reveals categories, indicating that navigation continues beyond the current view. A spinning icon, after a user clicks ‘Submit’ or ‘Save’ on a button, signals that a process is loading. A button that gently fades in and out on hover – labeled ‘Sign Up‘ – asks for interaction. A fading alert, such as ‘Connection lost‘ or ‘Download has failed, retrying‘, quietly suggests that the message is temporary. Even a ‘scale-up‘ focusing on an image can reveal that it is active. CSS became a must to represent progress and maintain users’ attention.

    Of course, as with everything, setting boundaries is essential. Many times action can cause confusion and make users feel distracted or, even worse, rushed. Not every interface needs to include movement. Sometimes, picking stillness is the best choice. Valuable designs recognise when to pause!

  • How to Make a Circular Clickable Button with Shadow Effect

    How to Make a Circular Clickable Button with Shadow Effect

    Hey there! 😃 In today’s technology-obsessed world, it’s absolutely crucial to master the art of creating an amazing circular clickable button. A well-crafted button not only enhances the presentation but also elevates the user experience. Maximizing user attention is vital, and buttons are, most of the time, the key to achieving this goal. By utilizing the right tools and techniques, we can create a visually stunning and functionally efficient button that not only looks great but also delivers an unforgettable user experience. 🆙

    Let’s collaborate to create a standout button that supports user-friendliness.

    HTML Basic Structure

    To start building our button, we need to organize our HTML code snippet. The first step is to create a parent element that will act as the base of our button. We give this element the class name .button-base. Next, we need to add a child element within this parent element to serve as the clickable part of the button. We give this child element the class name .clicable-part. It’s important to nest these two elements within a button HTML element as it’s more semantic, better for accessibility, and behaves correctly in forms and interactive contexts by default.
    Additionally, we need to create the shadow effect for our button, so we add one more HTML element with the class name .button-shadow.

    <button>
      <div class="button-base">
        <div class="clicable-part"></div>
      </div>
    </button>
    <div class="button-shadow"></div>
    HTML

    CSS foundation

    We move forward with CSS and make our button fresh and stylish! For this post, I am writing CSS using Sass syntax. If you would like to convert it to vanilla CSS and don’t already know how, I’d suggest you use an online Sass — CSS converter.

    Prepare the body for the clickable button

    Firstly, we apply a color (#f5f5f5 – dark gray) to the body by setting the background-color. Additionally, we want to center our button. For that reason, we are using the flex method.

    body {
      background-color: #f5f5f5;
      
      display: flex;
      align-items: center;
      justify-content: center;
    }
    SCSS

    Create the base of the clickable button

    To create the base of our button, we start by making a square with a width and height of 200 pixels. Then, we make it rounded by adding a border-radius of 50%. We use a pale white color (#f9f9f9) for the button’s background-color. To give it a more stylish look, we add some shadows using the box-shadow property.

    Finally, we add the flex method to prepare the space to position the clickable part of the button in the center of the base.

    📍 As seen in the code snippet below, we need to include border: none and background-color: transparent properties in the button element to ensure it will display only the styles we define. These properties remove the browser’s default styles that typically come with. As a result, it provides us with a clean starting point, so the button appears exactly as we’ve styled it, with no unexpected borders or colors.

    button {
      border: none;
      background-color: transparent;
      .button-base {
        width: 200px;
        height: 200px;
        border-radius: 50%;
        background-color: #f9f9f9;
        box-shadow: inset 0 6px 8px #eae8e8, /* top inset shadow */
          inset 0 -2px 15px #ccc7c7, /* bottom inset shadow */
          0 3px 3px #d6d1d1; /* bottom shadow */
        
        display: flex;
        align-items: center;
        justify-content: center;
      }
    }
    SCSS

    In the image below, you can see the base of the button we just created.

    An image showing the base of the circular clickable button

    Create the clickable part of the button

    To create the clickable part of our button, we first set the height and width to 80%. Then, we apply a border-radius: inherit to make it appear rounded and follow the shape of the base. For the background of the button, we use a linear-gradient that adds depth as it gives a bright orange color at the top that gradually becomes darker as it goes down. To add a more stylish look, we include shadows using the box-shadow property.

    .clicable-part {
      width: 80%;
      height: 80%;
      border-radius: inherit;
      border: 1px solid white;
      background: linear-gradient(
        to bottom,
        #f7eb13,
        #fd741b
        );
      box-shadow: inset 0px 3px 6px #ffa500, /* top inset shadow */
        0px 1px 3px #d05a05, /* bottom inset shadow */
        0 6px 6px #bcb8b8; /* bottom shadow */
    }
    SCSS

    The following image shows the clickable part we just added on the top of the base.

    An image showing the base of the circular clickable button. On it's top it has the clickable part.

    Add content at the top of the clickable part

    To add content at the top of the clickable part of a button, we can use a :before pseudoelement. Inside the pseudoelement, we can insert the desired symbol or text using the content property. For instance, in our case, a question mark emoticon (?) has been used, but you can use any symbol or text you prefer. It’s important to note that the flex method in the .clickable-part class is essential, as it centers the mark correctly.

    .clicable-part {
      ...
      display: flex;
      align-items: center;
      justify-content: center;
      &:before {
        position: absolute;
        content: "❔";
      }
    }
    SCSS

    The image below displays the content we added on the top of the clickable part of the button.

    An image showing the base of the circular clickable button. On it's top it has the clickable part. The clickable part it has a question mark on.

    Add the hover effect on the top of the clickable button

    To add a hover effect, we set the :hover CSS property. For the cursor, I prefer using the value pointer (👆), but feel free to choose any other style from the plethora of options available here. Finally, I apply the filter: brightness and increase it to 110%. This makes our button appear brighter whenever the mouse hovers over it. ✨

    .clicable-part {
      ...
      &:before {
        ..
      }
      &:hover {
        cursor: pointer;
        filter: brightness(110%);
      }
    }
    SCSS

    The gif below demonstrates how the hover effect (👆) appears.

    Activate the clickable part of the button

    To make your button fully functional, you need to activate its clickable part. We can achieve this by adding the :active property. Next, we give it a background with a linear-gradient that creates a sense of depth by providing a bright magenta color at the top that gradually becomes darker as it goes down. To make it more visually appealing, we include shadows using the box-shadow property.

    .clicable-part {
      ...
      &:before {
        ..
      }
      &:hover {
        ...
      }
      &:active {
        background: linear-gradient(
          to bottom,
          #f767f7,
          #df0361
          );
          box-shadow: inset 0px 3px 6px #df0361, /* top inset shadow */
          0 3px 5px #bcb8b8; /* bottom shadow */
      }
    }
    SCSS

    The following gif displays the activated clickable area.

    Update the button’s content when it is activated

    To enhance the user experience, we can dynamically update the content displayed on the button when it’s clicked. This may be accomplished by adding a :before pseudoelement and inserting the desired content into the content property. In our case, we will display a white heart (🤍) when the button is clicked.

    .clicable-part {
      ...
      &:before {
        ..
      }
      &:hover {
        ...
      }
      &:active {
        ...
        &:before {
          position: absolute;
          content: "🤍";
        }
      }
    }
    SCSS

    With just a single click, this button comes to life and reveals its beautiful new content in the following gif (🤍) – it’s an absolute must-see!! 😎

    Add the shadow effect to the clickable button

    The last thing we have to do is add the shadow effect. We create a rectangle with 140 pixels width and 15 pixels height. Next, we give it a rounded shape by setting the border-radius property to 50%. To create a background that looks like it becomes lighter as it goes toward outer space, we use the radial-gradient technique and make the center darker. To make the whole thing look smoother, we add shadows with the box-shadow property.

    Finally, we utilize the position: absolute combined with the top, left, and transform properties to move it below the button and center it.

    .shadow {
      width: 140px;
      height: 15px;
      border-radius: 50%;
      background: radial-gradient(#a7aaaa, #b2b7b7 10%, #eaeded);
      box-shadow: -5px 0px 10px 5px #eaeded, /* shadow right side */
        5px 0px 10px 5px #eaeded, /* shadow left side */
        inset -5px 0px 5px #eaeded, /* inset shadow right side */
        inset 5px 0px 5px #eaeded; /* inset shadow left side */
        
      position: absolute;
      top: 520px;
      left: 50%;
      transform: translate(-50%);
    }
    SCSS

    The button’s captivating shadow effect is truly impressive and adds to the overall appeal. Hope you find it enjoyable and engaging. Thank you for your attention. 🥳

    An image showing the base of the circular clickable button. On it's top it has the clickable part. The clickable part it has a question mark on. Button also has a shadow below.

    Complete code solution

    Below is the full code referenced in this blog post. Feel free to copy and use it in your own projects. If you have any questions or encounter any issues, don’t hesitate to reach out for assistance. You can easily copy the desired code snippet by clicking on the copy icon, located in the top-right corner of each snippet.

    <button>
      <div class="button-base">
        <div class="clicable-part"></div>
      </div>
    </button>
    <div class="button-shadow"></div>
    HTML
    @mixin flex-all-center {
      display: flex;
      align-items: center;
      justify-content: center;
    }
    
    $body-color: #f5f5f5;
    $button-base-color: #f9f9f9;
    $button-base-inset-top-shadow: #eae8e8;
    $button-base-inset-bottom-shadow: #ccc7c7;
    $button-base-dark-shadow: #d6d1d1;
    $button-color: linear-gradient(to bottom, #f7eb13, #fd741b);
    $button-inset-top-shadow: #ffa500;
    $button-inset-bottom-shadow: #d05a05;
    $button-dark-shadow: #bcb8b8;
    $button-active-color: linear-gradient(to bottom, #f767f7, #df0361);
    $button-active-inset-shadow: #df0361;
    $button-shadow: #eaeded;
    
    * {
      margin: 0;
      padding: 0;
      box-sizing: border-box;
    }
    
    html,
    body {
      height: 100vh;
    }
    
    body {
      background: $body-color;
      @include flex-all-center;
      min-width: 300px;
    }
    
    button {
      border: none;
      background-color: transparent;
      .button-base {
        width: 200px;
        height: 200px;
        border-radius: 50%;
        background-color: $button-base-color;
        box-shadow: inset 0 6px 8px $button-base-inset-top-shadow, /* top inset shadow */
        inset 0 -2px 15px $button-base-inset-bottom-shadow, /* bottom inset shadow */
        0 3px 3px $button-base-dark-shadow; /* bottom shadow */
        @include flex-all-center;
        .clicable-part {
          width: 80%;
          height: 80%;
          font-size: 50px;
          border-radius: inherit;
          border: 1px solid white;
          background: $button-color;
          box-shadow: inset 0px 3px 6px $button-inset-top-shadow, /* top inset shadow */
          0px 1px 3px $button-inset-bottom-shadow, /* bottom shadow */
          0 6px 6px $button-dark-shadow; /* bottom shadow */
          @include flex-all-center;
          &:before {
            position: absolute;
            content: "❔";
          }
          &:hover {
            cursor: pointer;
            filter: brightness(110%);
          }
          &:active {
            background: $button-active-color;
            box-shadow: inset 0px 3px 6px $button-active-inset-shadow, /* top inset shadow */
              0 3px 5px $button-dark-shadow; /* bottom shadow */
            &:before {
              position: absolute;
              content: "🤍";
            }
          }
        } /* end of clicable-part */
      } /* end of button-base */
    } /* end of button */
    
    .button-shadow {
      width: 140px;
      height: 15px;
      border-radius: 50%;
      background: radial-gradient(#a7aaaa, #b2b7b7 10%, #eaeded);
      box-shadow: -5px 0px 10px 5px $button-shadow, /* shadow right side */
        5px 0px 10px 5px $button-shadow, /* shadow left side */
        inset -5px 0px 5px $button-shadow, /* inset shadow right side */
        inset 5px 0px 5px $button-shadow; /* inset shadow left side */
      position: absolute;
      top: 520px;
      left: 50%;
      transform: translate(-50%);
    } /* end of shadow */
    SCSS
    Expand
  • Make a Unique Folded Corner Effect Utilizing the clip-path CSS Property

    Make a Unique Folded Corner Effect Utilizing the clip-path CSS Property

    Hello everybody! I’m excited to share a cool folded corner effect I created using just HTML and CSS. This eye-catching design adds a dynamic flair, creating a realistic illusion that enhances your webpage’s visual appeal —no images, extra scripts, or complex code required. How awesome is that? 😎

    Elements with clip-path do not take shadows directly. Instead, they must be nested within a container to inherit its shadows.

    Creating the folded corner effect using pseudo-element

    We’ll start by using the :before pseudo-element combined with the clip-path property to create the folded corner effect. The main element, which contains the pseudo-element, is styled with a filter property to apply a shadow. This shadow is then inherited by the pseudo-element, allowing the folded corner to display a subtle, realistic shadow as well. This technique keeps the design lightweight and visually appealing.

    Basic HTML structure for the folded corner effect

    The HTML code snippet creates a card layout. We have a parent element with the class .card, housing two child elements: the first with the class .title for the card’s title, and the second with the class .folded-corner to apply the folded corner effect via CSS.

    <div class="card">
      <div class="title">Folded Corner Effect</div>
      <div class="folded-corner"></div>
    </div>
    HTML

    CSS structure: creating the paper and cut corner

    Starting with the CSS, we define a horizontal rectangle by setting the width to 450px and the height to 300px, along with a subtle 2px border-radius for slightly rounded corners. The background color is set to #228a90, a rich teal with greenish-blue tones that gives the card a fresh, modern look.

    .card {
      width: 450px;
      height: 300px;
      border-radius: 2px;
      background-color: #228a90;
        
      display: flex;
      align-items: center;
      justify-content: center;
    }
    CSS
    Initial paper design before applying folded corner effect

    Then we use the clip-path property to shape the desired paper corner for the folded effect. I chose the top-left corner, but you can select any one you prefer by adjusting the corresponding points in the clip-path: polygon() function.

    .card {
      width: 450px;
      height: 300px;
      border-radius: 2px;
      background-color: #228a90;
      
      clip-path: polygon(0% 30%, 30% 0%, 100% 0%, 100% 100%, 0% 100%);
      position: relative;
    }
    CSS

    Think of the corners in this order: top-left, top-right, bottom-right, bottom-left (clockwise).

    Remember to split each selected corner into two coordinates to get the right look (watch those 👇 magenta measurements! 😉)
    Take into account that the top-left corner has both Axis-X and Axis-Y on 0%.

    Axis coordinates of card showing top-left corner cut, preparing the folded corner effect

    Finally, adding position:relative does not change something in our effect but prepares us for future positioning adjustments. As for centering our elements using flexbox—it’s purely for aesthetic purposes, helping keep everything visually balanced and neat.
    Below, we can see what is rendered on the screen for now. Pretty cool, right!? 😃

    Progress so far: paper with cut corner created using HTML and CSS folded corner effect

    CSS structure: how to create the folded corner effect

    To continue building our effect, we’ll use the folder-corner child element to create a second rectangle within the parent card element. This element will act as the folded piece of paper. We’ll give it a width of 70px and a height of 160px.

    .card .folded-corner {
      width: 70px;
      height: 160px;
      background-color: red;
      position: absolute;
    }
    CSS

    For now, we’ll use a red background color to help us visualize its position and behavior more clearly—this will be updated to its final color later. We’ll also apply position: absolute to enable precise positioning.

    Initial red-colored container element for folded corner effect

    Next, we continue with positioning. We use the top and left properties to move the .folded-corner element closer to the clipped corner, then apply the transform property to rotate it into place.

    .card .folded-corner {
      ...
      top: -7px;
      left: 52px;
      transform: rotate(56deg);
    }
    CSS
    Positioning folded-corner element at top -7px in folded corner effect layout
    top: -7px;
    Positioning folded-corner element at left 52px to align with cut corner
    left: 52px;
    Rotating folded-corner element by 52 degrees using CSS transform property
    transform: rotate(56deg);

    Finally, adding the filter property is essential for completing our effect. As mentioned earlier, applying a shadow directly to an element with a clip-path isn’t possible — so the solution is to create an additional element that can hold the shadow.

    To do this, we’ll add a :before pseudo-element with the same dimensions as our folded corner. This allows us to recreate the folded shape and apply the shadow to it — adding depth and realism to the folded corner effect. 😎

    .card .folded-corner {
      ...
      top: -7px;
      left: 52px;
      transform: rotate(56deg);
      filter: drop-shadow(6px 4px 5px rgba(0, 0, 0, 0.4));
    }
    CSS
    Initial red-colored container element for folded corner effect
    filter: drop-shadow(6px 4px 5px rgba(0, 0, 0, 0.4));

    Next, we move forward by using the before pseudo-element with the content property and set its position to absolute for precise placement within the parent.
    We want this pseudo-element to have the exact dimensions as the parent, so we set both its width and height to 100%, something that allows it to inherit the parent’s size.

    .card .folded-corner:before {
      content: "";
      position: absolute;
      width: 100%;
      height: 100%;
      background: pink;
      border-radius: 0 0 10% 0;
    }
    CSS

    For now, we apply a pink background to help visualize the structure. Finally, we add a border-radius of 10% to the bottom corner, which softens the edge and creates a smoother, more realistic folded appearance.

    Adding the before pseudoelement

    Next, we replace the pink background with a smooth linear gradient. We choose colors similar to the main hue but make them darker towards the edges and lighter in the center. This gradient effect enhances the appearance by making the center appear brighter and polish. ✨

    .card .folded-corner:before {
      ...
      background: linear-gradient(to right, #277c7f 5%, #5abcbc 30%, #63c5c6 40%, #5abcbc 50%, #277c7f 90%, #0d4749);
    }
    CSS
    Adding linear- gradient at the before pseudoelement

    To complete the shape, we apply the clip-path: polygon(0% -2%, 0% 100%, 100% 100%) property. This is essential for transforming the before pseudo-element —which starts as a rectangle, just like its parent—into a triangle.

    In simple words, this clipping path reshapes the element into the desired triangular form. 🥳

    .card .folded-corner:before {
      ...
      clip-path: polygon(0% -2%, 0% 100%, 100% 100%);
    }
    CSS
    Adding clip-path to the before pseudoelement

    The last step is to turn back to the parent element with the class .folded-corner and “remove” the red rectangle from view by simply replacing the red background-color with a transparent value.
    As we can see, the :before pseudoelement inherits its parent shadow effect while the parent becomes invisible.

    .card .folded-corner {
      width: 70px;
      height: 160px;
      background-color: transparent;
      position: absolute;
      top: -7px;
      left: 52px;
      transform: rotate(56deg);
      filter: drop-shadow(6px 4px 5px rgba(0, 0, 0, 0.4));
    }
    CSS
    Finalize the folded corner effect

    We can enhance the title to have a more eye-cathing result. Applying a white background-color, increasing the font-size, and adding a subtle black text-shadow will make the title stand out beautifully, elevating the overall design. 📄 ✨

    .card .title {
      font-family: sans-serif;
      font-size: 40px;
      font-weight: bold;
      text-align: center;
      padding: 0 50px;
      color: white;
      text-shadow: 1px 1px 1px black;
    }
    CSS
    Stylling paper's title

    Complete code example

    <div class="card">
      <div class="title">Folded Corner Effect</div>
      <div class="folded-corner"></div>
    </div>
    HTML
    .card {
      width: 450px;
      height: 300px;
      border-radius: 2px;
      background-color: #228a90;
      clip-path: polygon(0% 30%, 30% 0%, 100% 0%, 100% 100%, 0% 100%);
      position: relative;
      display: flex;
      align-items: center;
      justify-content: center;
    }
    
    .card .folded-corner {
      width: 70px;
      height: 160px;
      background-color: transparent;
      position: absolute;
      top: -7px;
      left: 52px;
      transform: rotate(56deg);
      filter: drop-shadow(6px 4px 5px rgba(0, 0, 0, 0.4));
    }
    
    .card .folded-corner:before {
      content: "";
      position: absolute;
      width: 100%;
      height: 100%;
      border-radius: 0 0 10% 0;
      background: linear-gradient(to right, #277c7f 5%, #5abcbc 30%, #63c5c6 40%, #5abcbc 50%, #277c7f 90%, #0d4749);
      clip-path: polygon(0% -2%, 0% 100%, 100% 100%);
    }
    
    .card .title {
      font-family: sans-serif;
      font-size: 40px;
      font-weight: bold;
      text-align: center;
      padding: 0 50px;
      color: white;
      text-shadow: 1px 1px 1px black;
    }
    CSS
    Expand

    If you have any questions or run into any issues, don’t hesitate to reach out in the comments below — I’m happy to help. You can easily copy any code snippet by clicking the copy icon in the top-right corner of each block.

    Summary

    We started by creating the paper and cutting its corner. Then, we set the clip-path property to define the shape and positioned the folded-corner element precisely over the clipped area. After that, we enhanced the styling with background gradients that match the paper’s tone, and wrapped up by polishing the effect for a clean, realistic look. 📄 ✨

    Wishing you the best of luck in all your creative endeavors! 😃

  • Keyframes in CSS Explained – Make Your Animations Stand Out

    Keyframes in CSS Explained – Make Your Animations Stand Out

    Hi there! 😃 In today’s post, we will analyze the amazing CSS @keyframes rule, an incredibly powerful tool for creating complex and visually stunning animations on web pages.

    Understanding keyframes in CSS

    In simple terms, keyframes define the animation’s behavior through a series of @keyframes which describes how the animation should change over time.
    Each keyframe represents a specific point in time, and CSS smoothly transitions between these keyframes to create fluid motion.

    With CSS keyframes, you can create various animations, from simple color changes to complex effects like movements and transformations. By combining keyframes with other CSS properties, we can control timing and duration and create dynamic and visually engaging websites.

    I will provide you with an example that will make this at-rule crystal clear. 🧐 Let’s grab a ☕ and move forward. 🚀 We’ve got this!

    Example of keyframes in CSS: The theory behind it

    The details of the animation will depend on the specific effect we want to achieve. Let’s say we want to create an animation where a square ⬛ transforms into a circle ⚫ and then back into a square ⬛ again. Additionally, the color 🌈 of the shape changes during the animation, and there are some movements and transitions involved. It might seem massive and confusing, 😰 but we can deal with it step by step together! 🛠

    For our animation to be smooth and realistic, we need to define the @keyframes. The first keyframe serves as the starting point (0%), followed by intermediate points and the final keyframe (100%) that marks the end of the animation and returns to the starting point.

    😃The following code snippet provides a quick example of a keyframes structure in action.

    @keyframes name-of-keyframe {
      0% {
        ... /* this is the starting point */
      }
      50% {
        ... /* this is one intermediate point */
      }
      100% {
        ... /* this is the ending point */
      }
    }
    CSS

    To create these keyframes, you’ll need to use CSS animation properties, such as animation-name, animation-duration, animation-iteration-count and animation-delay. The animation-name property connects the animation to its keyframes, while the other properties control how long it should last, how it should behave over time, and whether it has a delay before starting..

    Once you’ve defined your keyframes and animation properties, CSS will automatically insert transitions between the keyframes to create smooth changes. This means you don’t need to worry about manual calculations. CSS takes care of it for you. Cool huh!? 😎 ✨

    Example of keyframes in CSS: Practical implementation

    As we already mentioned, we will work with a box. We need to start with the HTML code and create a <div> element that has the class name .box.

    <div class="box"></div>
    HTML

    Then, in our CSS code, we define the basic properties. It should be a square with a width and height of 200 pixels, and we’ll keep the background-color simple by using black for now.

    .box {
      width: 200px;
      height: 200px;
      background-color: black;
    }
    CSS

    This is what is rendered on the screen for now. A simple black box.

    Applying animation effects to the elements

    To add animation effects to our <div> element, we need to define the animation properties of our class .box. We set the animation-name, which is the animation’s name, then the animation-duration, which is the time the animation takes to complete, and finally, the animation-iteration-count which declares how many times the animation should repeat.

    .box {
      ...
      animation-name: my-animation;
      animation-duration: 10s;
      animation-iteration-count: infinite;
    }
    
    /* ----- MY ANIMATION ----- */
    @keyframes my-animation {}
    CSS

    Then, we create our animation using the @keyframes rule, where we can specify the values of the CSS properties at different points during the animation. The most crucial step is to link the animation to our element. We do this by using the animation-name property and assigning it to the same name we defined earlier. In our case my-animation.

    Transforming colors and shapes with animation

    We will start our transformations by working with colors and shapes using the background-color and border-radius properties.

    /* ----- MY ANIMATION ----- */
    @keyframes my-animation {
      0% {
        background-color: pink;
      }
      25% {
        background-color: purple;
        border-radius: 50%;
      }
      50% {
        background-color: black;
        border-radius: 50%;
      }
      75% {
        background-color: purple;
        border-radius: 50%;
      }
      100% {
        background-color: pink;
      }
    }
    CSS

    As we can see, it begins with a pink square at starting point: 0%. Then, it transitions to purple (25%) where it starts becoming cyclic. After that, it turns to black (50%) and remains a full circle. Then (75%) shifts to purple again, where it starts transitioning back to a square. Finally (ending point: 100%) turns to a pink square.

    Keyframes in CSS: A pink square transitions into a purple circle, then a black circle, and back to a pink square using CSS @keyframes, background-color, and border-radius properties.

    Animating Element Position

    The next step is adjusting the position of our box. To do this, we need to adjust the positioning of the HTML element associated with our .box class and set it to position: relative, allowing it to move within its container.

    Now, let’s animate its movement:

    • The animation starts at the top-left corner 0%.
    • At 25%, it moves diagonally by changing both the top and left values.
    • At 50%, it continues moving horizontally to the left.
    • At 75%, it moves diagonally back by adjusting top and left again.
    • Finally, at 100%, it returns to its original position at the top-left corner.
    .box {
      ...
      position: relative;
    }
    
    /* ----- MY ANIMATION ----- */
    @keyframes my-animation {
      0% {
        ...
        left: 0px;
        top: 0px;
      }
      25% {
        ...
        left: 200px;
        top: 100px;
      }
      50% {
        ...
        left: 300px;
      }
      75% {
        ...
        left: 200px;
        top: 100px;
      }
      100% {
        ...
        left: 0px;
        top: 0px;
      }
    }
    CSS
    CSS animations: A pink square moves from the top left while transforming into a purple circle, then shifts left and becomes a black circle, before returning to the top left as a pink square using CSS @keyframes, top, and left properties.

    Animating Element Rotation

    We can also make our box a little bit playful! 🤹‍♀️ We will add some extra moves with the amazing transform CSS property.

    We will apply a rotation only between 25% and 75%.

    • The animation starts with no rotation at 0%.
    • At 25%, the element remains unrotated with transform: rotateY(0deg).
    • At 50%, it completes a full rotation with transform: rotateY(360deg)
    • At 75%, it returns to its original position with transform: rotateY(0deg).
    • Finally, at 100%, the cycle resets, ready to repeat.
    /* ----- MY ANIMATION ----- */
    @keyframes my-animation {
      0% {
        ...
      }
      25% {
        ...
        transform: rotateY(0deg);
      }
      50% {
        ...
        transform: rotateY(360deg);
      }
      75% {
        ...
        transform: rotateY(0deg);
      }
      100% {
        ...
      }
    }
    CSS
    CSS animations with @keyframes: This image shows a pink square moving from top left and turning to a purple circle, then moving only to left by rotating at axis-Y and turning to a black circle and then again moving back to top left and turning to a pink square using the CSS @keyframes property and the css transform: rotateY() property.

    Now, let’s try to make it even more impressive by enriching the starting and ending phases.

    • At 0%, we add transform: rotateX(360deg).
    • At 25%, it resets with transform: rotateX(0deg), creating a rotation along the X-axis from 0% to 25%.
    • At 50% and 75%, we maintain a non-rotating phase with transform: rotateX(0deg).
    • Finally, at 100%, we add transform: rotateX(360deg), creating another rotation from 75% to 100%.
    /* ----- MY ANIMATION ----- */
    @keyframes my-animation {
      0% {
        ...
        transform: rotateX(360deg);
      }
      25% {
        ...
        transform: rotateX(0deg);
      }
      50% {
        ...
        transform: rotateX(0deg);
      }
      75% {
        ...
        transform: rotateX(0deg);
      }
      100% {
        ...
        transform: rotateX(360deg);
      }
    }
    CSS
    CSS Keyframes: This image shows a pink square that rotating to axis-X from top left and turning to a purple circle, then moving only to left by rotating at axis-Y and turning to a black circle and then again rotating to axis-X going back to top left and turning to a pink square using the CSS @keyframes property and the css transform: rotateY() property.

    Inserting content into the animated element

    We can also add any content we want (text, image, emoticon, etc.) inside our HTML element. For our example, I use an emoticon and set its font-size to 100px.

    <div class="box">
      <div class="emoticon">🪐</div>
    </div>
    HTML
    .box .emoticon {
      font-size: 100px;
    }
    CSS
    CSS keyframes: This image shows a pink square with a perfectrly centered emoticon (Ringed planet) inside it, that rotating to axis-X from top left and turning to a purple circle, then moving only to left by rotating at axis-Y and turning to a black circle and then again rotating to axis-X going back to top left and turning to a pink square using the CSS @keyframes property. We create this animation setting the CSS animation-name, CSS animation-duration and CSS animation-iteration-count properties.

    Delaying the animation start

    We can add a delay to our animation by setting the animation-delay CSS property. This delay momentarily pauses the animation before it begins, creating a smoother and more controlled start.

    For instance, if we set the delay to 2s, the animation will start after 2 seconds. However, please note that this delay occurs only once when we first see the animation. To observe the effect again, we may need to refresh the page. 

    .box {
      ...
      animation-delay: 2s;
    }
    CSS

    You can see the animation with the delay effect below. It starts with its initial black background-color and after the 2s it starts the transitions we created with the @keyframes. 😉

    CSS Keyframes: This image shows a pink square with a perfectrly centered emoticon (Ringed planet) inside it, that rotating to axis-X from top left and turning to a purple circle, then moving only to left by rotating at axis-Y and turning to a black circle and then again rotating to axis-X going back to top left and turning to a pink square using the CSS @keyframes property. This animation has a starting delay of 2 seconds. We do so using the CSS animation-delay property.

    Using the @keyframes shorthand for animations

    By using shorthand, you can save space and time while improving your code’s readability. Instead of writing multiple properties separately, you can define them all using just the animation shorthand.

    .box {
      animation-name: my-animation;
      animation-duration: 10s;
      animation-iteration-count: infinite;
      animation-delay: 2s;
      
      /* Here’s the shorthand version */
      animation: my-animation 10s 2s infinite;
    }
    CSS

    Complete CSS animation code (copy & paste ready)

    Below is the full code referenced in this blog post. Feel free to copy and use it in your own projects.

    If you have any questions or encounter any issues, don’t hesitate to ask for help. You can easily copy the desired code snippet by clicking on the copy icon, located in the top-right corner of each snippet.

    We’d love to hear your thoughts! If you have feedback or questions, drop a comment below.

    <div class="box">
      <div class="emoticon">🪐</div>
    </div>
    HTML
    * {
      margin: 0;
      padding: 0;
      box-sizing: border-box;
    }
    
    html,
    body {
      height: 100vh;
    }
    
    .box {
      width: 200px;
      height: 200px;
      background-color: black;
      
      position: relative;
      display: flex;
      align-items: center;
      justify-content: center;
      
      animation: my-animation 10s 2s infinite;
    }
    
    .box .emoticon {
      font-size: 100px;
    }
    
    /* ----- MY ANIMATION ----- */
    @keyframes my-animation {
      0% {
        left: 0px;
        top: 0px;
        background-color: pink;
        transform: rotateX(360deg);
      }
      25% {
        left: 200px;
        top: 100px;
        background-color: purple;
        border-radius: 50%;
        transform: rotateY(0deg) rotateX(0deg);
      }
      50% {
        left: 300px;
        background-color: black;
        border-radius: 50%;
        transform: rotateY(360deg) rotateX(0deg);
        visibility: visible;
      }
      75% {
        left: 200px;
        top: 100px;
        background-color: purple;
        border-radius: 50%;
        transform: rotateY(0deg) rotateX(0deg);
      }
      100% {
        left: 0px;
        top: 0px;
        background-color: pink;
        transform: rotateX(360deg);
      }
    }
    CSS
  • How to Make A Blinking Animation Using CSS

    How to Make A Blinking Animation Using CSS

    Hey there! In this post, I will show you how to create a pair of blinking eyes effect using only CSS (SCSS), complete with a smooth blinking animation to bring the eyes to life. A cow’s pair of eyes! Yes, yes, you read it right! We are dealing with a hidden 🐮 cow! Below, you can see our new 🐄 friend, with flesh and bones.

    We are dealing with a hidden 🐮 cow!

    HTML Structure

    Firstly, let’s build our blinking eyes’ initial structure using only HTML:

    <div class="face">
      <div class="eye eye--left"></div>
      <div class="eye eye--right"></div>
      <div class="eyebrow eyebrow--left"></div>
      <div class="eyebrow eyebrow--right"></div>
    </div>
    HTML

    CSS Structure

    Secondly, we continue by enhancing our HTML with CSS, starting from the body. We use flexbox as we want to place our face container in the center of our screen.

    body {
      height: 100vh; // gives us the full screen-size height
      background-color: black;
      display: flex;
      align-items: center;
      justify-content: center;
    }
    CSS

    CSS Face Structure

    Next, we add our face container styling in order to be ready for our eyes’ positioning. We set background-color: white; just for contrast since our eyes will be black. Afterward, we use display: grid; and place-items: center; because we want our container’s children, our eyes, to get centered.

    .face {
      position: relative;
      width: 300px;
      height: 200px;
      background-color: white;
      display: grid;
      place-items: center;
    }
    CSS

    Adding the eyes

    Afterward, we continue by creating our beautiful cow’s 👀 eyes.

    .face {
      ...
      .eye {
        position: absolute;
        width: 64px;
        height: 80px;
        background-color: black;
        border-radius: 30px;
        overflow: hidden;
        &:before { // iris
          content: "";
          position: absolute;
          width: 28px;
          height: 28px;
          background-color: white;
          border-radius: 50%;
        } // end of before 
        &--left { // position of left eye
          left: 200px;
          transform: rotate(-10deg);
          &:before { // position of left iris
            top: 8px;
            right: 12px;
          }
        }
        &--right { // position of right eye
          right: 200px;
          transform: rotate(10deg);
          &:before { // position of right iris
            top: 8px;
            left: 12px;
          }
        }
      } // end of eye 
    } // end of face
    SCSS

    Adding the blinking animation

    Now is the right time, drum 🥁 roll, to add our blinking animation 😉 .

    .face {
      ...
      .eye {
        ...
        &:after { // eyelid 
          content: "";
          position: absolute;
      
          /* takes the same width as the eye (width: 64px;)
          in order to cover the whole eye when blinking */
          width: 100%;
          /* we need 0 initial height - as our starting point before the 
          animation runs */
          height: 0%;
          background-color: white;
          border-radius: 30px;
          box-shadow: 1px -2px 2px 2px white;
      
          /* here we add our "blink" animation since this is the
          html part (:after - blinking) we want to make animate.
          We want the animation to repeat every 4 seconds forever.
          */ 
          animation: blink 4s infinite ease-in;
        } // end of after
      } // end of eye
    } // end of face
    
    /* we name our animation "blink". We set different height percentages
    as a way to set our eye lids STAY IN DIFFERENT PART each time */ 
    @keyframes blink {
      0% {
        height: 0%;
      }
      30% {
        height: 0%;
      }
      33% {
        height: 100%;
      }
      40% {
        height: 0%;
      }
      70% {
        height: 0%;
      }
      75% {
        height: 100%;
      }
      78% {
        height: 0%;
      }
      81% {
        height: 100%;
      }
      84% {
        height: 0%;
      }
      100% {
        height: 0%; 
      }
    }
    SCSS

    Hint 💡
    Moreover, you should apply box shadow (check code above) to make the blinking eyelid overflow the eyes’ borders. This way during the blinking animation it will cover the whole eye and make it more realistic!

    Adding the eyebrows

    Finally, we add the 🤨 eyebrows to complete the gaze.

    .face {
      ...
      .eye {
        ...
      } /* end of eye */ 
      
      .eyebrow {
        position: absolute;
        width: 70px;
        height: 20px;
        border: solid 4px black;
        border-color: black transparent transparent transparent;
        border-radius: 50%/20px 20px 0 0;
        top: 40px;
        &--left {
          left: 40px;
          transform: rotate(10deg);
        }
        &--right {
          right: 40px;
          transform: rotate(-10deg);
        }
      } /* end of eyebrow */
    } /* end of face */
    SCSS

    Complete code solution

    Below is the full CSS code referenced in this blog post. Feel free to copy and use it in your projects.

    body {
      height: 100vh; // gives us the full screen-size height
      background-color: black;
      display: flex;
      align-items: center;
      justify-content: center;
    }
    
    .face {
      position: relative;
      width: 300px;
      height: 200px;
      background-color: white;
      display: grid;
      place-items: center;
      .eye {
        position: absolute;
        width: 64px;
        height: 80px;
        background-color: black;
        border-radius: 30px;
        overflow: hidden;
        &:before { // iris
          content: "";
          position: absolute;
          width: 28px;
          height: 28px;
          background-color: white;
          border-radius: 50%;
        } // end of before 
            &:after { // eyelid 
          content: "";
          position: absolute;
      
          /* takes the same width as the eye (width: 64px;)
          in order to cover the whole eye when blinking */
          width: 100%;
          /* we need 0 initial height - as our starting point before the 
          animation runs */
          height: 0%;
          background-color: white;
          border-radius: 30px;
          box-shadow: 1px -2px 2px 2px white;
      
          /* here we add our "blink" animation since this is the
          html part (:after - blinking) we want to make animate.
          We want the animation to repeat every 4 seconds forever.
          */ 
          animation: blink 4s infinite ease-in;
        } // end of after
        &--left { // position of left eye
          left: 200px;
          transform: rotate(-10deg);
          &:before { // position of left iris
            top: 8px;
            right: 12px;
          }
        }
        &--right { // position of right eye
          right: 200px;
          transform: rotate(10deg);
          &:before { // position of right iris
            top: 8px;
            left: 12px;
          }
        }
      } // end of eye 
      .eyebrow {
        position: absolute;
        width: 70px;
        height: 20px;
        border: solid 4px black;
        border-color: black transparent transparent transparent;
        border-radius: 50%/20px 20px 0 0;
        top: 40px;
        &--left {
          left: 40px;
          transform: rotate(10deg);
        }
        &--right {
          right: 40px;
          transform: rotate(-10deg);
        }
      } /* end of eyebrow */
    } // end of face
    
    @keyframes blink {
      0% {
        height: 0%;
      }
      30% {
        height: 0%;
      }
      33% {
        height: 100%;
      }
      40% {
        height: 0%;
      }
      70% {
        height: 0%;
      }
      75% {
        height: 100%;
      }
      78% {
        height: 0%;
      }
      81% {
        height: 100%;
      }
      84% {
        height: 0%;
      }
      100% {
        height: 0%; 
      }
    }
    SCSS
    Expand
  • How To Make A CSS Text Reflection Effect

    How To Make A CSS Text Reflection Effect

    Hi there! 😃 In this post, we’ll learn bit by bit how to create a CSS text reflection effect. When we say reflection, we’re referring to a mirror-like effect that looks like the text reflects on a surface, much like the way we see our reflection in a mirror.

    This is a simple yet amazing way to enhance the appearance of your text. Let’s analyze our effect so that you can easily follow along.

    HTML structure

    We will begin with our HTML structure. As you can see below, I prepared a div with the class .reflection-text , this is where our effect will take place.

    <div class="reflection-text">HELLO WORLD</div>
    CSS

    CSS foundation

    Let’s move forward with the CSS basic structure. We start with defining the background. It’s worth noting that using radial-gradient can make our effect more impressive. 😃

    body {
      background: radial-gradient(lightgreen, darkgreen);
      height: 100vh;
    }
    CSS

    Below, we can see the background we just created.

    In web development, we use the flex method in order to center our text. Then we will enhance its appearance, by making some adjustments. We will set the font-size to 100 pixels, select the “Roboto” font-family, and choose white as the text color.

    body {
      ...
      display: flex;
      align-items: center;
      justify-content: center;
    }
    
    .reflection-text {
      font-size: 100px;
      font-family: 'Roboto', sans-serif;
      color: white;
    }
    CSS

    This is what is rendered on the screen for now. A perfectly centered, 🎯 white text.

    Adding the CSS structure for the reflection effect

    Creating a reflection can be achieved by using pseudoelements like :before and :after. To ensure this works properly, we need to include position: relative in our .reflection-text class.

    .reflection-text {
      ...
      position: relative;
    }
    CSS

    Now, we are ready to proceed and create our reflection by adding the :before pseudoelement with all the necessary properties, as shown in the following code snippet.

    .reflection-text:before {
      content: "HELLO WORLD";
      position: absolute;
      top: 65px;
      transform: rotate(180deg) scaleX(-1);
      background: linear-gradient(
        to bottom, 
        rgba(255, 255, 255, 0) 20%, 
        rgba(255, 255, 255, 0.5) 60%, 
        rgba(255, 255, 255, 2) 100%
      );
      background-clip: text;
      color: transparent;
      opacity: 0.3;
    }
    CSS

    Breaking down the process

    🟢 To begin, we add the text “HELLO WORLD” to create another text element with the same content. This new text will serve as our reflection. Then, we set position: absolute so that we can move our reflected text below the original text. We use the top property to move the reflected text 65 pixels from the top, but you can always move the reflection in any direction you prefer. It is important to position the text and its reflection closely together for a more realistic reflection effect. 😉

    🟢 We move forward and use the transform CSS property to rotate the text by 180 degrees

    and then flip it horizontally using scaleX(-1). Now we have the perfect reflection! Let’s continue and make it more realistic.

    🟢 In the next step, we will adjust the color of our reflected text. To achieve this, we will utilize the linear-gradient CSS property and specify the direction as downwards. This will create white gradients, with the top appearing more intense and gradually fading towards the bottom of the text.

    🟢 It is commonly known that gradients cannot be directly applied to texts. Don’t worry! 🤔 We already have the solution to this problem. For now, let’s give a quick explanation. To create a clipped linear background pattern for text, first, we add the -webkit-background-clip: text property, and at the same time, we set the color to transparent, and our text automatically turns to transparent. In that way, our text takes the background: linear-gradient as its real color.

    🟢 For a more transparent text, we can adjust the opacity. The lower the opacity, the more transparent our text becomes. So, here we are! Our reflection is ready! 🥳

    Exploring different colors

    🔖 It is always an option to use black or any other color in our work. Below, I’ve included examples of texts with black, purple, and green colors. It’s important to remember that the key factor is to set the correct gradients at the linear-gradient property. That way, we can create respective shades. Therefore, please give extra attention to that! 😊

    Black text

    .reflection-text {
      position: relative;
      font-size: 100px;
      font-family: 'Roboto', sans-serif;
      color: black; /* default color */
    }
    CSS
    .reflection-text:before {
      content: "HELLO WORLD";
      position: absolute;
      top: 65px;
      transform: rotate(180deg) scaleX(-1);
      background: linear-gradient(to bottom, 
      rgba(0, 0, 0, 0) 20%, 
      rgba(0, 0, 0, 0.5) 60%, 
      rgba(0, 0, 0, 2) 100%);
      background-clip: text;
      color: transparent;
      opacity: 0.3;
    }
    CSS

    Purple Text

    .reflection-text {
      position: relative;
      font-size: 100px;
      font-family: 'Roboto', sans-serif;
      color: purple;
    }
    CSS
    .reflection-text:before {
      content: "HELLO WORLD";
      position: absolute;
      top: 65px;
      transform: rotate(180deg) scaleX(-1);
      background: linear-gradient(to bottom, 
      rgba(255, 55, 205, 0) 20%, 
      rgba(255, 55, 205, 0.5) 60%, 
      rgba(255, 55, 205, 2) 100%);
      background-clip: text;
      color: transparent;
      opacity: 0.3;
    }
    CSS

    Green Text

    .reflection-text {
      position: relative;
      font-size: 100px;
      font-family: 'Roboto', sans-serif;
      color: green;
    }
    CSS
    .reflection-text2:before {
      content:"HELLO WORLD";
      position: absolute;
      top: 65px;
      transform: rotate(180deg) scaleX(-1);
      background: linear-gradient(to bottom, 
      rgba(20, 150, 20, 0) 20%, 
      rgba(20, 150, 20) 60%, 
      rgba(20, 150, 20, 2) 100%);
      background-clip: text;
      color: transparent;
      opacity: 0.3;
    }
    CSS
  • How To Make a CSS Shine Effect Animation

    How To Make a CSS Shine Effect Animation

    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
  • Make Amazing CSS 2D Card With Flipping Animation On Hover

    Make Amazing CSS 2D Card With Flipping Animation On Hover

    Hello! In this post, I will show you how to create a visually appealing CSS 2d card with flipping animation that activates when you hover over it. To enhance the design, I have added an avatar and integrated the animation with it. If you are interested in how I created the avatar, you can check out the complete avatar code at the end of this post. You are free to use it in your animation or customize it to your liking. Enjoy! 😉

    For now, let’s move forward and create this incredible animation!

    CSS Flipping card animation on hover

    The following HTML and SCSS (Sass) code makes a card flip around. Using the X-axis and Y-axis which are two lines that intersect, helps us determine the position of a point in a two-dimensional area.

    Let’s analyze our code one step at a time:

    HTML structure

    We will begin with the HTML structure. We create a parent container called .flip-wrapper. This container acts as the parent element for our animation. Inside it, we have a child element with the .flip-card class, this is where our animation happens. Next, we divide the child element into two parts: the front side and the back side. On the front side, we’ll add the .avatar-container and place the avatar inside while on the back side, we’ll add the .text-container class and add some text.

    <div class="flip-wrapper">
      <div class="flip-card">
        <div class="avatar-container"></div>
        <div class="text-container">
          <h1>Hello</h1>
          <div><i>How are you today?</i></div>
        </div>
      </div>
    </div>
    HTML

    CSS Basic structure

    In our CSS code snippet, first of all, we set the background of our whole page to pink. 🐷🐷

    Moving on to the .flip-wrapper container, we specify its dimensions, giving it a fixed width and height of 300 pixels. To make a circular appearance, we apply a border-radius of 50%. If you desire, you can maintain the square ⬜ shape. I chose this rounded ⚪ design because it makes it easier for us to observe the effect we’re aiming for. 😉

    Next, we focus on the .flip-card element. We set the position: relative property and then its witdh and height to 100% to ensure it covers the entire available space. We also add a white background-color and a subtle gray shadow effect. To maintain the circular theme, we apply a border-radius of 50% to this container too.

    Finally, we set the position: absolute property in both .avatar-container and .text-container classes. In that way we will be ready to place the content we want on both, the front and the back, sides of our card.

    body {
      background: pink;
    }
    
    .flip-wrapper {
      width: 300px;
      height: 300px;
      border-radius: 50%;
      .flip-card {
        position: relative;
        width: 100%;
        height: 100%;
        background-color: white;
        box-shadow: inset 0 0 15px grey;
        border-radius: 50%;
      }
    }
    
    .avatar-container,
    .text-container {
      position: absolute;
    }
    SCSS

    This is what’s rendered on our screen at the moment.

    Adding the hover effect

    In order for our effect to function as intended we have to work with both the parent and the child element. We begin with the parent element, where we apply the :hover effect and change the cursor to a pointer (you can pick any cursor style you prefer).

    .flip-wrapper {
      ...
      &:hover {
        cursor: pointer;
      }
    }
    SCSS

    Preparing the front side of my flipping card

    I added an avatar on the front side of my flipping card. You can add whatever you want (some text, maybe, or an emoticon ✏️) or you can leave it empty, though it is not really useful for observing the flipping.

    .avatar-container {
      ...
    }
    SCSS

    In the following image, we can see how the front side of our flipping card would be. Nice! Isn’t it? 😃

    Preparing the back side of my flipping card

    Here we prepare our text’s style. We keep the default black color and we centered our text based on the display: flex method.

    .text-container {
      display: flex;
      flex-direction: column;
      align-items: center;
      justify-content: center;
    }
    SCSS

    Below we can see how the back side of our flipping card would be. Cool huh! 😃

    Now we are ready to connect these two parts and finally create our amazing animation.

    Adding the flipping animation at the 2D card

    We are free to create flipping animations on both axis X and Y. Below, I prepared two examples. The first one is for axis-Y while the second one is for axis-X. Let’s break it down and see them analytically. 🧐

    Flipping animation on axis-Y

    In order to achieve our goal we have to combine the following CSS properties.

    1. transform: rotateY(180deg) We begin by setting the transform property, which is responsible for the flipping, inside the hover effect. It is also necessary to add it to the class that represents the back side of our card, in our case the .text-container class, otherwise, our text won’t be rendered on the screen when we hover over the card.
    2. transition: transform 6s & transform-style: preserve-3d We continue by combining these two properties inside the .flip-card class. The first one shows us the exact, time in seconds (s), our effect will take place while the second one makes the children of an element appear as if they are positioned in a 3D space. So this property gives us the impression that the descendants (children) of our element are located within a three-dimensional space.
    3. backface-visibility: hidden We finalize our work with the backface-visibility property that defines whether or not the back side of an element should be visible when facing the user. The back face of an element is a mirror image of the front face being displayed.
    .flip-wrapper {
      ...
      &:hover {
        cursor: pointer;
        .flip-card {
          transform: rotateY(180deg);
        }
      }
      .flip-card {
        ...
        transition: transform 6s;
        transform-style: preserve-3d;
      }
    }
    
    .avatar-container,
    .text-container {
      ...
      backface-visibility: hidden;
    }
    
    .text-container {
      transform: rotateY(180deg);
    }
    SCSS

    Voila!! Here is our amazing flipping 2d card animation for the Y-axis!! 🥳

    Flipping animation on axis-X

    We do as previously but in this case, we set the transform: rotateX as we want our animation to move along the X-axis.

    .flip-wrapper {
      ...
      &:hover {
        cursor: pointer;
        .flip-card {
          transform: rotateX(180deg);
        }
      }
      .flip-card {
        ...
        transition: transform 6s;
        transform-style: preserve-3d;
      }
    }
    
    .avatar-container,
    .text-container {
      ...
      backface-visibility: hidden;
    }
    
    .text-container {
      transform: rotateX(180deg);
    }
    SCSS

    Boom! 🎉 This is our wonderful flipping 2d card animation for the X-axis!!

    Complete avatar code

    Below, I include my HTML and CSS avatar code.

    <div class="avatar-container">
      <div class="hair-back"></div>
      <div class="hair hair--left"></div>
      <div class="hair hair--right"></div>
      <div class="hair-clip hair-clip--left"></div>
      <div class="hair-clip hair-clip--right"></div>
      <div class="ear ear--left"></div>
      <div class="ear ear--right"></div>
      <div class="face">
        <div class="eyebrow1 eyebrow1--left"></div>
        <div class="eyebrow1 eyebrow1--right"></div>
        <div class="eyebrow2 eyebrow2--left"></div>
        <div class="eyebrow2 eyebrow2--right"></div>
        <div class="eye-glasses eye-glasses-left"></div>
        <div class="eye-glasses eye-glasses-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="neck"></div>
      <div class="t-shirt"></div>
      <div class="neckless"></div>
    </div> <!-- end of avatar-container -->
    HTML
    Expand
    $body-color: #ff9aab;
    $container-color: white;
    $skin-color: #eabcb4;
    $primary-color: #2d2a2a;
    $secondary-color: #f1f1f1;
    $eye-color: #17884e;
    $eyeline-color: #5b3a3a;
    $eyelash-color: #6d4646;
    $iris-color: #000;
    $hair-color: #dfc2ae;
    $hair-clip-color1: green;
    $hair-clip-color2: #b3498d;
    $hair-clip-color: linear-gradient($hair-clip-color1, $hair-clip-color2, $hair-clip-color1, $hair-clip-color2, $hair-clip-color1);
    $eye-glasses-color: #a32a80;
    $eyebrow-color: #5b3a3a;
    $nose-color: #646363;
    $lips-color: #cd0b87;
    $t-shirt-color: #0b443c;
    $neckless-color: #0b443c;
    
    * {
      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;
      width: 320px;
      height: 320px;
      border-radius: 50%;
      background-color: $container-color;
      box-shadow: inset 0 0 15px grey;
      overflow: hidden;
      .hair-back {
        position: absolute;
        width: 140px;
        height: 200px;
        border-radius: 44% 44% 20px 20px;
        top: 30px;
        left: 50%;
        transform: translate(-50%);
        background-color: $hair-color;
        filter: drop-shadow(0 0 2px #bc9b83);
        z-index: 2;
        &:before {
          content: "";
          position: absolute;
          width: 0.5px;
          height: 28px;
          background-color: #bc9b83;
          filter: drop-shadow(0 0 4px #69660f);
          top: 0px;
          left: 50%;
          transform: translate(-50%);
        }
        &:after {
          content: "";
          position: absolute;
          width: 100px;
          height: 110px;
          border-radius: 20%;
          background-color: #d8baa4;
          top: 70px;
          left: 50%;
          transform: translate(-50%);
        }
      }
      
      .hair {
          position: absolute;
          width: 40px;
          height: 40px;
          background-color: $hair-color;
          filter: drop-shadow(0 0 2px #bc9b83);
          z-index: 1;
          &--left {
            border-radius: 50% 50% 70% 70%;
            top: 22px;
            left: 80px;
            transform: rotate(-50deg);
          }
          &--right {
            border-radius: 50% 50% 60% 60%;
            top: 22px;
            right: 80px;
            transform: rotate(50deg);
          }
        }
      
      .hair-clip {
        position: absolute;
        width: 28px;
        height: 6px;
        background: $hair-clip-color;
        box-shadow: 0 0 2px #037203;
        border-radius: 20%;
        z-index: 10;
        &--left {
          transform: rotate(-50deg);
          top: 48px;
          left: 98px;
        }
        &--right {
          transform: rotate(50deg);
          top: 48px;
          right: 98px;
        }
      }
    
      .ear {
        position: absolute;
        width: 10px;
        height: 20px;
        background-color: $skin-color;
        filter: drop-shadow(0 0 1px #7e7a1f);
        border-radius: 40%;
        top: 95px;
        z-index: 3;
        &--left {
          left: 104px;
          transform: rotate(-5deg);
          &: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: 104px;
          transform: rotate(5deg);
          &: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;
          }
        }
      } // end of ear
    
      .face {
        position: absolute;
        width: 100px;
        height: 110px;
        border-radius: 100% / 70% 70% 160% 160%;
        background-color: $skin-color;
        top: 54px;
        left: 50%;
        transform: translate(-50%);
        box-shadow: 0 0.5px 2px #b37865;
        z-index: 10;
            
        .eye-glasses {
        position: absolute;
        width: 40px;
        height: 32px;
        border: 3px solid $eye-glasses-color;
        top: 32px;
        z-index: 10;
        &.eye-glasses-left {
          border-radius: 12px 18px 18px 18px;
          left: 5px;
          &:before {
            content: "";
            position: absolute;
            width: 14px;
            height: 3px;
            background-color: $eye-glasses-color;
            top: 10px;
            left: 35px;
          }
          &:after {
            content: "";
            position: absolute;
            width: 6px;
            height: 3px;
            background-color: $eye-glasses-color;
            top: 8px;
            left: -8px;
          }
        }
        &.eye-glasses-right {
          border-radius: 18px 12px 18px 18px;
          right: 5px;
          &:before {
            content: "";
            position: absolute;
            width: 15px;
            height: 3px;
            background-color: $eye-glasses-color;
            top: 6px;
            left: -15px;
          }
          &:after {
            content: "";
            position: absolute;
            width: 6px;
            height: 3px;
            background-color: $eye-glasses-color;
            top: 8px;
            right: -8px;
          }
        }
      }  // end of eye-glasses
    
        .eye {
        position: absolute;
        width: 20px;
        height: 20px;
        top: 38px;
        background-color: $secondary-color;
        border: 2px solid $eyeline-color;
        border-radius: 75% 0%;
        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: 16px;
          box-shadow: -1px 0 2px darken($eyeline-color, 50%);
        }
        &--right {
          right: 16px;
          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 eye-lash
      } // end of eye
         
        .eyebrow1 {
          position: absolute;
          width: 20px;
          height: 3px;
          background-color: $eyebrow-color;
          border-radius: 50%;
          top: 28px;
          &--left {
            transform: rotate(10deg);
            left: 16px;
          }
          &--right {
            transform: rotate(-10deg);
            right: 16px;
          }
        } // end of eyebrow1 //
        .eyebrow2 {
            position: absolute;
            content: "";
            width: 14px;
            height: 2px;
            background-color: $eyebrow-color;
            border-radius: 50%;
            top: 28px;
            &--left {
              transform: rotate(-12deg);
              left: 9px;
            }
            &--right {
              transform: rotate(12deg);
              right: 9px;
            }
          } // end of eyebrow2 //
        
        .nose {
          position: absolute;
          width: 5px;
          height: 2px;
          background-color: $nose-color;
          border-radius: 50%;
          transform: rotate(45deg);
          top: 70px;
          left: 44px;
          &:before {
            content: "";
            position: absolute;
            width: 5px;
            height: 2px;
            background-color: $nose-color;
            border-radius: 50%;
            transform: rotate(90deg);
            top: -6px;         
            left: 6px;
            }
        } // end of nose
    
        .lips {
        position: absolute;
        width: 18px;
        height: 18px;
        border-radius: 90% 0;
        background-color: darken($lips-color, 1%);
        top: 90px;
        left: 50%;
        transform: rotate(45deg) translate(-60%);
        &:before {
          content: "";
          position: absolute;
          width: 0;
          height: 0;
          border-left: 3px solid transparent;
          border-right: 3px solid transparent;
          border-top: 3px solid $skin-color;
          border-radius: 60%;
          transform: rotate(-45deg);
          top: 24%;
          left: 12%;
        }
      }  // end of lips
    } // end of face 
    
      .neck {
        position: absolute;
        width: 34px;
        height: 50px;
        background-color: $skin-color;
        filter: drop-shadow(0 0 2px #865748);
        top: 149px;
        left: 50%;
        transform: translate(-50%);
        z-index: 9;
        &:before {
          content: "";
          position: absolute;
          width: 60px;
          height: 40px;
          background-color: $skin-color;
          border-radius: 50%;
          top: 40px;
          left: 50%;
          transform: translate(-50%);
        }
      } // end of neck
    
      .t-shirt {
        position: absolute;
        width: 166px;
        height: 140px;
        background-color: $t-shirt-color;
        border-radius: 100% / 50% 50% 20% 20%;
        top: 190px;
        left: 50%;
        transform: translate(-50%);
        filter: drop-shadow(0 0 2px);
        z-index: 4;
      } // end of t-shirt
      
      .neckless {
        content: "";
        position: absolute;
        width: 36px;
        height: 10px;
        background-color: $neckless-color;
        border-radius: 2px 2px 0 0;
        z-index: 10;
        top: 183px;
        left: 50%;
        transform: translate(-50%);
      } // end of neckless
    } // end of avatar-container
    SCSS
    Expand
  • How To Effectively Use CSS Transform Scale On Hover

    How To Effectively Use CSS Transform Scale On Hover

    Hey there! Today, I’m gonna teach you how to use CSS transform scale on hover by using the transform: scale property. I’ve already created an avatar in order to make our animation more understandable and fun! 😄 If you’re curious about how I made the avatar, you will find the complete avatar code at the end of my post. You are encouraged to incorporate it into your animation as well 😉 The choice is yours!

    Meanwhile, let’s just dive 🤿 into creating these amazing scale animations!

    Meanwhile, let’s just dive into creating these amazing scale animations!

    HTML structure

    In order to create the scale transformations, first of all, it is necessary to make a container, which I named scale-content. This is the ‘place’ where we will do our CSS manipulations. After that, we move forward with a second container, the avatar-container. I named it that way as I intend to position the avatar inside it. As a matter of choice, 😊 you are able to add the avatar, too. Otherwise, you can continue only with the box. Once we prepare those two containers we are ready to move on.

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

    CSS basic styling

    Next, we do the appropriate settings in order to center our container to the body, using the display: flex CSS property. We have also added the colors, setting body-color and container-color.

    $body-color: #8e7d9e;
    $container-color: #0f0b0f;
    
    * {
      margin: 0;
      padding: 0;
      box-sizing: border-box;
    }
    
    html,
    body {
      height: 100%;
    }
    
    body {
      min-width: 500px;
      display: flex;
      align-items: center;
      justify-content: center;
      background-color: $body-color;
    }
    SCSS

    CSS containers structure

    We begin with position: relative CSS property to the parent container and position: absolute to the child container in order to achieve the desired positioning of elements. Next, we specify the width and height of both containers according to our desired dimensions. We also use the CSS properties we want in order to create our avatar-container with the willing characteristics.

    .scale-content {
      position: relative;
      width: 320px;
      height: 320px;
      .avatar-container {
        position: absolute;
        width: 100%;
        height: 100%;
        background-color: $container-color;
        border: 2px solid black;
        box-shadow: 0 0 10px;
        border-radius: 50%;
        overflow: hidden;
      } /* end of avatar-container */
    } /* end of scale-content */
    SCSS

    Great! Now, take a break and look at the container we made using our earlier code. Feel free to go with it, or you may come up with your own! 😊

    CSS scale transformation structure

    Our containers are ready!! We can continue by doing our manipulations and creating scale transformations.

    We apply the transition: transform CSS property to the parent element, which enables us to achieve smooth changes in property values within a specified duration. As you can see below, I set 4s, and as a result, our transition lasts 4 seconds.

    Next, we set the CSS transform: scale(X, Y) property on the child element in order to resize, increase, or decrease the size of an element in the axes. We have the capability to simultaneously resize both axes with the same or different values or selectively resize either the X-axis or the Y-axis.

    💡 Below there are some examples of scale transformations as a way to understand it better 😃

    transform: scale(X, Y) with the same value on both axes

    • Resizes (increases) with the same value, the size of an element in both axes.
    .scale-content {
      ...
      transition: transform 4s;
      &:hover {
        cursor: pointer;
        transform: scale(1.2);
      }
      .avatar-container {
        ...
      } /* end of avatar-container */
    }  /* end of scale-content */
    CSS
    CSS scale transform:This image shows a scale transformation effect on hover which increase, with the same value, the size of the avatar-container in both axes.
    • Resizes (decreases) with the same value, the size of an element in both axes.
    .scale-content {
      ...
      transition: transform 4s;
      &:hover {
        cursor: pointer;
        transform: scale(0.5);
      }
      .avatar-container {
        ...
      } /* end of avatar-container */
    } /* end of scale-content */
    CSS

    transform: scale(X, Y) with different values on both axes

    • Resizes (increase the width and decrease the height), with different values, the size of an element in both axes.
    .scale-content {
      ...
      transition: transform 4s;
      &:hover {
        cursor: pointer;
        transform: scale(1.4, 0.4);
      }
      .avatar-container {
        ...
      } /* end of avatar-container */
    } /* end of scale-content */
    CSS
    • Resizes (decrease the width and increase the height), with different values, the size of an element in both axes.
    .scale-content {
      ...
      transition: transform 4s;
      &:hover {
        cursor: pointer;
        transform: scale(0.4, 1.4);
      }
      .avatar-container {
        ...
      } /* end of avatar-container */
    } /* end of scale-content */
    CSS

    transform: scale(X) increase or decrease width

    • Resizes (increases) the width of an element (X-axis).
    .scale-content {
      ...
      transition: transform 4s;
      &:hover {
        cursor: pointer;
        transform: scaleX(2);
      }
      .avatar-container {
        ...
      } /* end of avatar-container */
    } /* end of scale-content */
    CSS
    • Resizes (decreases) the width of an element (X-axis).
    .scale-content {
      ...
      transition: transform 4s;
      &:hover {
        cursor: pointer;
        transform: scaleX(0.2);
      }
      .avatar-container {
        ...
      } /* end of avatar-container */
    } /* end of scale-content */
    CSS

    transform: scale(Y) increase or decrease height

    • Resizes (increases) the height of an element (Y-axis).
    .scale-content {
      ...
      transition: transform 4s;
      &:hover {
        cursor: pointer;
        transform: scaleY(2);
      }
      .avatar-container {
        ...
      } /* end of avatar-container */
    } /* end of scale-content */
    CSS
    • Resizes (decreases) the height of an element (Y-axis).
    .scale-content {
      ...
      transition: transform 4s;
      &:hover {
        cursor: pointer;
        transform: scaleY(0.5);
      }
      .avatar-container {
        ...
      } /* end of avatar-container */
    } /* end of scale-content */
    CSS

    Complete avatar code

    Below, I include my HTML and CSS avatar code.

    <section class="avatar-container">
      <div class="hair-back"></div>
      <div class="face">
        <div class="ear ear-left">
          <div class="earing earing-left"></div>
        </div>
        <div class="ear ear-right">
          <div class="earing earing-right"></div>
        </div>
        <div class="eyebrow eyebrown-left"></div>
        <div class="eyebrow eyebrown-right"></div>
        <div class="hair-front"></div>
        <div class="hair-long"></div>
        <div class="hairband">
          <div class="bow-big"></div>
          <div class="bow-small"></div>
        </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>
        <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>
        <div class="eye-glasses eye-glasses-left"></div>
        <div class="eye-glasses eye-glasses-right"></div>
        <div class="nose"></div>
        <div class="lips"></div>
      </div>
      <div class="avatar-body">
        <div class="neck"></div>
        <div class="t-shirt">
          <div class="pocket"></div>
        </div>
        <div class="neckless">
          <div class="perl perl--perl1"></div>
          <div class="perl perl--perl2"></div>
          <div class="perl perl--perl3"></div>
          <div class="perl perl--perl4"></div>
          <div class="perl perl--perl5"></div>
          <div class="perl perl--perl6"></div>
          <div class="perl perl--perl7"></div>
          <div class="perl perl--perl8"></div>
          <div class="perl perl--perl9"></div>
          <div class="perl perl--perl10"></div>
        </div>
      </div>
    </section>
    HTML
    Expand
    $body-color: #8e7d9e;
    $container-color: #0f0b0f;
    $skin-color: #fbd0c3;
    $hair-color: #ec3535;
    $eyebrow-color: #5b3a3a;
    $hairband-color: #091845;
    $bow-big-color: #2d2b78;
    $bow-small-color: #9914d2;
    $eye-base-color: #f1f1f1;
    $eyeline-color: #5b3a3a;
    $eyelash-color: #6d4646;
    $iris-color: #000;
    $eye-glasses-color: #0d2b85;
    $nose-color: #383737;
    $lips-color: #e41202;
    $t-shirt-color: #e6e9ee;
    $button-color: #2d2a2a;
    $perl-color: #8314d2;
    
    * {
      margin: 0;
      padding: 0;
      box-sizing: border-box;
    }
    
    html,
    body {
      height: 100%;
    }
    
    body {
      display: flex;
      align-items: center;
      justify-content: center;
      background-color: $body-color;
    }
    
    .avatar-container {
      position: relative;
      width: 320px;
      height: 320px;
      background-color: $container-color;
      border: 2px solid black;
      box-shadow: 0 0 10px;
      border-radius: 50%;
      overflow: hidden;
      .hair-back {
        position: absolute;
        width: 106px;
        height: 110px;
        border-radius: 50%;
        top: 30px;
        left: 50%;
        transform: translate(-50%);
        background-color: $hair-color;
          &:before {
          content: "";
          position: absolute;
          width: 34px;
          height: 100px;
          border-radius: 60%;
          background-color: $hair-color;
          top: 74px;
          left: -8px;
        }
    } // end of hair-back
      
      .face {
        position: absolute;
        width: 100px;
        height: 110px;
        border-radius: 100% / 70% 70% 140% 140%;
        background-color: $skin-color;
        top: 54px;
        left: 50%;
        transform: translate(-50%);
        box-shadow: 0 0.5px 3px;
        z-index: 2;
        .ear {
        position: absolute;
        width: 12px;
        height: 22px;
        background-color: $skin-color;
        border-radius: 40%;
        top: 40px;
        z-index: 6;
        &.ear-left {
          left: -9px;
          transform: rotate(-6deg);
           &:before {
            content: "";
            position: absolute;
            width: 7px;
            height: 10px;
            background-color: $skin-color;
            border-radius: 40%;
            box-shadow: inset 1px 1px 1px darken($skin-color, 15%);
            top: 3px;
            left: 2px;
          }
        }
        &.ear-right {
          right: -9px;
          transform: rotate(6deg);
          &:before {
            content: "";
            position: absolute;
            width: 7px;
            height: 10px;
            background-color: $skin-color;
            border-radius: 40%;
            box-shadow: inset -1px 1px 1px darken($skin-color, 15%);
            top: 3px;
            right: 2px;
          }
        }
        .earing {
          position: absolute;
          width: 5px;
          height: 5px;
          background-color: $perl-color;
          border: 1px solid black;
          border-radius: 50%;
          z-index: 7;
          top: 15px;
          &.earing-left {
            left: 3px;
          }
          &.earing-right {
            right: 3px;
          }
        } // end of earings
      } // end of ears
        .eyebrow {
          position: absolute;
          width: 34px;
          height: 10px;  
          border: solid 3px $eyebrow-color;
          border-color: $eyebrow-color transparent transparent transparent;
          top: 28px;
          z-index: 3;
          &.eyebrown-left {
            left: 7px;
            border-radius: 50%/5px 10px 0 0;
          }
          &.eyebrown-right {
            right: 7px;
            border-radius: 50%/10px 5px 0 0;
          }
    } // end of eyebrows
        
        .hair-front {
        position: absolute;
        z-index: 10;
        width: 80px;
        height: 36px;
        border-radius:50%;
        top: -7px;
        left: -14px;
        background-color: $hair-color;
        transform: rotate(-50deg);
        z-index: 4;
        &:before {
          content: "";
          position: absolute;
          z-index: 10;
          width: 70px;
          height: 30px;
          border-radius:50%;
          top: 44px;
          right: -23px;
          background-color: $hair-color;
          transform: rotate(-85deg);
        }
    }  // end of hair-front
        
        .hair-long {
          position: absolute;
          width: 60px;
          height: 60px;
          border-radius: 60%;
          box-shadow: 20px 12px 0 0 $hair-color;
          z-index: -1;
          top: 116px;
          left: 10px;
          transform: rotate(122deg);
          &:before {
            content: "";
            position: absolute;
            width: 60px;
            height: 60px;
            border-radius: 60%;
            box-shadow: 20px 12px 0 0 $hair-color;
            z-index: 100;
            top: 58px;
            left: 37px;
            transform: rotate(230deg);
          }
    }  // end of hair-long
    
        .hairband {
          position: absolute;
          width: 100px;
          height: 100px;
          border-radius: 60%;
          box-shadow: 4px 4px 0 0 $hairband-color;
          z-index: 10;
          top: -5px;
          transform: rotate(225deg);
          .bow-big {
            position: absolute;
            width: 10px;
            height: 14px;
            background-color: $bow-big-color;
            border-radius: 50%;
            transform: rotate(90deg);
            top: 40px;
            left: 96px;
            z-index: 10;
            &:before {
              content: "";
              position: absolute;
              width: 0;
              height: 0;
              border-top: 10px solid transparent;
              border-left: 20px solid $bow-big-color;
              border-bottom: 10px solid transparent;
              border-radius: 30%;
              top: -4px;
              left: -10px;
            }
            &:after {
              content: "";
              position: absolute;
              width: 0;
              height: 0;
              border-top: 10px solid transparent;
              border-right: 20px solid $bow-big-color;
              border-bottom: 10px solid transparent;
              border-radius: 30%;
              top: -4px;
              right: -10px;
            }
          }
          .bow-small {
            position: absolute;
            width: 6px;
            height: 10px;
            background-color: $bow-small-color;
            border-radius: 50%;
            transform: rotate(90deg);
            top: 42px;
            left: 98px;
            z-index: 10;
            &:before {
              content: "";
              position: absolute;
              width: 0;
              height: 0;
              border-top: 6px solid transparent;
              border-left: 16px solid $bow-small-color;
              border-bottom: 6px solid transparent;
              border-radius: 30%;
              top: -2px;
              left: -10px;
            }
            &:after {
              content: "";
              position: absolute;
              width: 0;
              height: 0;
              border-top: 6px solid transparent;
              border-right: 16px solid $bow-small-color;
              border-bottom: 6px solid transparent;
              border-radius: 30%;
              top: -2px;
              right: -10px;
            }
          }
    } // end of hairband
        
        .eye {
          position: absolute;
          width: 20px;
          height: 20px;
          top: 38px;
          background-color: $eye-base-color;
          border: 2px solid $eyeline-color;
          border-radius: 75% 0%;
          transform: rotate(45deg);
          &:before {
            content: "";
            position: absolute;
            width: 10px;
            height: 10px;
            top: 50%;
            left: 50%;
            transform: translate(-30%, -70%);
            background: radial-gradient(circle, purple, blue);
            box-shadow: inset 0 0 3px;
            border-radius: 50%;
          }
          &.eye-left {
            left: 15px;
            box-shadow: -1px 1px 2px darken($eyeline-color, 10%);
          }
          &.eye-right {
            right: 15px;
            box-shadow: 1px -1px 2px darken($eyeline-color, 10%);
          }
          &:after {
            content: "";
            position: absolute;
            width: 4px;
            height: 4px;
            top: 50%;
            left: 50%;
            transform: translate(20%, -120%);
            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: 2px;
            }
            &--left1 {
             top: 2px;
             left: -2px;
            }
            &--left2 {
             top: 6px;
             left: -4px;
            }
            &--left3 {
             top: 10px;
             left: -5px;
            }
            &--left4 {
             top: 14px;
             left: -5px;
            }
            &--right {
              top: -1px;
              right: 15px;
            }
            &--right1 {
              top: -4px;
              right: 11px;
            }
            &--right2 {
              top: -7px;
              right: 7px;
            }
            &--right3 {
              top: -8px;
              right: 3px;
            }
            &--right4 {
              top: -8px;
              right: -1px;
            }
          }
    } // end of eye
    
        .eye-glasses {
          position: absolute;
          width: 40px;
          height: 34px;
          border: 4px solid $eye-glasses-color;
          top: 31px;
          z-index: 5;
          border-radius: 50%;
          &.eye-glasses-left {
            left: 5px;
            &:before {
              content: "";
              position: absolute;
              width: 14px;
              height: 4px;
              background-color: $eye-glasses-color;
              top: 8px;
              left: 35px;
            }
            &:after {
              content: "";
              position: absolute;
              width: 9px;
              height: 3px;
              background-color: $eye-glasses-color;
              top: 8px;
              left: -9px;
            }
          }
          &.eye-glasses-right {
            right: 5px;
            &:after {
              content: "";
              position: absolute;
              width: 9px;
              height: 3px;
              background-color: $eye-glasses-color;
              top: 8px;
              right: -10px;
            }
          }
        } // end of eyeglasses
    
        .nose {
          position: absolute;
          width: 8px;
          height: 8px;
          border-radius: 50%;
          box-shadow: 1px 1px 0 0 $nose-color;
          top: 62px;
          left: 46px;
          transform: rotate(45deg);
            &:before {
            content: "";
            position: absolute;
            width: 10px;
            height: 10px;
            border-radius: 60%;
            box-shadow: 1px 1px 0 0 $nose-color;
            top: 1px;
            left: -2px;
            transform: rotate(75deg);
          }
          &:after {
            content: "";
            position: absolute;
            width: 10px;
            height: 10px;
            border-radius: 50%;
            box-shadow: 1px 1px 0 0 $nose-color;
            top: -3px;
            right: -3px;
            transform: rotate(-65deg);
          }
    } // end of nose
    
        .lips {
          position: absolute;
          width: 18px;
          height: 18px;
          border-radius: 90% 0;
          background-color: darken($lips-color, 1%);
          top: 90px;
          left: 50%;
          transform: rotate(45deg) translate(-60%);
          &:before {
            content: "";
            position: absolute;
            width: 0;
            height: 0;
            border-left: 3px solid transparent;
            border-right: 3px solid transparent;
            border-top: 3px solid $skin-color;
            border-radius: 60%;
            transform: rotate(-45deg);
            top: 24%;
            left: 12%;
          }
    } // end of lips
      } // end of face
      
      .avatar-body {
        .neck {
          position: absolute;
          width: 36px;
          height: 50px;
          background-color: $skin-color;
          top: 150px;
          left: 50%;
          transform: translate(-50%);
          z-index: 1;
          &:before {
            content: "";
            position: absolute;
            width: 40px;
            height: 34px;
            border-radius: 2px 2px 50% 50%;
            background-color: $t-shirt-color;
            top: 26px;
            left: -2px;
          }
        } // end of neck
        .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%);
          .pocket {
            position: absolute;
            width: 32px;
            height: 40px;
            background-color: $t-shirt-color;
            box-shadow: 0 0 2px;
            border: 2px solid black;
            border-radius: 20%;
            top: 50px;
            left: 100px;
            &:before {
              content: "";
              position: absolute;
              width: 30px;
              height: 12px;
              background-color: $t-shirt-color;
              box-shadow: 0 0 2px;
              border: 2px solid black;
              border-radius: 20%;
              top: -4px;
              left: -3px;
            }
            &:after {
              content: "";
              position: absolute;
              width: 5px;
              height: 5px;
              background-color: $button-color;
              box-shadow: 0 0 2px;
              border: 2px solid black;
              border-radius: 50%;
              top: 0px;
              left: 9px;
            }
          } // end of pocket
        } // end of t-shirt
        .neckless {
          position: absolute;
          width: 50px;
          height: 50px;
          border-radius: 50%;
          box-shadow: 2px 2px 0 transparent;
          top: 167px;
          left: 50%;
          transform: translate(-50%) rotate(45deg);
          z-index: 10;
          .perl {
            position: absolute;
            width: 10px;
            height: 10px;
            border-radius: 50%;
            border: 2px solid black;
            background-color: $perl-color;
            &--perl1 {
              top: 4px;
              left: 42px;
            }
            &--perl2 {
              top: 42px;
              left: 4px;
            }
            &--perl3 {
              top: 12px;
              left: 44px;
            }
            &--perl4 {
              top: 44px;
              left: 12px;
            }
            &--perl5 {
              top: 20px;
              left: 45px;
            }
            &--perl6 {
              top: 45px;
              left: 20px;
            }
            &--perl7 {
              top: 28px;
              left: 45px;
            }
            &--perl8 {
              top: 45px;
              left: 28px;
            }
            &--perl9 {
              top: 36px;
              left: 42px;
            }
            &--perl10 {
              top: 42px;
              left: 35px;
            }
          } // end of perl
        } // end of neckless
      } // end of body
    } // end of avatar-container
    SCSS
    Expand
    This image shows our avatar.