CSSHTMLJavaScript

iPhone 14 Dynamic Island Using HTML CSS JavaScript

iPhone 14 Dynamic Island Using HTML CSS JavaScript. Using HTML, CSS & JavaScript we can create so many interesting thing.

Today in this article, we will see how to create iPhone 14 Dynamic Island animation using html css JavaScript. we will use HTML for structure, CSS for styling and JavaScript for animation.

Source Code:

HTML(Pug):

input#deep-purple(name="theme", type="radio", checked)
input#gold(name="theme", type="radio")
input#space-black(name="theme", type="radio")
input#silver(name="theme", type="radio")
input#random(name="theme", type="radio")
input#zoom(name="zoom", type="checkbox")

.scene
	.pallette
		label.swatch(tabIndex="0", for="deep-purple")
		label.swatch(tabIndex="0", for="gold")
		label.swatch(tabIndex="0", for="space-black")
		label.swatch(tabIndex="0", for="silver")
		label.swatch(tabIndex="0", for="random")
			.icon
			.tooltip CMD + click to save

	.zoom-con
		label.swatch(tabIndex="0", for="zoom")

	.phone-con
		.phone
			.buttons
				.left
					.button
					.button
					.button
				.right
					.button
			.camera
			.screen-container
				.bg
					.deep-purple
						.section
							.glow
						.section
							.glow
					.gold
						.section
							.glow
						.section
							.glow
					.space-black
						.section
							.glow
						.section
							.glow
					.silver
						.section
							.glow
						.section
							.glow
					.random.canvas
						.shapes
							.shape
							.shape
							.shape
							.shape
							.shape
							.shape
				.notch-container(tabIndex="0")
					.notch
						.content
							.left
								.tile
								.text
							.right
							.bar
								.duration
				.notch-blur
				.screen
					.app
						.weather
					.app
					.app
					.app
					.app
					.app
					.app
					.app
					.app
					.app

——————————
📂 Important Links:
——————————
>> Learn Graphics Design & Make A Successful Profession.
>> Canva Makes Graphics Design Easy.
>> Start Freelancing Today & Earn Money.
>> Make Video Editing As Your Profession.

CSS(SCSS):

@import url("https://fonts.googleapis.com/css2?family=Inter:wght@400&display=swap");

:root {
	--size: max(5px, 1vmin);
	--height: 80em;
	--pad: 1.25em;
	--border-radius: 6.666em;
	--gutter: calc(var(--pad) * 2);
	--scene-pad: 5vmin;
	--bg-blur: 0.333em;

	--button-width: 0.333em;

	--notch-height: 3.33em;
	--notch-width: 33.3%;
	--notch-radius: calc(var(--border-radius) - calc(var(--pad) * 2));
	--notch-duration: 0.333s;

	--ease: cubic-bezier(0.666, 0, 0.4, 1);
	--ease-spring: cubic-bezier(0.666, 0, 0.4, 1.2);
	--ease-out: cubic-bezier(0.15, 0, 0.333, 1);

	--border-width: 0.4em;

	--deep-purple: 284;
	--gold: 22.5;
	--space-black: 215;
	--silver: 254;

	--c-h: var(--deep-purple);
	--c-s: 100%;
	--c-l: 50%;
}

// Squircle effect
@function round-off() {
	@return url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' version='1.1'><defs><filter id='round'><feGaussianBlur in='SourceGraphic' stdDeviation='5' result='blur' /><feColorMatrix in='blur' mode='matrix' values='1 0 0 0 0  0 1 0 0 0  0 0 1 0 0  0 0 0 19 -9' result='goo'/><feComposite in='SourceGraphic' in2='goo' operator='atop'/></filter></defs></svg>#round");
}

// Smoother gradients
@function scrim-gradient(
	$startColor,
	$direction: "to bottom",
	$from: 0,
	$to: 100,
	$type: linear,
	$reverse: false,
	$debug: false
) {
	$scrimCoordinates: (
		0: 1,
		19: 0.738,
		34: 0.541,
		47: 0.382,
		56.5: 0.278,
		65: 0.194,
		73: 0.126,
		80.2: 0.075,
		86.1: 0.042,
		91: 0.021,
		95.2: 0.008,
		98.2: 0.002,
		100: 0
	);

	$hsl: "";

	@if type-of($startColor) == "list" {
		$hsl: $startColor;
	} @else {
		$hue: hue($startColor);
		$saturation: saturation($startColor);
		$lightness: lightness($startColor);
		$hsl: #{$hue}, #{$saturation}, #{$lightness};
	}

	$stops: ();

	@each $colorStop, $alpha in $scrimCoordinates {
		$stop: unquote("hsla(#{$hsl}, #{if($reverse, 1 - $alpha, $alpha)})")
			$from +
			($colorStop/($to/(100 - $from))) *
			1%;
		$stops: append($stops, $stop, comma);
	}

	@if $debug {
		@return "$startColor: #{$startColor},$direction: #{$direction}, $from: #{$from}, $to: #{$to}, $type: #{$type}, $reverse: #{$reverse}";
	} @else {
		@return #{$type}-gradient(unquote($direction), $stops);
	}
}

