In this post, we will dive into actual implementation of Skeleton Loader step by step. The first post of the series is focused on providing an overview of Skeleton Loader, its purpose, usage and points to keep in mind while designing. If you are still uncertain regarding concept, refer Skeleton Loader: An overview, purpose, usage and design Steps Involved: Design a Background Design a Gradient Animate Gradient Display loader only for empty placeholders Complete Implementation Design a Background We have to keep background for the placeholders where content has not been loaded yet. These visual placeholders should be in light gray or neutral colors. 🅐 🅑 < > div < = > span class "skeleton-loader-background" </ > span </ > div { : ; : ; : block; : lightgray; 🅒 } .skeleton-loader-background width 100% height 15px display background Create a section for loading content. A. Create inside that section for adding hooks to a text. Assigned a class “skeleton-loader-background” for styling background. B. <span> Specify with light-gray color. C. background Image: Skeleton Loader Background Design a Gradient 🅐 < > div < = > span class "skeleton-loader-gradient" </ > span </ > div { : ; : ; : block; : ( 🅑 to right, rgba(255, 255, 255, 0), (255, 255, 255, 0.5) , (255, 255, 255, 0) ), lightgray; : repeat-y; 🅒 : ; 🅓 : ; 🅔 } .skeleton-loader-gradient width 100% height 15px display background linear-gradient rgba 50% rgba 80% background-repeat background-size 50px 200px background-position 0 0 Create a section, span for adding hooks and assign a class “skeleton-loader-gradient” for styling gradient. A. Specify direction and pattern. Here, gradient will get applied from left to right. It consists of white color with 0% opacity (transparent) in the starting, 50% opacity in the middle and 80% opacity at the end. Also, background contains two values separated by commas. According to specifications, values gets stacked vertically. The first value remains on top and other goes down from there. B. linear-gradient Repeat gradient vertically i.e. on Y-axis. C. Specify size of the gradient i.e. width and height. D. Set the position of the gradient to start i.e. 0 0. E. Image: Skeleton Loader Gradient Animate Gradient Motion plays an important role in applications. It can help to make interfaces more expressive and intuitive. For Skeleton loader, we have to animate a gradient from left most end towards right. When thinking of motion, we should aim for an appropriate duration. If it is slow it makes users feel they are waiting more than they actually are. If it is quite fast it gives bad perception. We have to keep right balance of speed, direction and easing to give performant experience. We have a light-gray background and gradient designed. Next, we have to animate gradient from left to right, repeatedly with an ease. 🅐 < > div < = > span class "skeleton-loader" </ > span </ > div { : ; : ; : block; : ( 🅑 to right, rgba(255, 255, 255, 0), (255, 255, 255, 0.5) , (255, 255, 255, 0) ), lightgray; : repeat-y; : ; : ; : shine infinite; 🅒 } @ shine { 🅓 { : , ; } } .skeleton-loader width 100% height 15px display background linear-gradient rgba 50% rgba 80% background-repeat background-size 50px 500px background-position 0 0 animation 1s keyframes to background-position 100% 0 /* move highlight to right */ 0 0 Create a section, span for adding hooks and assign a class “skeleton-loader” for styling gradient. A. Specify gradient and light-gray background for loader. B. Specify name, duration and iteration count. C. animation Using rule, specify how animation will gradually change from the current style to the new style at certain times. Here, it will change background position from left to right (0 to 100%). D. keyframes Image: Skeleton Loader Animation Show loader only for empty placeholders { 🅐 : ; : ; : block; : ( to right, rgba(255, 255, 255, 0), (255, 255, 255, 0.5) , (255, 255, 255, 0) ), lightgray; : repeat-y; : ; : ; : shine infinite; } .skeleton-loader :empty width 100% height 15px display background linear-gradient rgba 50% rgba 80% background-repeat background-size 50px 500px background-position 0 0 animation 1s The selector matches every element that has no child elements or text nodes. Here, it will display skeleton loader only when content has not been loaded. A. :empty Complete Implementation < > html < > head < = /> meta charset "UTF-8" < = = /> meta name "viewport" content "width=device-width, initial-scale=1.0" < = = = /> link rel "stylesheet" type "text/css" href "loader.css" < = = = /> link rel "stylesheet" type "text/css" href "tile.css" < = > script src "script.js" </ > script </ > head < > body < = > div class "prod--wrapper" < = > div class "prod--col prod--img" < = = /> img id "productImage" class "prod--img-graphic skeleton-loader" </ > div < = > div class "prod--col prod--details" < = > div class "prod--row prod--name" < = = > span id "productName" class "prod--name-text skeleton-loader" </ > span </ > div < = > div class "prod--row prod--description" < = = > span id "productId" class "prod--description-text skeleton-loader" </ > span </ > div </ > div </ > div </ > body </ > html { : ; : ; : block; : ( to right, rgba(255, 255, 255, 0), (255, 255, 255, 0.5) , (255, 255, 255, 0) ), lightgray; : repeat-y; : ; : ; : shine infinite; } @ shine { { : ; } } .skeleton-loader :empty width 100% height 15px display background linear-gradient rgba 50% rgba 80% background-repeat background-size 50px 500px background-position 0 0 animation 1s keyframes to background-position 100% 0 { : flex; : ; : ; : solid ; : ; : ; : , ; } { : flex; : row; } { : flex; : column; } { : ; : ; } { : ; : ; : top; : ; } { : ; : ; } { : ; : ; : block; : ; } { : auto; } { : bold; : ; : ; : ; : ; } { : ; } { : ; : ; : ; } .prod--wrapper display width 95% margin 32px 0 border 1px #b6b6b6 border-radius 6px padding 22px 10px font-family "Calibri" "Arial" .prod--wrapper .prod--row display flex-direction .prod--wrapper .prod--col display flex-direction .prod--wrapper .prod--img width 20% margin 0 15px .prod--wrapper .prod--img .prod--img-graphic max-height 100% height 100% vertical-align max-width 100% .prod--wrapper .prod--details width 90% margin-left 17px .prod--wrapper .prod--details .prod--name margin-bottom 3px width 85% display max-width 100% .prod--wrapper .prod--details .prod--name .prod--name-para margin 0 .prod--wrapper .prod--details .prod--name .prod--name-text font-weight font-size 16px line-height 23px color #002877 height 40px .prod--wrapper .prod--details .prod--description margin-bottom 13px .prod--wrapper .prod--details .prod--description .prod--description-text font-size 13px line-height 18px color #666666 .addEventListener( , { eleProductImage = .getElementById( ); eleProductName = .getElementById( ); eleProductId = .getElementById( ); { xhr = XMLHttpRequest(); xhr.open( , , ); xhr.onload = { res = .parse(xhr.responseText); eleProductImage.src = res.image; eleProductName.innerHTML = res.title; eleProductId.innerHTML = res.description; }; xhr.send(); } getProductDetails(); }); document "DOMContentLoaded" ( ) function var document "productImage" var document "productName" var document "productId" ( ) function getProductDetails var new "GET" "https://fakestoreapi.com/products/1" true ( ) function var JSON Here, we have designed product tile containing image, product name and product description. We are fetching content through live API using JavaScript. will get fired on load of HTML DOM. We will perform JavaScript operations on receipt of this event. A. DOMContentLoaded B. Access elements through . HTML DOM API C. Fetch data from live API. Here, we are using dummy API for fetching product details ( ). https://fakestoreapi.com/products/1 D. Populate HTML elements with appropriate content. Image: Skeleton Loader Visual You can also check my video depicting the designing of the Skeleton Loader as per the steps mentioned above. Bottom Line While working with animations, it looks demanding at first sight. However, implementing them shouldn’t be that tough compared to the experience it provides. Also, you can reuse the CSS anywhere in your code. For , head over to . working example repository If you enjoyed reading this post, do appreciate and give a follow. Thank you for your time.