SOURCE

console 命令行工具 X clear

                    
>
console
// inspiration: https://dribbble.com/shots/5471123-Tab-Bar-Exploration-XVII

console.clear();

const tabbarEl = document.querySelector(".tabbar");
const showButton = tabbarEl.querySelector(".tabbar--button");

showButton.addEventListener("click", showMenu);

function showMenu() {
	if (tabbarEl.classList.contains("show")) {
		tabbarEl.classList.remove("show");
	} else {
		tabbarEl.classList.add("show");
	}
}
<div class="phone">
	<div class="phone__left"></div>
	<div class="phone__right"></div>
	<div class="phone__bottom">
		<button class="button__home"></button>
	</div>
	<div class="phone__screen"></div>


	<div class="app">

		<div class="app--content">
			<span style="--index: 0;"></span>
			<span style="--index: 1;"></span>
			<span style="--index: 2;"></span>
			<span style="--index: 3;"></span>
			<span style="--index: 4;"></span>
			<span style="--index: 5;"></span>
			<span style="--index: 6;"></span>
			<span style="--index: 7;"></span>
			<span style="--index: 8;"></span>
			<span style="--index: 9;"></span>
			<span style="--index: 10;"></span>
			<span style="--index: 11;"></span>
		</div>

		<div class="tabbar">
			<div class="tabbar--front">
				<button class="tabbar--button">
					<div class="icon">
						<svg xmlns='http://www.w3.org/2000/svg' width='512' height='512' viewBox='0 0 512 512'>
							<line x1='256' y1='112' x2='256' y2='400' />
							<line x1='400' y1='256' x2='112' y2='256' />
						</svg>
					</div>
				</button>
				<div class="options">
					<div class="options__wrapper">
						<span></span>
						<span></span>
						<span></span>
						<span></span>
						<span></span>
						<span></span>
						<span></span>
						<span></span>
						<span></span>
					</div>
				</div>
			</div>
			<div class="tabbar--back">
				<button></button>
				<div class="options"></div>
			</div>
		</div>

	</div>

</div>


<svg class="goo-filter" style="position: absolute; transform: translateX(-100%); pointer-events: none; user-select: none;" viewbox="0 0 1 1">
	<filter id="goo">
		<feGaussianBlur in="SourceGrapgic" stdDeviation="10" 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 40 -10" result="goo" />
		<feBlend in="SourceGraphic" in2="goo" />
	</filter>
</svg>




<div class="support">
	<a href="https://twitter.com/DevLoop01" target="_blank"><i class="fab fa-twitter-square"></i></a>
	<a href="https://dribbble.com/devloop01" target="_blank"><i class="fab fa-dribbble"></i></a>
</div>
:root {
	--phone-width: 350px;
	--phone-height: 480px;
	--phone-color: rgb(20, 20, 20);

	--screen-color: rgb(10, 10, 10);
	--app-width: 350px;
	--app-height: 400px;
	--app-bg: #090831;

	--button-color: #ff4f79;

	--bg: #4a4a6a;

	--phone-animation-duration: 1.2s;
	--phone-animation-delay: 500ms;
	--phone-animation-easing: ease;
	--phone-animation-direction: forwards;

	--screen-animation-duration: 0.8s;
	--screen-animation-delay: 1800ms;
	--screen-animation-easing: ease;
	--screen-animation-direction: forwards;
}
* {
	box-sizing: border-box;
	margin: 0;
	padding: 0;
}

body {
	width: 100%;
	height: 100vh;
	display: flex;
	justify-content: center;
	background: var(--bg);
	overflow: hidden;
}

button {
	border: none;
	&:focus {
		outline: none;
		border: none;
	}
}

.phone {
	position: relative;
	min-width: var(--phone-width);
	height: var(--phone-height);
	display: flex;
	justify-content: center;
	align-items: center;
	border-bottom-left-radius: 2rem;
	border-bottom-right-radius: 2rem;

	transform: translateY(-200%);
	animation: show-phone var(--phone-animation-duration) var(--phone-animation-easing)
		var(--phone-animation-direction);
	animation-delay: var(--phone-animation-delay);

	box-shadow: 0 0 0 5px rgb(100, 100, 100), 0 2.4px 5.3px rgba(0, 0, 0, 0.07),
		0 5.7px 12.6px rgba(0, 0, 0, 0.101), 0 10.6px 23.8px rgba(0, 0, 0, 0.125),
		0 19px 42.4px rgba(0, 0, 0, 0.149), 0 35.5px 79.4px rgba(0, 0, 0, 0.18),
		0 85px 190px rgba(0, 0, 0, 0.25);
	overflow: hidden;

	&__screen {
		position: absolute;
		left: 0;
		top: 0;
		width: var(--app-width);
		height: calc(5px + var(--app-height));
		background: var(--screen-color);
		z-index: 80;

		animation: hide-screen-top var(--screen-animation-duration) var(--screen-animation-easing)
			var(--screen-animation-direction);
		animation-delay: var(--screen-animation-delay);
	}

	&__left,
	&__right {
		position: absolute;
		top: 0;
		width: 10px;
		height: 85%;
		background: var(--phone-color);
		z-index: 100;
	}
	&__left {
		left: 0;
		transform: translateX(-2px);
	}
	&__right {
		right: 0;
		transform: translateX(2px);
	}
	&__bottom {
		position: absolute;
		left: 50%;
		bottom: 0;
		transform: translateX(-50%);
		border-bottom-left-radius: 2rem;
		border-bottom-right-radius: 2rem;
		width: calc(100% + 4px);
		height: 80px;
		background: var(--phone-color);
		z-index: 100;
		display: flex;
		justify-content: center;
		align-items: center;
		.button__home {
			--button-home-size: 55px;
			position: relative;
			width: var(--button-home-size);
			height: var(--button-home-size);
			border: 2px solid rgb(35, 35, 35);
			border-radius: 50%;
			background: none;
			&::after {
				content: "";
				position: absolute;
				left: 50%;
				top: 50%;
				transform: translate(-50%, -50%);
				width: 25%;
				height: 25%;
				background: none;
				border: 2px solid rgb(80, 80, 80);
				border-radius: 30%;
			}
		}
	}
}