@keyframes appear {
	to {
		transform: scale3d(1, 1, 1);
		opacity: 1;
	}
}

body {
	background: darken(blue, 48);
}

.scene {
	display: flex;
	flex-wrap: wrap;
	gap: 3em 0;
	align-items: center;
	align-content: center;
	justify-content: center;
	min-height: 100vh;
	font-family: Inter;
	font-size: var(--size);
	padding: var(--scene-pad);
	box-sizing: border-box;
}

.phone-con {
	flex-basis: 100%;
	display: flex;
	justify-content: center;
}

.phone {
	position: relative;
	z-index: 1;

	aspect-ratio: 37/76;
	background: black;
	height: var(--height);
	border-radius: var(--border-radius);
	box-shadow: 0 0 0.1em 0.25em hsl(var(--c-h), 20%, 25%),
		0 0 0 var(--border-width) hsl(var(--c-h), 30%, 85%);
	box-sizing: border-box;

	opacity: 0;
	transform: scale3d(1.1, 1.1, 1);
	animation: appear 1s var(--ease-out) forwards;
	webkit-backface-visibility: hidden;

	&:before {
		content: "";
		position: absolute;
		top: var(--border-radius);
		right: calc(var(--border-width) * -1);
		bottom: var(--border-radius);
		left: calc(var(--border-width) * -1);
		border: 0.5em solid hsl(var(--c-h), 20%, 30%);
		border-left-width: 0;
		border-right-width: 0;
	}
}

.buttons {
	position: absolute;
	inset: calc(var(--border-width) * -1);
	pointer-events: none;

	.left,
	.right {
		position: absolute;
		width: var(--button-width);
		display: flex;
		flex-direction: column;
		align-items: stretch;
		gap: 1.5em;
	}

	.left {
		right: 100%;
		top: calc(var(--border-radius) * 2);

		.button {
			&:nth-child(1) {
				height: 3em;
				margin-bottom: 0.5em;
			}
		}
	}

	.right {
		left: 100%;
		transform: scale3d(-1, 1, 1);
		top: calc(var(--border-radius) * 3);

		.button {
			height: 9.5em;
		}
	}

	.button {
		background: hsl(var(--c-h), 20%, 95%);
		height: 6em;
		box-shadow: inset -0.15em 0 0.1em black,
			inset 0 0 0.1em hsl(var(--c-h), 30%, 90%),
			inset 0 0.2em 0.1em hsl(var(--c-h), 30%, 90%),
			inset 0 -0.2em 0.1em hsl(var(--c-h), 30%, 90%),
			inset -0.1em 0.333em 0.1em rgba(black, 0.5),
			inset -0.1em -0.333em 0.1em rgba(black, 0.5);

		border-top-left-radius: 0.2em;
		border-bottom-left-radius: 0.2em;
	}
}

.screen-container {
	position: absolute;
	// overflow: hidden;
	inset: 0;

	border-radius: var(--border-radius);
	border: var(--pad) solid black;

	display: flex;
	flex-direction: column;
	align-items: center;
	gap: calc(var(--pad) * 2);

	// Bottom thingy
	&:before {
		content: "";
		position: absolute;
		z-index: 2;
		background: white;
		width: 36.6%;
		bottom: calc(var(--pad) * 0.75);
		height: calc(var(--pad) * 0.5);
		border-radius: calc(var(--pad) * 0.25);
		filter: drop-shadow(0 0.1em 0.25em rgba(black, 0.1));
	}
}

