Rotating Möbius Loop using HTML and CSS

Share your love

The Möbius loop, a symbol of endlessness and simplicity, is as mesmerizing in mathematics as it is in design. What if you could bring this geometric marvel to life on the web? In this blog, we’ll demonstrate how to create a beautifully rotating Möbius loop using nothing but HTML and CSS. With clever use of CSS 3D transforms, gradients, and animations, we’ll capture the elegance of this one-sided surface and set it in motion. Whether you’re exploring creative web elements or diving into mathematical art, this project will inspire you to push the boundaries of what CSS can achieve. Let’s get the loop spinning!

I would recommend you don’t just copy and paste the code, just look at the code and type by understanding it.

Demo

See the Pen Rotating Möbius Loop – SCSS by Josetxu (@josetxu) on CodePen.

HTML Code 

Starter Template

<!doctype html>
<html lang="en">

<head>
    <!-- Required meta tags -->
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1">

    <!-- CSS -->
    <link rel="stylesheet" href="style.css">

    <title>Coding Torque</title>
</head>

<body>
    <!-- Further code here -->

</body>

</html>

Paste the below code in your <body> tag.

- for (i = 0; i < 400; i++)
  .cam

.content
  .zoom
    - for (var l=0; l<18; l++)
      .line
        .cuboid
          - for (var s=0; s<6; s++)
            .side

CSS Code 

Create a file style.css and paste the code below.

@import url('https://fonts.googleapis.com/css2?family=Days+One&family=Gluten&display=swap');

* {
	transform-style: preserve-3d;
	box-sizing: border-box;
}

body {
	margin: 0;
	padding: 0;
	width: 100vw;
	height: 100vh;
	overflow: hidden;
	perspective: 100vmin;
	background: radial-gradient(circle at 50% 100%, #607D8B80, #fff0), radial-gradient(circle at 50% 0%, #607D8B40, #1e0053);
	background-color: #000;
}

body:before, body:after {
	content: "hover to rotate";
	position: absolute;
	width: 100%;
	text-align: center;
	text-transform: uppercase;
	font-family: 'Gluten', Arial, Helvetica, serif;
	color: #7678bb;
	text-shadow: 0px -1px 0 #0008, 0px 1px 0 #0008;
	top: 5vh;
	left: 0;
	z-index: -1;
}

body:after {
	content: "click & hold to zoom";
	top: 95vh;
}

.content {
	width: 50vmin;
	height: 50vmin;
	left: calc(50% - 25vmin);
	top: calc(50% - 25vmin);
	background: #f000;
	display: flex;
	align-items: center;
	justify-content: center;
	transform: rotateX(40deg);
	position: absolute;
	transition: all 0.5s ease 0s;
	z-index: 1;
}

.cuboid {
	--height: 6;
	--width: 6;
	--depth: 6;
	--hue: 250;
	--sat: 15%;
	--lum: 45%;
	height: calc(var(--height) * 1vmin);
	width: calc(var(--width) * 1vmin);
	position: absolute;
}

.cuboid .side {
	position: absolute;
	top: 50%;
	left: 50%;
	height: 100%;
	width: 100%;
	border-radius: 2px;
	background: hsl(var(--hue), var(--sat), var(--lum));
}

.cuboid .side:nth-of-type(1) {
	transform: translate3d(-50%, -50%, calc(var(--depth) * 0.5vmin));
}
.cuboid .side:nth-of-type(2) {
	transform: translate3d(-50%, -50%, calc(var(--depth) * -0.5vmin)) rotateY(180deg);
}
.cuboid .side:nth-of-type(3) {
	width: calc(var(--depth) * 1vmin);
	transform: translate(-50%, -50%) rotateY(90deg)	translate3d(0, 0, calc(var(--width) * 0.5vmin));
	--lum: 70%;
}
.cuboid .side:nth-of-type(4) {
	width: calc(var(--depth) * 1vmin);
	transform: translate(-50%, -50%) rotateY(-90deg) translate3d(0, 0, calc(var(--width) * 0.5vmin));
	--lum: 70%;
}
.cuboid .side:nth-of-type(5) {
	height: calc(var(--depth) * 1vmin);
	transform: translate(-50%, -50%) rotateX(90deg) translate3d(0, 0, calc(var(--height) * 0.5vmin));
	--lum: 20%;
}
.cuboid .side:nth-of-type(6) {
	height: calc(var(--depth) * 1vmin);
	transform: translate(-50%, -50%) rotateX(-90deg) translate3d(0, 0, calc(var(--height) * 0.5vmin));
	--lum: 20%;
}


.cuboid .side:before {
	content: "";
	position: absolute;
	width: 100%;
	height: 100%;
	background:	
		repeating-conic-gradient(#0004 0%, #fff0 .0003%, #fff0 .0005%,  #fff0 .00095%),
		repeating-conic-gradient(#fff2 0%, #fff0 .0005%, #fff0 .0015%, #fff0 .009%);
	background-size: 100% 101%;
}

.line {
	width: 50%;
	height: 10vmin;
	position: absolute;
	left: 0;
	transform-origin: 100% 50%;
}

@for $i from 1 through 18 {
	.line:nth-child(#{$i}) {
		transform: rotate(($i) * 20deg);
		.cuboid {
			transform: rotateY($i * 10deg);
			animation: spin-#{$i} 6s linear 0s infinite;
		}
		@keyframes spin-#{$i} {
			to { transform: rotateY(($i) * 10deg + 360deg); }
		}
	}

}


.zoom {
	width: 100%;
	height:100%;
	display: flex;
	align-items: center;
	justify-content: center;
}


.cam {
	width: 5vw;
	height: 5vh;
	float: left;
	box-sizing: border-box;
	position: relative;
	z-index: 3;
	cursor: zoom-in;	
	/*transform: translateZ(0vmin);*/
	/*box-shadow: 0 0 1px 0 red inset;*/
	@for $i from 1 through 20 {
		@for $j from 1 through 20 {
			$key: ($i - 1) * 20 + $j;
			&:nth-child(#{$key}) {
				&:hover ~ .content {
					transform: 
						rotateX(($i - 8) * 10deg + 65) 
						rotateY(($j - 8) * 10deg - 24);
				}
			}
		}
	}
	&:active ~ .content .zoom {
		transform: scale3d(1.75, 1.75, 1.75);
		transition: all 0.75s ease 0s;
	}
}

Final Output

Written by: Piyush Patil

Code Credits: https://codepen.io/josetxu/pen/poGxZXv

If you found any mistakes or have any doubts please feel free to Contact Us

Hope you find this post helpful💖

Share your love

Leave a Reply

Your email address will not be published. Required fields are marked *