.app {
	position: absolute;
	left: 0;
	top: 0;
	width: var(--app-width);
	height: var(--app-height);
	background: var(--app-bg);
	z-index: 50;

	&--content {
		position: absolute;
		left: 0;
		top: -5%;
		width: 100%;
		height: 150%;
		display: grid;
		grid-template-columns: repeat(auto-fill, minmax(80px, 1fr));
		grid-template-rows: repeat(auto-fill, minmax(100px, 1fr));
		grid-gap: 0.8rem;
		padding: 0 1.5rem;

		span {
			background: rgba(255, 255, 255, 0.08);
			border-radius: 0.5rem;
			transform: translateY(25%) rotate(5deg);
			transform-origin: top left;
			opacity: 0;
			animation: card-pop-in 350ms var(--screen-animation-easing)
				var(--screen-animation-direction);
			animation-delay: calc(300ms + var(--screen-animation-delay) + 30ms * var(--index));
		}
	}
}

.tabbar {
	position: absolute;
	width: 100%;
	height: 10px;
	bottom: 0;
	left: 0;

	button,
	.options {
		position: absolute;
		left: 50%;
		top: 50%;
		transform: translate(-50%, -50%);
	}

	button {
		--size: 40px;
		--button-y-offset: -50%;
		border: none;
		width: var(--size);
		height: var(--size);
		border-radius: var(--size);
		background: var(--button-color);
		transform: translate(-50%, var(--button-y-offset));
		transition: transform 500ms ease;
		transition-delay: 200ms;
		cursor: pointer;

		top: 400%;
		animation: button-pop-in-elastic 500ms cubic-bezier(0.185, 1.485, 0.35, 3.575)
			var(--screen-animation-direction);
		animation-delay: calc(1s + var(--screen-animation-delay));

		.icon {
			position: absolute;
			left: 0;
			top: 0;
			transform: translateY(-20%) rotate(0);
			width: 100%;
			height: 100%;
			display: flex;
			justify-content: center;
			align-items: center;
			transition: transform 500ms ease;
			transition-delay: 200ms;
			svg {
				width: 50%;
				height: 50%;
				fill: none;
				stroke: rgb(255, 255, 255);
				stroke-linecap: round;
				stroke-linejoin: round;
				stroke-width: 60px;

				transform: rotate(180deg);
				animation: rotate 500ms cubic-bezier(0.185, 1.485, 0.35, 3.575)
					var(--screen-animation-direction);
				animation-delay: calc(1s + var(--screen-animation-delay));
			}
		}
	}

	.options {
		width: var(--options-width);
		height: var(--options-height);
		transform: translate(-50%, var(--options-y-offset));
		background: var(--button-color);
		transition: transform 500ms ease;
		transition-delay: 200ms;
		display: flex;
		justify-content: center;
		align-items: center;

		&__wrapper {
			display: grid;
			grid-template-columns: repeat(3, 100px);
			grid-template-rows: repeat(3, 100px);
			place-content: center;
			grid-gap: 0.6rem;
			clip-path: circle(0% at 50% 50%);
			transition: clip-path 500ms ease;
			span {
				background: rgba(255, 255, 255, 0.2);
				border-radius: 50%;
			}
		}
	}

	&--front,
	&--back {
		position: absolute;
		left: 50%;
		top: 0;
		transform: translateX(-50%);
		width: 100%;
		height: 100%;
	}

	&--front {
		--options-width: 100%;
		--options-height: 400px;
		--options-y-offset: 3%;
		z-index: 2;
		button {
			--size: 40px;
			z-index: 4;
		}
	}
	&--back {
		--options-width: 100px;
		--options-height: 100px;
		--options-y-offset: 10%;
		filter: url(#goo);
		button {
			pointer-events: none;
		}
		z-index: 1;
	}

	&.show {
		.tabbar--front {
			--options-y-offset: -112%;
			button {
				--button-y-offset: -130%;
			}
			.icon {
				transform: translateY(0%) rotate(45deg * 5);
			}
			.options {
				&__wrapper {
					clip-path: circle(100% at 50% 50%);
					transition-delay: 400ms;
				}
			}
		}
		.tabbar--back {
			--options-y-offset: -154%;
			button {
				--button-y-offset: -140%;
			}
		}
	}
}

@keyframes show-phone {
	to {
		transform: translateY(0);
	}
}

@keyframes hide-screen-top {
	to {
		opacity: 0;
		pointer-events: none;
	}
}

@keyframes card-pop-in {
	to {
		opacity: 1;
		transform: translateY(0) rotate(0);
	}
}

@keyframes button-pop-in-elastic {
	to {
		top: 50%;
	}
}

@keyframes rotate {
	to {
		transform: rotate(0deg);
	}
}


.support{
	position: absolute;
	right: 10px;
	bottom: 10px;
	padding: 10px;
	display: flex;
	a{
		margin: 0 10px;
		color: #fff;
		font-size: 1.8rem;
		backface-visibility: hidden;
		transition: all 150ms ease;
		&:hover{
			transform: scale(1.1);
		}
	}

}