.bg {
	position: absolute;
	inset: 0;
	background: black;
	border-radius: calc(var(--border-radius) - var(--pad));
	overflow: hidden;
	// filter: round-off();
	transform: translateZ(0);

	> * {
		position: absolute;
		inset: 0;
		display: flex;
		flex-direction: column;
		opacity: 0;
		transition: opacity 1s var(--ease-out) 0.5s;
		background: black;
	}

	.section {
		--g-h: var(--c-h);
		--g-s: var(--c-s);
		--g-l: var(--c-l);

		flex-grow: 1;
		position: relative;
		overflow: hidden;

		border-radius: calc(var(--border-radius) - var(--pad));
		border-bottom-left-radius: 20em;
		border-bottom-right-radius: 20em;

		&:before {
			content: "";
			position: absolute;
			inset: 0;
			border-radius: inherit;

			background: scrim-gradient(
					black,
					"120% 110% at 50% 92.5%",
					$from: 33.3,
					$type: radial
				),
				scrim-gradient(
					(calc(var(--g-h) - var(--g-hue-adjust-2, var(--g-hue-adjust))), 100%, 50%),
					"100% 66.6% at 110% var(--g-hue-adjust-2-y, 100%)",
					$from: 33.3,
					$type: radial
				),
				scrim-gradient(
					(calc(var(--g-h) - var(--g-hue-adjust-2, var(--g-hue-adjust))), 100%, 50%),
					"100% 66.6% at -10% var(--g-hue-adjust-2-y, 100%)",
					$from: 33.3,
					$type: radial
				),
				scrim-gradient(
					(calc(var(--g-h) + 33.3), 100%, var(--g-lightness, 82.5%)),
					"150% 100% at 50% 80%",
					$from: 35,
					$type: radial,
					$reverse: true
				);

			background-color: hsl(var(--g-h), var(--g-s), var(--g-l));

			transform: scale3d(1.1, 1.25, 1);
			transform-origin: bottom;
			transition: transform 1s var(--ease-out) 0.5s;
		}

		&:after {
			content: "";
			position: absolute;
			inset: 0;
			border: var(--border-width) solid rgba(white, 0.8);
			border-radius: inherit;
			filter: blur(0.05em);
			// backdrop-filter: blur(0.75em);

			mask-image: radial-gradient(
				100% 100% at 50% 70%,
				black 30%,
				transparent 50%
			);
			transform: translatez(2px);
		}

		.glow {
			position: absolute;
			inset: 0;
			border-radius: inherit;
			mix-blend-mode: overlay;
			z-index: 1;
			background: radial-gradient(
				80% 150% at 50% 100%,
				hsl(var(--g-h), 100%, var(--g-l)),
				transparent 70%
			);
		}
	}

	// Bottom bg section
	.section:last-of-type {
		--g-h: calc(var(--c-h) - var(--g-hue-adjust, 0));
		--g-l: calc(var(--c-l) + 40%);
		--g-lightness: 95%;

		transform: scale3d(1, -1, 1) translateZ(1px);
	}
}

.notch-container {
	position: absolute;
	z-index: 3;
	top: var(--pad);
	right: var(--pad);
	left: var(--pad);
	display: flex;
	justify-content: center;

	height: 100%;
	max-height: calc(var(--notch-radius) * 2);

	pointer-events: none;
	outline: none;

	transition: var(--notch-duration) var(--ease);
	transition-property: max-height, max-width, filter, transform;
	will-change: max-width, max-height, filter;

	// Stop transitions when resizing screen or zooming
	.is-resizing &,
	.is-resizing & * {
		transition: none;
	}

	&:hover,
	&:focus-within {
		--shadow-opacity: 0.5;
		transition-timing-function: var(--ease-spring);

		.content {
			--content-padding: 2em;

			.text {
				opacity: 1;
			}
		}

		.notch {
			max-width: 100%;
			max-height: 100%;
			// transition: max-width 0.3s ease-in-out, max-height 0.2s ease-in-out 0.1s;
			pointer-events: all;
			transform: scale3d(1, 1, 1);
		}

		~ .notch-blur {
			opacity: 1;
			max-height: calc(var(--notch-radius) * 3.333 + var(--pad));
		}
	}

	&:focus-within {
		max-height: calc(var(--notch-radius) * 3);

		--bar-height: 1em;
		--bar-opacity: 1;

		.left,
		.right {
			max-height: calc(100% - var(--bar-height, 0%) - var(--content-gap));
		}

		~ .notch-blur {
			max-height: calc(var(--notch-radius) * 5);
			opacity: 1;
		}
	}
}

// Blurred drop-shadow
.notch-blur {
	position: absolute;
	z-index: 2;
	top: calc(var(--pad) - 3px);
	right: calc(var(--pad) - 3px);
	left: calc(var(--pad) - 3px);
	height: 100%;
	max-height: calc(var(--notch-radius) * 1.5);
	backdrop-filter: blur(0.2em);
	mask-image: scrim-gradient(black, $from: 60);
	opacity: 0;

	border-radius: calc(var(--border-radius) - var(--pad));

	transition: var(--notch-duration) var(--ease);
	transition-property: max-height, max-width, opacity, transform;
	will-change: max-width, max-height;
}

.notch {
	position: relative;
	border-radius: var(--notch-radius);
	pointer-events: all;
	overflow: hidden;
	color: white;

	// max-height: var(--notch-height);
	// max-width: var(--notch-width);

	display: flex;

	cursor: pointer;

	width: 100%;
	// max-width: var(--notch-width);

	transition: inherit;
	transition-property: inherit;
	will-change: inherit;

	filter: drop-shadow(0 1em 2em hsla(0 0% 0% / var(--shadow-opacity, 0)));

	transform: scale3d(0.375, 0.4, 1);
	transform-origin: top;

	&:before {
		content: "";
		position: absolute;
		inset: 0;
		background: black;
		filter: round-off();
		border-radius: inherit;
	}
}

