1<!DOCTYPE html>
2<html lang="en">
3<head>
4<meta charset="UTF-8" />
5<meta name="viewport" content="width=device-width, initial-scale=1.0" />
6<title>Dot Split Animation</title>
7<style>
8 :root{
9 --bg:#f8f4e6;
10 --dot:#a7375d;
11 --size:50px;
12 --small:27px;
13 --gap:40px;
14 --dur:1.35s;
15 }
16
17 html,body{
18 margin:0;
19 width:100%;
20 height:100%;
21 overflow:hidden;
22 background:var(--bg);
23 }
24
25 body{
26 display:grid;
27 place-items:center;
28 }
29
30 .loader{
31 position:relative;
32 width:140px;
33 height:80px;
34 }
35
36 .dot{
37 position:absolute;
38 top:50%;
39 left:50%;
40 border-radius:50%;
41 background:var(--dot);
42 transform:translate(-50%,-50%);
43 will-change: transform, width, height, opacity;
44 }
45
46 .single{
47 width:var(--size);
48 height:var(--size);
49 animation:singlePulse var(--dur) ease-in-out infinite;
50 }
51
52 .pair{
53 width:var(--small);
54 height:var(--small);
55 opacity:0;
56 }
57
58 .left{
59 animation:leftDot var(--dur) ease-in-out infinite;
60 }
61
62 .right{
63 animation:rightDot var(--dur) ease-in-out infinite;
64 }
65
66 @keyframes singlePulse{
67 0%, 24%, 76%, 100%{
68 width:var(--size);
69 height:var(--size);
70 opacity:1;
71 transform:translate(-50%,-50%) scale(1);
72 }
73 32%, 68%{
74 width:calc(var(--size) * 0.82);
75 height:calc(var(--size) * 0.82);
76 opacity:0;
77 transform:translate(-50%,-50%) scale(0.9);
78 }
79 }
80
81 @keyframes leftDot{
82 0%, 24%, 76%, 100%{
83 opacity:0;
84 transform:translate(-50%,-50%) translateX(0) scale(0.85);
85 }
86 32%{
87 opacity:1;
88 transform:translate(-50%,-50%) translateX(calc(var(--gap) * -0.65)) scale(1);
89 }
90 50%{
91 opacity:1;
92 transform:translate(-50%,-50%) translateX(calc(var(--gap) * -1)) scale(1);
93 }
94 68%{
95 opacity:1;
96 transform:translate(-50%,-50%) translateX(calc(var(--gap) * -0.65)) scale(1);
97 }
98 }
99
100 @keyframes rightDot{
101 0%, 24%, 76%, 100%{
102 opacity:0;
103 transform:translate(-50%,-50%) translateX(0) scale(0.85);
104 }
105 32%{
106 opacity:1;
107 transform:translate(-50%,-50%) translateX(calc(var(--gap) * 0.65)) scale(1);
108 }
109 50%{
110 opacity:1;
111 transform:translate(-50%,-50%) translateX(var(--gap)) scale(1);
112 }
113 68%{
114 opacity:1;
115 transform:translate(-50%,-50%) translateX(calc(var(--gap) * 0.65)) scale(1);
116 }
117 }
118</style>
119</head>
120<body>
121 <div class="loader" aria-label="animated splitting dot">
122 <div class="dot single"></div>
123 <div class="dot pair left"></div>
124 <div class="dot pair right"></div>
125 </div>
126</body>
127</html>