30 CSS Keyframe Animations07 / 30
CSS Wave Animation
Ocean waves with animated boat, gradient wave, liquid-level vial and expanding pulse rings using CSS clip-path and sinusoidal keyframe paths.
Published
This is a full-page demo — interact inside the frame above, or open it in the playground for the full-screen experience.
The code
<div class="kf-07">
<div class="kf-07__cell" style="width:100%;max-width:700px">
<div class="kf-07__ocean">
<div class="kf-07__wave kf-07__wave--1"></div>
<div class="kf-07__wave kf-07__wave--2"></div>
<div class="kf-07__wave kf-07__wave--3"></div>
<div class="kf-07__ship">⛵</div>
</div>
<span class="kf-07__label">Ocean Waves</span>
</div>
<div class="kf-07__cell" style="width:100%;max-width:600px">
<div class="kf-07__grad-wave">
<div class="kf-07__grad-text">FLOWING</div>
</div>
<span class="kf-07__label">Gradient Wave</span>
</div>
<div class="kf-07__row">
<div class="kf-07__cell">
<div class="kf-07__vial"><div class="kf-07__liquid"></div><div class="kf-07__pct">65%</div></div>
<span class="kf-07__label">Liquid Level</span>
</div>
<div class="kf-07__cell">
<div class="kf-07__rings">
<div class="kf-07__ring"></div><div class="kf-07__ring"></div>
<div class="kf-07__ring"></div><div class="kf-07__ring"></div>
</div>
<span class="kf-07__label">Pulse Rings</span>
</div>
</div>
</div><div class="kf-07">
<div class="kf-07__cell" style="width:100%;max-width:700px">
<div class="kf-07__ocean">
<div class="kf-07__wave kf-07__wave--1"></div>
<div class="kf-07__wave kf-07__wave--2"></div>
<div class="kf-07__wave kf-07__wave--3"></div>
<div class="kf-07__ship">⛵</div>
</div>
<span class="kf-07__label">Ocean Waves</span>
</div>
<div class="kf-07__cell" style="width:100%;max-width:600px">
<div class="kf-07__grad-wave">
<div class="kf-07__grad-text">FLOWING</div>
</div>
<span class="kf-07__label">Gradient Wave</span>
</div>
<div class="kf-07__row">
<div class="kf-07__cell">
<div class="kf-07__vial"><div class="kf-07__liquid"></div><div class="kf-07__pct">65%</div></div>
<span class="kf-07__label">Liquid Level</span>
</div>
<div class="kf-07__cell">
<div class="kf-07__rings">
<div class="kf-07__ring"></div><div class="kf-07__ring"></div>
<div class="kf-07__ring"></div><div class="kf-07__ring"></div>
</div>
<span class="kf-07__label">Pulse Rings</span>
</div>
</div>
</div>@import url('https://fonts.googleapis.com/css2?family=DM+Sans:wght@400;700&display=swap');
.kf-07,
.kf-07 *,
.kf-07 *::before,
.kf-07 *::after {
box-sizing: border-box;
margin: 0;
padding: 0;
}
.kf-07 ::selection {
background: #0077b6;
color: #fff;
}
.kf-07 {
--bg: #03045e;
--deep: #0077b6;
--mid: #00b4d8;
--light: #90e0ef;
--foam: #caf0f8;
--white: #fff;
--gold: #ffd60a;
font-family: 'DM Sans',sans-serif;
background: linear-gradient(180deg,#03045e 0%,#0096c7 60%,#00b4d8 100%);
min-height: 100vh;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
padding: 40px 20px;
gap: 56px;
overflow: hidden;
position: relative;
color: var(--white);
}
/* 1 — Ocean waves stacked */
.kf-07__ocean {
position: relative;
width: 100%;
max-width: 700px;
height: 180px;
background: linear-gradient(180deg,rgba(0,150,199,.3),rgba(0,77,110,.6));
border-radius: 12px;
overflow: hidden;
}
.kf-07__wave {
position: absolute;
bottom: 0;
left: 0;
right: 0;
background: var(--mid);
border-radius: 100% 100% 0 0/40px;
}
.kf-07__wave--1 {
height: 60px;
background: rgba(0,180,216,.7);
animation: kf-07-wave1 4s ease-in-out infinite;
}
.kf-07__wave--2 {
height: 50px;
background: rgba(144,224,239,.5);
animation: kf-07-wave2 5s ease-in-out infinite .3s;
}
.kf-07__wave--3 {
height: 40px;
background: rgba(202,240,248,.4);
animation: kf-07-wave1 6s ease-in-out infinite .6s;
}
@keyframes kf-07-wave1 {
0%,
100% {
transform: translateX(-50px) scaleY(1);
}
50% {
transform: translateX(30px) scaleY(1.1);
}
}
@keyframes kf-07-wave2 {
0%,
100% {
transform: translateX(40px) scaleY(1);
}
50% {
transform: translateX(-30px) scaleY(.9);
}
}
.kf-07__ship {
position: absolute;
top: 16px;
left: 0;
font-size: 28px;
animation: kf-07-sail 8s linear infinite;
}
@keyframes kf-07-sail {
from {
left: -40px;
}
to {
left: calc(100% + 40px);
}
}
/* 2 — Sine wave line */
.kf-07__sine {
width: 100%;
max-width: 600px;
height: 80px;
position: relative;
overflow: hidden;
}
.kf-07__sine-line {
position: absolute;
bottom: 0;
left: -100%;
width: 300%;
height: 100%;
background: none;
border-top: 3px solid var(--mid);
border-radius: 100%;
animation: kf-07-sine 3s linear infinite;
}
.kf-07__sine-line--2 {
border-top-color: var(--light);
animation-delay: .5s;
opacity: .6;
}
.kf-07__sine-line--3 {
border-top-color: var(--foam);
animation-delay: 1s;
opacity: .3;
}
@keyframes kf-07-sine {
to {
transform: translateX(33.33%);
}
}
/* 3 — Animated gradient wave bg */
.kf-07__grad-wave {
width: 100%;
max-width: 700px;
height: 120px;
position: relative;
border-radius: 12px;
overflow: hidden;
}
.kf-07__grad-wave::before {
content: '';
position: absolute;
inset: 0;
background: linear-gradient(90deg,#03045e,var(--deep),var(--mid),var(--light),var(--mid),var(--deep),#03045e);
background-size: 400% 100%;
animation: kf-07-gradwave 4s linear infinite;
}
@keyframes kf-07-gradwave {
to {
background-position: -400% 0;
}
}
.kf-07__grad-text {
position: relative;
z-index: 1;
height: 100%;
display: flex;
align-items: center;
justify-content: center;
font-size: 2rem;
font-weight: 700;
letter-spacing: .1em;
}
/* 4 — Liquid level */
.kf-07__vial {
width: 90px;
height: 180px;
border: 3px solid var(--foam);
border-radius: 45px;
position: relative;
overflow: hidden;
background: rgba(0,0,0,.2);
}
.kf-07__liquid {
position: absolute;
bottom: 0;
left: 0;
right: 0;
height: 65%;
background: linear-gradient(180deg,var(--mid),var(--deep));
}
.kf-07__liquid::before {
content: '';
position: absolute;
top: -18px;
left: -50%;
width: 200%;
height: 36px;
background: var(--mid);
border-radius: 50%;
animation: kf-07-liq 2.5s ease-in-out infinite;
}
@keyframes kf-07-liq {
0%,
100% {
transform: translateX(-10px) rotateZ(-2deg);
}
50% {
transform: translateX(10px) rotateZ(2deg);
}
}
.kf-07__pct {
position: absolute;
inset: 0;
display: grid;
place-items: center;
font-weight: 700;
font-size: 1.1rem;
color: var(--white);
}
/* 5 — Pulse ring wave */
.kf-07__rings {
position: relative;
width: 120px;
height: 120px;
display: grid;
place-items: center;
}
.kf-07__ring {
position: absolute;
border-radius: 50%;
border: 2px solid var(--mid);
animation: kf-07-ring 2.4s ease-out infinite;
}
.kf-07__ring:nth-child(1) {
inset: 40px;
animation-delay: 0s;
}
.kf-07__ring:nth-child(2) {
inset: 30px;
animation-delay: .4s;
border-color: var(--light);
}
.kf-07__ring:nth-child(3) {
inset: 20px;
animation-delay: .8s;
border-color: var(--foam);
}
.kf-07__ring:nth-child(4) {
inset: 10px;
animation-delay: 1.2s;
}
@keyframes kf-07-ring {
0% {
transform: scale(1);
opacity: 1;
}
100% {
transform: scale(3);
opacity: 0;
}
}
.kf-07__row {
display: flex;
gap: 40px;
flex-wrap: wrap;
justify-content: center;
align-items: center;
width: 100%;
max-width: 700px;
}
.kf-07__cell {
display: flex;
flex-direction: column;
align-items: center;
gap: 14px;
}
.kf-07__label {
font-size: 11px;
letter-spacing: .18em;
text-transform: uppercase;
color: rgba(202,240,248,.6);
}
@media (prefers-reduced-motion: reduce) {
.kf-07 * {
animation: none!important;
}
}@import url('https://fonts.googleapis.com/css2?family=DM+Sans:wght@400;700&display=swap');
.kf-07,
.kf-07 *,
.kf-07 *::before,
.kf-07 *::after {
box-sizing: border-box;
margin: 0;
padding: 0;
}
.kf-07 ::selection {
background: #0077b6;
color: #fff;
}
.kf-07 {
--bg: #03045e;
--deep: #0077b6;
--mid: #00b4d8;
--light: #90e0ef;
--foam: #caf0f8;
--white: #fff;
--gold: #ffd60a;
font-family: 'DM Sans',sans-serif;
background: linear-gradient(180deg,#03045e 0%,#0096c7 60%,#00b4d8 100%);
min-height: 100vh;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
padding: 40px 20px;
gap: 56px;
overflow: hidden;
position: relative;
color: var(--white);
}
/* 1 — Ocean waves stacked */
.kf-07__ocean {
position: relative;
width: 100%;
max-width: 700px;
height: 180px;
background: linear-gradient(180deg,rgba(0,150,199,.3),rgba(0,77,110,.6));
border-radius: 12px;
overflow: hidden;
}
.kf-07__wave {
position: absolute;
bottom: 0;
left: 0;
right: 0;
background: var(--mid);
border-radius: 100% 100% 0 0/40px;
}
.kf-07__wave--1 {
height: 60px;
background: rgba(0,180,216,.7);
animation: kf-07-wave1 4s ease-in-out infinite;
}
.kf-07__wave--2 {
height: 50px;
background: rgba(144,224,239,.5);
animation: kf-07-wave2 5s ease-in-out infinite .3s;
}
.kf-07__wave--3 {
height: 40px;
background: rgba(202,240,248,.4);
animation: kf-07-wave1 6s ease-in-out infinite .6s;
}
@keyframes kf-07-wave1 {
0%,
100% {
transform: translateX(-50px) scaleY(1);
}
50% {
transform: translateX(30px) scaleY(1.1);
}
}
@keyframes kf-07-wave2 {
0%,
100% {
transform: translateX(40px) scaleY(1);
}
50% {
transform: translateX(-30px) scaleY(.9);
}
}
.kf-07__ship {
position: absolute;
top: 16px;
left: 0;
font-size: 28px;
animation: kf-07-sail 8s linear infinite;
}
@keyframes kf-07-sail {
from {
left: -40px;
}
to {
left: calc(100% + 40px);
}
}
/* 2 — Sine wave line */
.kf-07__sine {
width: 100%;
max-width: 600px;
height: 80px;
position: relative;
overflow: hidden;
}
.kf-07__sine-line {
position: absolute;
bottom: 0;
left: -100%;
width: 300%;
height: 100%;
background: none;
border-top: 3px solid var(--mid);
border-radius: 100%;
animation: kf-07-sine 3s linear infinite;
}
.kf-07__sine-line--2 {
border-top-color: var(--light);
animation-delay: .5s;
opacity: .6;
}
.kf-07__sine-line--3 {
border-top-color: var(--foam);
animation-delay: 1s;
opacity: .3;
}
@keyframes kf-07-sine {
to {
transform: translateX(33.33%);
}
}
/* 3 — Animated gradient wave bg */
.kf-07__grad-wave {
width: 100%;
max-width: 700px;
height: 120px;
position: relative;
border-radius: 12px;
overflow: hidden;
}
.kf-07__grad-wave::before {
content: '';
position: absolute;
inset: 0;
background: linear-gradient(90deg,#03045e,var(--deep),var(--mid),var(--light),var(--mid),var(--deep),#03045e);
background-size: 400% 100%;
animation: kf-07-gradwave 4s linear infinite;
}
@keyframes kf-07-gradwave {
to {
background-position: -400% 0;
}
}
.kf-07__grad-text {
position: relative;
z-index: 1;
height: 100%;
display: flex;
align-items: center;
justify-content: center;
font-size: 2rem;
font-weight: 700;
letter-spacing: .1em;
}
/* 4 — Liquid level */
.kf-07__vial {
width: 90px;
height: 180px;
border: 3px solid var(--foam);
border-radius: 45px;
position: relative;
overflow: hidden;
background: rgba(0,0,0,.2);
}
.kf-07__liquid {
position: absolute;
bottom: 0;
left: 0;
right: 0;
height: 65%;
background: linear-gradient(180deg,var(--mid),var(--deep));
}
.kf-07__liquid::before {
content: '';
position: absolute;
top: -18px;
left: -50%;
width: 200%;
height: 36px;
background: var(--mid);
border-radius: 50%;
animation: kf-07-liq 2.5s ease-in-out infinite;
}
@keyframes kf-07-liq {
0%,
100% {
transform: translateX(-10px) rotateZ(-2deg);
}
50% {
transform: translateX(10px) rotateZ(2deg);
}
}
.kf-07__pct {
position: absolute;
inset: 0;
display: grid;
place-items: center;
font-weight: 700;
font-size: 1.1rem;
color: var(--white);
}
/* 5 — Pulse ring wave */
.kf-07__rings {
position: relative;
width: 120px;
height: 120px;
display: grid;
place-items: center;
}
.kf-07__ring {
position: absolute;
border-radius: 50%;
border: 2px solid var(--mid);
animation: kf-07-ring 2.4s ease-out infinite;
}
.kf-07__ring:nth-child(1) {
inset: 40px;
animation-delay: 0s;
}
.kf-07__ring:nth-child(2) {
inset: 30px;
animation-delay: .4s;
border-color: var(--light);
}
.kf-07__ring:nth-child(3) {
inset: 20px;
animation-delay: .8s;
border-color: var(--foam);
}
.kf-07__ring:nth-child(4) {
inset: 10px;
animation-delay: 1.2s;
}
@keyframes kf-07-ring {
0% {
transform: scale(1);
opacity: 1;
}
100% {
transform: scale(3);
opacity: 0;
}
}
.kf-07__row {
display: flex;
gap: 40px;
flex-wrap: wrap;
justify-content: center;
align-items: center;
width: 100%;
max-width: 700px;
}
.kf-07__cell {
display: flex;
flex-direction: column;
align-items: center;
gap: 14px;
}
.kf-07__label {
font-size: 11px;
letter-spacing: .18em;
text-transform: uppercase;
color: rgba(202,240,248,.6);
}
@media (prefers-reduced-motion: reduce) {
.kf-07 * {
animation: none!important;
}
}Here's a working CSS Keyframe Animation from CodeFronts. Use it as-is or adapt to your framework. All classes are scoped under a unique prefix so the code won't collide with your existing styles. MIT licensed.
Demo: CSS Wave Animation
Source: https://codefronts.com/motion/css-keyframe-animations/css-wave-animation/
Ocean waves with animated boat, gradient wave, liquid-level vial and expanding pulse rings using CSS clip-path and sinusoidal keyframe paths.
## HTML
```html
<div class="kf-07">
<div class="kf-07__cell" style="width:100%;max-width:700px">
<div class="kf-07__ocean">
<div class="kf-07__wave kf-07__wave--1"></div>
<div class="kf-07__wave kf-07__wave--2"></div>
<div class="kf-07__wave kf-07__wave--3"></div>
<div class="kf-07__ship">⛵</div>
</div>
<span class="kf-07__label">Ocean Waves</span>
</div>
<div class="kf-07__cell" style="width:100%;max-width:600px">
<div class="kf-07__grad-wave">
<div class="kf-07__grad-text">FLOWING</div>
</div>
<span class="kf-07__label">Gradient Wave</span>
</div>
<div class="kf-07__row">
<div class="kf-07__cell">
<div class="kf-07__vial"><div class="kf-07__liquid"></div><div class="kf-07__pct">65%</div></div>
<span class="kf-07__label">Liquid Level</span>
</div>
<div class="kf-07__cell">
<div class="kf-07__rings">
<div class="kf-07__ring"></div><div class="kf-07__ring"></div>
<div class="kf-07__ring"></div><div class="kf-07__ring"></div>
</div>
<span class="kf-07__label">Pulse Rings</span>
</div>
</div>
</div>
```
## CSS
```css
@import url('https://fonts.googleapis.com/css2?family=DM+Sans:wght@400;700&display=swap');
.kf-07,
.kf-07 *,
.kf-07 *::before,
.kf-07 *::after {
box-sizing: border-box;
margin: 0;
padding: 0;
}
.kf-07 ::selection {
background: #0077b6;
color: #fff;
}
.kf-07 {
--bg: #03045e;
--deep: #0077b6;
--mid: #00b4d8;
--light: #90e0ef;
--foam: #caf0f8;
--white: #fff;
--gold: #ffd60a;
font-family: 'DM Sans',sans-serif;
background: linear-gradient(180deg,#03045e 0%,#0096c7 60%,#00b4d8 100%);
min-height: 100vh;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
padding: 40px 20px;
gap: 56px;
overflow: hidden;
position: relative;
color: var(--white);
}
/* 1 — Ocean waves stacked */
.kf-07__ocean {
position: relative;
width: 100%;
max-width: 700px;
height: 180px;
background: linear-gradient(180deg,rgba(0,150,199,.3),rgba(0,77,110,.6));
border-radius: 12px;
overflow: hidden;
}
.kf-07__wave {
position: absolute;
bottom: 0;
left: 0;
right: 0;
background: var(--mid);
border-radius: 100% 100% 0 0/40px;
}
.kf-07__wave--1 {
height: 60px;
background: rgba(0,180,216,.7);
animation: kf-07-wave1 4s ease-in-out infinite;
}
.kf-07__wave--2 {
height: 50px;
background: rgba(144,224,239,.5);
animation: kf-07-wave2 5s ease-in-out infinite .3s;
}
.kf-07__wave--3 {
height: 40px;
background: rgba(202,240,248,.4);
animation: kf-07-wave1 6s ease-in-out infinite .6s;
}
@keyframes kf-07-wave1 {
0%,
100% {
transform: translateX(-50px) scaleY(1);
}
50% {
transform: translateX(30px) scaleY(1.1);
}
}
@keyframes kf-07-wave2 {
0%,
100% {
transform: translateX(40px) scaleY(1);
}
50% {
transform: translateX(-30px) scaleY(.9);
}
}
.kf-07__ship {
position: absolute;
top: 16px;
left: 0;
font-size: 28px;
animation: kf-07-sail 8s linear infinite;
}
@keyframes kf-07-sail {
from {
left: -40px;
}
to {
left: calc(100% + 40px);
}
}
/* 2 — Sine wave line */
.kf-07__sine {
width: 100%;
max-width: 600px;
height: 80px;
position: relative;
overflow: hidden;
}
.kf-07__sine-line {
position: absolute;
bottom: 0;
left: -100%;
width: 300%;
height: 100%;
background: none;
border-top: 3px solid var(--mid);
border-radius: 100%;
animation: kf-07-sine 3s linear infinite;
}
.kf-07__sine-line--2 {
border-top-color: var(--light);
animation-delay: .5s;
opacity: .6;
}
.kf-07__sine-line--3 {
border-top-color: var(--foam);
animation-delay: 1s;
opacity: .3;
}
@keyframes kf-07-sine {
to {
transform: translateX(33.33%);
}
}
/* 3 — Animated gradient wave bg */
.kf-07__grad-wave {
width: 100%;
max-width: 700px;
height: 120px;
position: relative;
border-radius: 12px;
overflow: hidden;
}
.kf-07__grad-wave::before {
content: '';
position: absolute;
inset: 0;
background: linear-gradient(90deg,#03045e,var(--deep),var(--mid),var(--light),var(--mid),var(--deep),#03045e);
background-size: 400% 100%;
animation: kf-07-gradwave 4s linear infinite;
}
@keyframes kf-07-gradwave {
to {
background-position: -400% 0;
}
}
.kf-07__grad-text {
position: relative;
z-index: 1;
height: 100%;
display: flex;
align-items: center;
justify-content: center;
font-size: 2rem;
font-weight: 700;
letter-spacing: .1em;
}
/* 4 — Liquid level */
.kf-07__vial {
width: 90px;
height: 180px;
border: 3px solid var(--foam);
border-radius: 45px;
position: relative;
overflow: hidden;
background: rgba(0,0,0,.2);
}
.kf-07__liquid {
position: absolute;
bottom: 0;
left: 0;
right: 0;
height: 65%;
background: linear-gradient(180deg,var(--mid),var(--deep));
}
.kf-07__liquid::before {
content: '';
position: absolute;
top: -18px;
left: -50%;
width: 200%;
height: 36px;
background: var(--mid);
border-radius: 50%;
animation: kf-07-liq 2.5s ease-in-out infinite;
}
@keyframes kf-07-liq {
0%,
100% {
transform: translateX(-10px) rotateZ(-2deg);
}
50% {
transform: translateX(10px) rotateZ(2deg);
}
}
.kf-07__pct {
position: absolute;
inset: 0;
display: grid;
place-items: center;
font-weight: 700;
font-size: 1.1rem;
color: var(--white);
}
/* 5 — Pulse ring wave */
.kf-07__rings {
position: relative;
width: 120px;
height: 120px;
display: grid;
place-items: center;
}
.kf-07__ring {
position: absolute;
border-radius: 50%;
border: 2px solid var(--mid);
animation: kf-07-ring 2.4s ease-out infinite;
}
.kf-07__ring:nth-child(1) {
inset: 40px;
animation-delay: 0s;
}
.kf-07__ring:nth-child(2) {
inset: 30px;
animation-delay: .4s;
border-color: var(--light);
}
.kf-07__ring:nth-child(3) {
inset: 20px;
animation-delay: .8s;
border-color: var(--foam);
}
.kf-07__ring:nth-child(4) {
inset: 10px;
animation-delay: 1.2s;
}
@keyframes kf-07-ring {
0% {
transform: scale(1);
opacity: 1;
}
100% {
transform: scale(3);
opacity: 0;
}
}
.kf-07__row {
display: flex;
gap: 40px;
flex-wrap: wrap;
justify-content: center;
align-items: center;
width: 100%;
max-width: 700px;
}
.kf-07__cell {
display: flex;
flex-direction: column;
align-items: center;
gap: 14px;
}
.kf-07__label {
font-size: 11px;
letter-spacing: .18em;
text-transform: uppercase;
color: rgba(202,240,248,.6);
}
@media (prefers-reduced-motion: reduce) {
.kf-07 * {
animation: none!important;
}
}
```Here's a working CSS Keyframe Animation from CodeFronts. Use it as-is or adapt to your framework. All classes are scoped under a unique prefix so the code won't collide with your existing styles. MIT licensed.
Demo: CSS Wave Animation
Source: https://codefronts.com/motion/css-keyframe-animations/css-wave-animation/
Ocean waves with animated boat, gradient wave, liquid-level vial and expanding pulse rings using CSS clip-path and sinusoidal keyframe paths.
## HTML
```html
<div class="kf-07">
<div class="kf-07__cell" style="width:100%;max-width:700px">
<div class="kf-07__ocean">
<div class="kf-07__wave kf-07__wave--1"></div>
<div class="kf-07__wave kf-07__wave--2"></div>
<div class="kf-07__wave kf-07__wave--3"></div>
<div class="kf-07__ship">⛵</div>
</div>
<span class="kf-07__label">Ocean Waves</span>
</div>
<div class="kf-07__cell" style="width:100%;max-width:600px">
<div class="kf-07__grad-wave">
<div class="kf-07__grad-text">FLOWING</div>
</div>
<span class="kf-07__label">Gradient Wave</span>
</div>
<div class="kf-07__row">
<div class="kf-07__cell">
<div class="kf-07__vial"><div class="kf-07__liquid"></div><div class="kf-07__pct">65%</div></div>
<span class="kf-07__label">Liquid Level</span>
</div>
<div class="kf-07__cell">
<div class="kf-07__rings">
<div class="kf-07__ring"></div><div class="kf-07__ring"></div>
<div class="kf-07__ring"></div><div class="kf-07__ring"></div>
</div>
<span class="kf-07__label">Pulse Rings</span>
</div>
</div>
</div>
```
## CSS
```css
@import url('https://fonts.googleapis.com/css2?family=DM+Sans:wght@400;700&display=swap');
.kf-07,
.kf-07 *,
.kf-07 *::before,
.kf-07 *::after {
box-sizing: border-box;
margin: 0;
padding: 0;
}
.kf-07 ::selection {
background: #0077b6;
color: #fff;
}
.kf-07 {
--bg: #03045e;
--deep: #0077b6;
--mid: #00b4d8;
--light: #90e0ef;
--foam: #caf0f8;
--white: #fff;
--gold: #ffd60a;
font-family: 'DM Sans',sans-serif;
background: linear-gradient(180deg,#03045e 0%,#0096c7 60%,#00b4d8 100%);
min-height: 100vh;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
padding: 40px 20px;
gap: 56px;
overflow: hidden;
position: relative;
color: var(--white);
}
/* 1 — Ocean waves stacked */
.kf-07__ocean {
position: relative;
width: 100%;
max-width: 700px;
height: 180px;
background: linear-gradient(180deg,rgba(0,150,199,.3),rgba(0,77,110,.6));
border-radius: 12px;
overflow: hidden;
}
.kf-07__wave {
position: absolute;
bottom: 0;
left: 0;
right: 0;
background: var(--mid);
border-radius: 100% 100% 0 0/40px;
}
.kf-07__wave--1 {
height: 60px;
background: rgba(0,180,216,.7);
animation: kf-07-wave1 4s ease-in-out infinite;
}
.kf-07__wave--2 {
height: 50px;
background: rgba(144,224,239,.5);
animation: kf-07-wave2 5s ease-in-out infinite .3s;
}
.kf-07__wave--3 {
height: 40px;
background: rgba(202,240,248,.4);
animation: kf-07-wave1 6s ease-in-out infinite .6s;
}
@keyframes kf-07-wave1 {
0%,
100% {
transform: translateX(-50px) scaleY(1);
}
50% {
transform: translateX(30px) scaleY(1.1);
}
}
@keyframes kf-07-wave2 {
0%,
100% {
transform: translateX(40px) scaleY(1);
}
50% {
transform: translateX(-30px) scaleY(.9);
}
}
.kf-07__ship {
position: absolute;
top: 16px;
left: 0;
font-size: 28px;
animation: kf-07-sail 8s linear infinite;
}
@keyframes kf-07-sail {
from {
left: -40px;
}
to {
left: calc(100% + 40px);
}
}
/* 2 — Sine wave line */
.kf-07__sine {
width: 100%;
max-width: 600px;
height: 80px;
position: relative;
overflow: hidden;
}
.kf-07__sine-line {
position: absolute;
bottom: 0;
left: -100%;
width: 300%;
height: 100%;
background: none;
border-top: 3px solid var(--mid);
border-radius: 100%;
animation: kf-07-sine 3s linear infinite;
}
.kf-07__sine-line--2 {
border-top-color: var(--light);
animation-delay: .5s;
opacity: .6;
}
.kf-07__sine-line--3 {
border-top-color: var(--foam);
animation-delay: 1s;
opacity: .3;
}
@keyframes kf-07-sine {
to {
transform: translateX(33.33%);
}
}
/* 3 — Animated gradient wave bg */
.kf-07__grad-wave {
width: 100%;
max-width: 700px;
height: 120px;
position: relative;
border-radius: 12px;
overflow: hidden;
}
.kf-07__grad-wave::before {
content: '';
position: absolute;
inset: 0;
background: linear-gradient(90deg,#03045e,var(--deep),var(--mid),var(--light),var(--mid),var(--deep),#03045e);
background-size: 400% 100%;
animation: kf-07-gradwave 4s linear infinite;
}
@keyframes kf-07-gradwave {
to {
background-position: -400% 0;
}
}
.kf-07__grad-text {
position: relative;
z-index: 1;
height: 100%;
display: flex;
align-items: center;
justify-content: center;
font-size: 2rem;
font-weight: 700;
letter-spacing: .1em;
}
/* 4 — Liquid level */
.kf-07__vial {
width: 90px;
height: 180px;
border: 3px solid var(--foam);
border-radius: 45px;
position: relative;
overflow: hidden;
background: rgba(0,0,0,.2);
}
.kf-07__liquid {
position: absolute;
bottom: 0;
left: 0;
right: 0;
height: 65%;
background: linear-gradient(180deg,var(--mid),var(--deep));
}
.kf-07__liquid::before {
content: '';
position: absolute;
top: -18px;
left: -50%;
width: 200%;
height: 36px;
background: var(--mid);
border-radius: 50%;
animation: kf-07-liq 2.5s ease-in-out infinite;
}
@keyframes kf-07-liq {
0%,
100% {
transform: translateX(-10px) rotateZ(-2deg);
}
50% {
transform: translateX(10px) rotateZ(2deg);
}
}
.kf-07__pct {
position: absolute;
inset: 0;
display: grid;
place-items: center;
font-weight: 700;
font-size: 1.1rem;
color: var(--white);
}
/* 5 — Pulse ring wave */
.kf-07__rings {
position: relative;
width: 120px;
height: 120px;
display: grid;
place-items: center;
}
.kf-07__ring {
position: absolute;
border-radius: 50%;
border: 2px solid var(--mid);
animation: kf-07-ring 2.4s ease-out infinite;
}
.kf-07__ring:nth-child(1) {
inset: 40px;
animation-delay: 0s;
}
.kf-07__ring:nth-child(2) {
inset: 30px;
animation-delay: .4s;
border-color: var(--light);
}
.kf-07__ring:nth-child(3) {
inset: 20px;
animation-delay: .8s;
border-color: var(--foam);
}
.kf-07__ring:nth-child(4) {
inset: 10px;
animation-delay: 1.2s;
}
@keyframes kf-07-ring {
0% {
transform: scale(1);
opacity: 1;
}
100% {
transform: scale(3);
opacity: 0;
}
}
.kf-07__row {
display: flex;
gap: 40px;
flex-wrap: wrap;
justify-content: center;
align-items: center;
width: 100%;
max-width: 700px;
}
.kf-07__cell {
display: flex;
flex-direction: column;
align-items: center;
gap: 14px;
}
.kf-07__label {
font-size: 11px;
letter-spacing: .18em;
text-transform: uppercase;
color: rgba(202,240,248,.6);
}
@media (prefers-reduced-motion: reduce) {
.kf-07 * {
animation: none!important;
}
}
```How this works
Ocean waves use absolutely-positioned strips with border-radius: 100% 100% 0 0 / 40px — the slash radius produces a flattened arch shape. Three layers animate translateX back-and-forth with scaleY(1 → 1.1) at staggered durations of 4s, 5s and 6s, so the surface never repeats predictably. A ship emoji sails across via a separate kf-07-sail that moves left: -40px → calc(100% + 40px) linearly over 8s.
The liquid vial fills with a semi-transparent block whose ::before is a wide ellipse positioned above the fill line — sliding it left-right via translateX(-10px ↔ 10px) with a tiny rotateZ sells the sloshing surface. The animated gradient wave uses a 7-stop horizontal linear-gradient at background-size: 400% 100% and animates background-position: 0 → -400% for a continuous flow.
Make it yours
- Tune wave height by editing
height: 60pxon.kf-07__wave--1down to40pxfor calmer seas. - Change liquid level by editing
height: 65%on.kf-07__liquid— match the displayed percentage text. - Recolour via
--deep,--mid,--light,--foamcustom properties on the.kf-07root. - Slow the gradient flow by changing
kf-07-gradwavefrom4sto10sfor a slow-tide effect. - Increase ripple count by adding more
.kf-07__ringchildren and extending thenth-childinset + delay pairs.
Gotchas — read before shipping
background-positionanimation on the gradient wave keeps a paint-on-every-frame, but tiles to GPU when you addwill-change: background-position.- The ship's
leftanimation hits layout; on mobile, swap totransform: translateX()with a fixed parent width. - Wave layers stacking on top of each other can create moire patterns at certain blend modes — keep the layers as solid translucent fills, not blends.
Browser support
| Chrome | Safari | Firefox | Edge |
|---|---|---|---|
| 60+ | 12+ | 60+ | 60+ |