.content {
	--content-padding: 1.75em;
	--duration-height: 0.5em;
	--content-gap: 1em;

	width: 100%;
	display: flex;
	flex-wrap: wrap;
	align-items: stretch;
	justify-content: stretch;
	padding: var(--content-padding);
	gap: var(--content-gap);
	font-size: 125%;

	transition-property: padding;
	will-change: padding;

	position: relative;

	.left,
	.right {
		height: 100%;
		max-height: calc(100% - var(--bar-height, 0%));

		display: flex;
		align-items: center;
		gap: 1em;
	}

	&,
	.left,
	.right,
	.bar,
	.text {
		transition: var(--notch-duration) var(--ease-out);
	}

	.left,
	.right,
	.bar {
		transition-property: max-height, opacity;
		will-change: max-height;
	}

	.left {
		flex-grow: 2;
		// background: red;
	}

	.text {
		display: flex;
		flex-direction: column;
		gap: 0.333em;
		transition-property: opacity;

		opacity: var(--bar-opacity, 0);

		&:before {
			content: "The Move";
			order: 1;
			text-transform: uppercase;
		}

		&:after {
			order: 2;
			content: "Space Rangers";
			opacity: 0.5;
		}
	}

	.right {
		flex-grow: 1;
		// background: blue;
	}

	.tile {
		background: #{desaturate(darken(blue, 10), 25%)};
		height: 100%;
		aspect-ratio: 1;
		border-radius: 33.3%;
		position: relative;

		&:before {
			content: "";
			position: absolute;
			inset: 0;
			border-radius: 50%;

			background: radial-gradient(
					50% 50% at 55% 40%,
					desaturate(darken(blue, 20), 25%),
					#cd1385 75%,
					transparent
				)
				center / 133.3% 133.3%;
			background-color: yellow;
			filter: blur(0.05em);
		}
	}

	.bar {
		display: flex;
		align-items: center;
		gap: 1em;
		flex-basis: 100%;
		height: 100%;
		max-height: var(--bar-height, 0%);
		color: rgba(white, 0.5);

		opacity: var(--bar-opacity, 0);

		.duration {
			position: relative;
			height: var(--duration-height);
			background: rgba(white, 0.25);
			border-radius: calc(var(--duration-height) * 0.5);
			overflow: hidden;
			flex-grow: 1;

			&:before {
				content: "";
				height: 100%;
				background: white;
				width: 25%;
				position: absolute;
			}
		}

		&:before {
			content: "1:20";
		}

		&:after {
			content: "-1:48";
		}
	}
}

.camera {
	display: flex;
	justify-content: center;
	align-items: center;
	height: var(--notch-height);
	aspect-ratio: 1/1;
	border-radius: 50%;
	pointer-events: none;

	position: absolute;
	z-index: 4;
	top: calc(var(--pad) * 2);
	right: calc(50% - calc(var(--notch-width) * 0.5));
	margin-right: calc(var(--pad) * 0.333);

	&:before {
		content: "";
		height: 33.3%;
		aspect-ratio: 1;
		border-radius: inherit;
		box-shadow: inset 0 0 0.25em #4c4da3;
		background: radial-gradient(#6667ac, transparent 50%) no-repeat 33.3% 10% /
				75% 50%,
			radial-gradient(darken(#6667ac, 15), transparent 50%) no-repeat 60% 85% / 50%
				50%;
		background-color: #080928;
	}
}

.screen {
	// opacity: 0;
	display: flex;
	flex-wrap: wrap;
	align-content: flex-start;
	flex-grow: 1;
	gap: var(--gutter);

	box-sizing: border-box;
	width: 100%;
	position: relative;
	overflow: hidden;
	z-index: 1;

	padding: var(--gutter);
	padding-top: calc(var(--gutter) * 3);
	border-radius: calc(var(--border-radius) - var(--pad));

	transition: opacity 1s var(--ease-out) 0.25s;
}

.app {
	--col: 4;

	aspect-ratio: 1;
	border-radius: 20%;
	flex-basis: 15%;
	flex-grow: 1;

	display: flex;
	flex-direction: column;
	justify-content: space-between;
	gap: 2%;

	padding: 5%;
	box-sizing: border-box;
	font-size: 1.5em;

	--scale: 1.5;
	--duration: 0.8s;

	transform: scale3d(var(--scale), var(--scale), 1);
	animation: appear var(--duration) var(--ease-out) forwards;

	&:nth-child(1),
	&:nth-child(2) {
		flex-basis: 40%;
		border-radius: 15%;
		background: linear-gradient(
				190deg,
				var(--app-bg-s1, white) 33.3%,
				var(--app-bg-s2, var(--app-bg-s1, white))
			)
			top / 100% 125%;
	}

	&:not(:nth-child(1)):not(:nth-child(2)) {
		&:before {
			content: "";
			background: linear-gradient(
					190deg,
					var(--app-bg-s1, white),
					var(--app-bg-s2, var(--app-bg-s1, white))
				)
				top / 100% 125%;
			border-radius: inherit;
			position: absolute;
			inset: 0;
			filter: round-off();
		}
	}

	&:nth-child(1),
	&:nth-child(2),
	&:nth-child(3),
	&:nth-child(6),
	&:nth-child(7),
	&:nth-child(10) {
		--scale: 1.75;
		--duration: 1s;
	}

	&:nth-child(1) {
		--app-bg-s1: #{darken(#6490d2, 10)};
		--app-bg-s2: #6490d2;

		color: white;
		transform-origin: 125% 200%;

		&:after {
			content: "Sunny";
		}

		.weather {
			display: flex;
			flex-direction: column;
			gap: 2%;

			&:before {
				content: "Oakland";
			}

			&:after {
				font-size: 225%;
				content: "80°";
			}
		}
	}

	&:nth-child(2) {
		--app-bg-s1: #cbe2ae;
		--app-bg-s2: #{lighten(#cbe2ae, 15)};

		transform-origin: -25% 200%;

		&:before {
			content: "";
			align-self: flex-end;
			width: 40%;
			background: #f8d7a2;
			border: var(--border-width) solid white;
			aspect-ratio: 1;
			border-radius: 50%;
		}

		&:after {
			content: "Hudson Ave";
			font-weight: 500;
			margin-top: auto;
		}
	}

	&:nth-child(3) {
		--app-bg-s1: #a7f88f;
		--app-bg-s2: #41c144;

		transform-origin: 175% 200%;
	}

	&:nth-child(4) {
		transform-origin: 75% 230%;
	}

	&:nth-child(5) {
		--app-bg-s1: #cecdd5;
		--app-bg-s2: #89888d;

		transform-origin: -25% 230%;
	}

	&:nth-child(6) {
		--app-bg-s1: #1ac5fb;
		--app-bg-s2: #1d71f2;

		transform-origin: -125% 200%;
	}

	&:nth-child(7) {
		--app-bg-s1: #fe9b01;
		--app-bg-s2: #f67324;

		transform-origin: 175% 80%;
	}

	&:nth-child(8) {
		--app-bg-s1: #cb65f0;
		--app-bg-s2: #8628bb;

		transform-origin: 75% 100%;
	}

	&:nth-child(9) {
		--app-bg-s1: #1d71f2;
		--app-bg-s2: #1ac8fd;

		transform-origin: -25% 100%;
	}

	&:nth-child(10) {
		transform-origin: -125% 80%;
	}
}

.pallette {
	position: relative;
	z-index: 1;

	order: 1;
	display: flex;
	gap: 2em;
	margin-right: 2.25em;
	margin-bottom: -0.25em;

	&:hover ~ .phone-con .screen {
		transition-delay: 0.5s;
		opacity: 0;
	}
}

.zoom-con {
	order: 1;
}

// --------------
// Theme picker
// --------------

// Hide inputs
input[type="radio"],
input[type="checkbox"] {
	display: none;
}

.swatch {
	--swatch-size: max(30px, 5em);
	--border-opacity: 0;

	background: white;
	width: var(--swatch-size);
	height: var(--swatch-size);
	border-radius: 50%;
	position: relative;
	cursor: pointer;

	border: max(1.5px, var(--border-width)) solid black;
	box-sizing: border-box;
	// transform: scale3d(0.85, 0.85, 1);

	background: radial-gradient(
		100% 100% at 50% 30%,
		var(--swatch-s1),
		var(--swatch-s2)
	);

	opacity: 0;
	transform: translate3d(0, 20%, 0) scale3d(0.75, 0.75, 1);
	animation: appear 0.333s var(--ease-out) forwards 0.75s;

	display: flex;
	align-items: center;
	color: white;
	justify-content: center;

	outline: none;

	&:before {
		content: "";
		position: absolute;
		inset: -1px;
		border-radius: inherit;
		border: var(--border-width) solid black;
		background-image: radial-gradient(
			400% 300% at 50% 225%,
			transparent 20%,
			white
		);
		// filter: blur(0.2em);
		// box-shadow: inset 0 0 0.1em 0.1em black;
	}

	&:not([for="zoom"]) {
		&:after {
			content: "";
			position: absolute;
			inset: calc(var(--border-width) * -1);
			border-width: inherit;
			border-style: inherit;
			opacity: var(--border-opacity);
			transition: 0.25s var(--ease-out);
			transition-property: opacity;
			border-radius: inherit;
		}

		&:hover {
			--border-opacity: 0.666;
		}

		&:focus {
			--border-opacity: 1;
		}
	}

	&:nth-child(1) {
		transform-origin: 100% 200%;
	}

	&:nth-child(2) {
		animation-delay: 0.8s;
		transform-origin: 80% 200%;
	}

	&:nth-child(3) {
		animation-delay: 0.85s;
		transform-origin: 50% 200%;
	}

	&:nth-child(4) {
		animation-delay: 0.9s;
		transform-origin: 40% 200%;
	}

	&:nth-child(5) {
		animation-delay: 0.95s;
		transform-origin: 20% 200%;
	}

	&[for="deep-purple"] {
		--swatch-s1: hsl(var(--deep-purple), 100%, 50%);
		--swatch-s2: hsl(calc(var(--deep-purple) - 60), 100%, 20%);

		&:before {
			opacity: 0.5;
		}
	}

	&[for="gold"] {
		--swatch-s1: hsl(var(--gold), 100%, 50%);
		--swatch-s2: hsl(var(--gold), 100%, 50%);
	}

	&[for="space-black"] {
		--swatch-s1: hsl(var(--space-black), 50%, 20%);
		--swatch-s2: hsl(var(--space-black), 50%, 10%);

		&:before {
			opacity: 0.5;
		}
	}

	&[for="silver"] {
		--swatch-s1: hsl(var(--silver), 50%, 80%);
		--swatch-s2: hsl(var(--silver), 50%, 10%);

		&:before {
			opacity: 0.75;
		}
	}

	&[for="random"] {
		&:before {
			background: none;
		}

		border-color: rgba(white, 0.25);
		transition: border-color 0.2s var(--ease-out);

		&:hover {
			border-color: rgba(white, 0.75);

			.icon {
				opacity: 1;
			}
		}

		.icon {
			position: absolute;
			inset: 22.5%;
			background: url("data:image/svg+xml,%3Csvg width='24' height='24' fill='none' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='m18 15 3 3m0 0-3 3m3-3h-4l-1-1-1-1h-1m4-13 3 3m0 0-3 3m3-3h-4l-1 1-1 1-6 8-1 1-1 1H3M3 6h4l1 1 1 1 1 1' stroke='%23fff' stroke-width='1.5' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E")
				no-repeat center / contain;
			opacity: 0.75;
			transition: opacity 0.2s var(--ease-out);
		}

		#random:not(:checked) ~ .scene &:after {
			border: none;
		}

		#random:checked ~ .scene & {
			--swatch-s1: hsl(var(--r-h), var(--r-s), var(--r-l));
			--swatch-s2: hsl(var(--r-h), var(--r-s), calc(min(98%, var(--r-l) + 10%)));

			&:after {
				border-color: hsl(var(--r-h), 50%, 75%);
			}

			.icon {
				background: url("data:image/svg+xml,%3Csvg width='24' height='24' fill='none' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='m18 15 3 3m0 0-3 3m3-3h-4l-1-1-1-1h-1m4-13 3 3m0 0-3 3m3-3h-4l-1 1-1 1-6 8-1 1-1 1H3M3 6h4l1 1 1 1 1 1' stroke='%23000' stroke-width='1.5' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E")
					no-repeat center / contain;
			}

			&:hover,
			&:focus {
				.tooltip {
					pointer-events: all;
					opacity: 1;
				}
			}
		}
	}

	&[for="zoom"] {
		--zoom-icon: url("data:image/svg+xml,%3Csvg width='32' height='32' fill='none' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='m5 27 9-9m-9 9v-9m0 9h9M27 5l-9 9m9-9v9m0-9h-9' stroke='%23fff' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E");
		animation-delay: 1s;
		transform-origin: 40% 200%;

		border-color: rgba(white, 0.25);
		transition: border-color 0.2s var(--ease-out);

		&:before {
			background: none;
		}

		&:after {
			content: "";
			position: absolute;
			inset: 22.5%;
			background: var(--zoom-icon) center / cover;
			opacity: 0.75;
			transition: opacity 0.2s var(--ease-out);
		}

		&:hover {
			border-color: rgba(white, 0.5);

			&:after {
				opacity: 1;
			}
		}

		&:focus {
			border-color: rgba(white, 0.75);

			&:after {
				opacity: 1;
			}
		}
	}
}

// Deep Purple theme
.deep-purple {
	--c-h: var(--deep-purple);
	--g-hue-adjust: 40;
	--g-hue-adjust-2: 45;

	.section:last-of-type {
		--g-hue-adjust-2-y: 85%;
	}
}

// Gold theme
.gold {
	--c-h: var(--gold);
	--g-hue-adjust: 0;

	.section:last-of-type {
		--g-hue-adjust: 15;
		--g-hue-adjust-2: -190;
		--g-lightness: 82.5%;
	}
}

// Space Black theme
.space-black {
	--c-h: var(--space-black);
	--g-hue-adjust: 0;
	--g-lightness: 95%;

	.section:last-of-type {
		--g-hue-adjust: 215;
		--g-hue-adjust-2: -215;
	}
}

// Silver theme
.silver {
	--c-h: var(--silver);
	--c-s: 10%;
	--g-hue-adjust: 40;
	--g-lightness: 95%;
	--g-hue-adjust-2-y: 85%;

	.section:last-of-type {
		--g-hue-adjust-2: 15;
	}

	.glow {
		opacity: 0.25;
	}
}

$themes: "deep-purple", "gold", "space-black", "silver", "random";

@each $theme in $themes {
	label[for="#{$theme}"]:after {
		border-color: hsl(var(--#{$theme}), 50%, 75%);
	}

	##{$theme}:checked {
		~ .scene .phone .bg .#{$theme} {
			opacity: 1;
			z-index: 1;
			transition-delay: 0s;

			.section:before {
				transition-delay: 0s;
				transform: scale3d(1, 1, 1) translate3d(0, 0, 0);
			}
		}

		~ .scene .pallette label[for="#{$theme}"] {
			--border-opacity: 1 !important;
		}
	}
}

// Zoom
#zoom:checked ~ .scene {
	--size: max(5px, 2vmin);

	opacity: 0;
	animation: appear 0.5s var(--ease-out) forwards;

	.phone {
		order: 1;
	}

	.pallette,
	.zoom-con {
		order: 0;
		font-size: 50%;
	}

	label[for="zoom"] {
		--zoom-icon: url("data:image/svg+xml,%3Csvg width='32' height='32' fill='none' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='m14 18-9 9m9-9v9m0-9H5M18 14l9-9m-9 9V5m0 9h9' stroke='%23fff' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E");
	}
}

#zoom:not(:checked) ~ .scene {
	opacity: 0;
	animation: appear-again 0.5s var(--ease-out) forwards;

	@keyframes appear-again {
		to {
			transform: scale3d(1, 1, 1);
			opacity: 1;
		}
	}
}

// Random gradient
.random {
	background: hsl(var(--r-h), var(--r-s), var(--r-l));

	&--colourful {
		--bm-outer: overlay;
		--bm-inner: difference;
	}

	&--moody {
		--bm-outer: exclusion;
		--bm-inner: multiply;
	}

	&--neon {
		--bm-outer: hue;
		--bm-inner: multiply;
	}

	&--abstract {
		--bm-outer: color-burn;
		--bm-inner: difference;
	}

	&--grayscale {
		--bm-outer: color-burn;
		--bm-inner: difference;
		filter: brightness(1.2) grayscale(100%) contrast(2);
	}

	&--light-leak {
		--bm-outer: color-burn;
		--bm-inner: multiply;
	}
}

.shapes {
	mix-blend-mode: var(--bm-outer, overlay);
	background: hsl(var(--r-h), var(--r-s), 85%);
	position: absolute;
	inset: 0%;
	z-index: 1;
	backface-visibility: hidden;
}

.shape {
	position: absolute;
	pointer-events: none;
	transition-property: background, inset, border-radius, filter, transform;
	will-change: inset, border-radius, filter;
	mix-blend-mode: var(--bm-inner, difference);
	top: 50%;
	left: 50%;
	aspect-ratio: 1/1;

	background: hsl(var(--r-h), var(--r-s), var(--r-l));
	width: var(--w, 99%);
	border-radius: var(--b-r, 55%);
	filter: blur(var(--b));
	transform: translate3d(calc(var(--x, -1%) - 50%), calc(var(--y, -8%) - 50%), 0)
		scale3d(var(--s-x, 1.9), var(--s-y, 1.15), 1) rotate(var(--r, 260deg));
}

.tooltip {
	--t-caret: 0.5em;

	position: absolute;
	z-index: 1;
	top: calc(100% + var(--t-caret) + 0.5em);
	white-space: nowrap;
	background: black;
	color: rgba(white, 0.75);
	padding: 0.25em;
	font-size: max(11px, 1em);
	border-radius: 0.25em;
	border: 1px solid lighten(black, 25);

	pointer-events: none;
	opacity: 0;
	transition: opacity 0.25s var(--ease);

	&:after {
		content: "";
		position: absolute;
		bottom: calc(100% - calc(var(--t-caret) / 2) - 1px);
		left: calc(50% - calc(var(--t-caret) / 2));
		border-radius: inherit;
		height: var(--t-caret);
		width: var(--t-caret);
		background: inherit;
		border: inherit;
		border-top-color: transparent;
		border-left-color: transparent;
		transform: rotate(-135deg);
	}

	#zoom:checked ~ .scene & {
		top: unset;
		bottom: calc(100% + var(--t-caret) + 0.5em);

		&:after {
			transform: rotate(45deg);
			top: calc(100% - calc(var(--t-caret) / 2) - 1px);
			bottom: unset;
		}
	}
}

Another article for you.

CSS iPhone 14 Lock Screen Animation
CSS iPhone 14 Lock Screen Animation

JavaScript(Babel):

const delay = 300;
let afterResize;
let currentStyle;

window.onresize = function () {
	document.body.classList.add("is-resizing");
	clearTimeout(afterResize);
	afterResize = setTimeout(
		() => document.body.classList.remove("is-resizing"),
		delay
	);
};

document.getElementById("zoom").addEventListener("click", () => {
	document.body.classList.add("is-resizing");
	setTimeout(() => document.body.classList.remove("is-resizing"), delay);
});

// Generating random gradient

let dimension = 1000; // Size of tile to be download px

const styles = [
	"colourful",
	"moody",
	"neon",
	"abstract",
	"grayscale",
	"light-leak"
];

const generateBtn = document.querySelector('[for="random"]');
const canvas = document.querySelector(".canvas");

const random = (min, max) => Math.floor(Math.random() * (max - min + 1) + min);

// Generate randomised gradients

generateBtn.addEventListener("click", generateOrSave);

function generateOrSave(e) {
	if (e.metaKey) {
		saveGradient(e);
	} else {
		generateGradient();
	}
}

function generateGradient() {
	// Assign style
	const newStyle = styles[Math.floor(Math.random() * styles.length)];

	// console.log(styles, styles[Math.floor(Math.random() * styles.length)]);

	if (currentStyle) canvas.classList.remove(`random--${currentStyle}`);

	currentStyle = newStyle;
	canvas.classList.add(`random--${newStyle}`);

	// Loop through each canvas and assign a bunch of random CSS variables
	const shapes = canvas.getElementsByClassName("shape");

	document.body.style.setProperty("--r-h", `${random(0, 360)}deg`);
	document.body.style.setProperty("--r-s", `${random(40, 90)}%`);
	document.body.style.setProperty("--r-l", `${random(55, 90)}%`);

	Object.values(shapes).forEach((shape) => {
		shape.style.setProperty("--r-h", `${random(0, 360)}deg`);
		shape.style.setProperty("--r-s", `${random(40, 90)}%`);
		shape.style.setProperty("--r-l", `${random(55, 90)}%`);

		shape.style.setProperty("--w", `${random(0, 30) + 85}%`);
		shape.style.setProperty("--b-r", `${random(20, 60)}%`);
		shape.style.setProperty("--b", `${random(5, 75) / 10}em`);
		shape.style.setProperty("--x", `${random(0, 100) - 50}%`);
		shape.style.setProperty("--y", `${random(0, 100) - 50}%`);
		shape.style.setProperty("--s-x", `${1 + (random(0, 130) - 30) / 100}`);
		shape.style.setProperty("--s-y", `${1 + (random(0, 130) - 30) / 100}`);
		shape.style.setProperty("--r", `${random(0, 720) - 360}deg`);
	});
}

// Convert RGB colour to Hex
// Needed for api.color.pizza call
const rgba2hex = (rgba) =>
	`#${rgba
		.match(/^rgba?\((\d+),\s*(\d+),\s*(\d+)(?:,\s*(\d+\.{0,1}\d*))?\)$/)
		.slice(1)
		.map((n, i) =>
			(i === 3 ? Math.round(parseFloat(n) * 255) : parseFloat(n))
				.toString(16)
				.padStart(2, "0")
				.replace("NaN", "")
		)
		.join("")}`;

// Save gradient
function saveGradient(e) {
	const gradient = canvas;
	const rect = gradient.getBoundingClientRect();
	const scale = dimension / rect.width;

	//	Get canvas background color
	const color = rgba2hex(
		window.getComputedStyle(gradient, null).getPropertyValue("background-color")
	);

	console.log(color, scale, rect);

	// Get name of color for use in file name
	fetch(`https://api.color.pizza/v1/${color.substring(1)}`)
		.then((c) => c.json())
		.then((c) => {
			// console.log(c);

			// Convert DOM to canvas
			domtoimage
				.toPng(gradient, {
					bgColor: "#ffffff",
					width: rect.width * scale,
					height: rect.height * scale,
					style: {
						transform: `scale(${scale})`,
						"transform-origin": "top left"
					}
				})
				// Download image
				.then(function (dataUrl) {
					// const img = new Image();
					// img.src = dataUrl;
					// document.body.appendChild(img);

					// Render canvas as a link and click dat
					const link = document.createElement("a");
					link.download = `${currentStyle}-${c["paletteTitle"]
						.toLowerCase()
						.replaceAll(" ", "-")}-gradient`;
					link.href = dataUrl;
					link.click();
				});
		});
}
, ,

More Queries: