Skip to content

Instantly share code, notes, and snippets.

@Rplus
Last active May 27, 2016 09:20
Show Gist options
  • Select an option

  • Save Rplus/a7a93f34dd2ae52780fddccfd10d96d1 to your computer and use it in GitHub Desktop.

Select an option

Save Rplus/a7a93f34dd2ae52780fddccfd10d96d1 to your computer and use it in GitHub Desktop.
Möbiusband
<!DOCTYPE html>
html(lang="en")
head
meta(charset="UTF-8")
title Rotating Möbiusband in 3D CSS
meta(name="viewport", content="width=device-width")
link(rel="stylesheet", href="style.css")
body
h1.intro Rotating Möbiusband
small in 3D CSS
input.sr-only#revolution(type="checkbox", checked)
input.sr-only#rotation(type="checkbox")
input.sr-only#revolution-dir--clockwise(type="radio", name="revolution-dir", checked)
input.sr-only#revolution-dir--anticlockwise(type="radio", name="revolution-dir")
input.sr-only#rotation-dir--clockwise(type="radio", name="rotation-dir", checked)
input.sr-only#rotation-dir--anticlockwise(type="radio", name="rotation-dir")
.controls
dl.controls__revolution
dt.pri-controls
label.control-label(for="revolution") Revolution
dd.sub-controls
label.control-label.control-label--radio(for="revolution-dir--clockwise") clockwise
dd.sub-controls
label.control-label.control-label--radio(for="revolution-dir--anticlockwise") anticlockwise
dl.controls__rotation
dt.pri-controls
label.control-label(for="rotation") Rotation
dd.sub-controls
label.control-label.control-label--radio(for="rotation-dir--clockwise") clockwise
dd.sub-controls
label.control-label.control-label--radio(for="rotation-dir--anticlockwise") anticlockwise
- var i = 100;
.box
- while(i--)
.s
blockquote.info
| ref: #[a(href="https://en.wikipedia.org/wiki/M%C3%B6bius_strip") Möbius strip]
$c-bgc: #e7e5d8;
$count: 100;
$strip-ratio: 20;
$strip-width: 1vmin;
.s {
position: absolute;
top: 0;
left: 0;
width: $strip-width;
height: $strip-width * $strip-ratio;
transform-style: preserve-3d;
&::before {
content: "";
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
background-image: linear-gradient(90deg, rgba(#000, .5), rgba(#fff, .75));
animation: rotation 10s linear infinite paused;
#rotation:checked ~ .box & {
// animation-play-state: running;
animation: rotation 10s linear infinite;
}
// safari mobile doesn't support
// via: https://developer.mozilla.org/en-US/docs/Web/CSS/animation-direction#Browser_compatibility
@supports (animation-direction: reverse) {
#rotation-dir--anticlockwise:checked ~ .box & {
animation-direction: reverse;
}
}
}
@for $i from 1 through $count {
&:nth-of-type(#{$i}) {
transform:
rotateY(#{$i * 360deg / $count})
translateZ(20vmin)
rotateX(#{$i * 180deg / $count});
}
}
}
.box {
position: absolute;
top: 50%;
left: 50%;
transform-style: preserve-3d;
transform: rotateX(-30deg);
animation: revolution 10s linear infinite paused;
#revolution:checked ~ & {
// animation-play-state: running;
animation: revolution 10s linear infinite;
}
@supports (animation-direction: reverse) {
#revolution-dir--anticlockwise:checked ~ & {
animation-direction: reverse;
}
}
}
@keyframes rotation {
from {
transform: rotateX(0deg);
}
to {
transform: rotateX(360deg);
}
}
@keyframes revolution {
from {
transform: rotateX(-30deg) rotateY(0deg);
}
to {
transform: rotateX(-30deg) rotateY(-360deg);
}
}
/// reset
*,
*::before,
*::after {
box-sizing: border-box;
margin: 0;
}
html {
height: 100%;
}
body {
display: flex;
flex-direction: column;
min-height: 100%;
margin: 0;
background: $c-bgc;
color: #333;
text-align: center;
}
a {
color: inherit;
}
.intro {
width: 90%;
max-width: 30rem;
padding-bottom: 1rem;
margin: 0 auto 1em;
padding-top: .5em;
font-size: calc(1rem + 2vmin);
text-transform: capitalize;
border-bottom: 1px dashed rgba(#000, .3);
small {
display: block;
opacity: .5;
font-style: italic;
text-transform: none;
}
}
.info {
margin-top: auto;
padding: 1em;
font-size: .9em;
font-style: italic;
font-family: serif;
text-align: right;
opacity: .5;
}
.sr-only {
position: absolute;
width: 1px;
height: 1px;
padding: 0;
margin: -1px;
overflow: hidden;
clip: rect(0, 0, 0, 0);
border: 0;
}
.controls {
display: flex;
margin-left: auto;
margin-right: auto;
text-align: left;
line-height: 1.7;
@media (max-height: 30em) and (orientation: landscape) {
margin-right: 45%;
& ~ .box {
left: calc(50% + 40vmin);
}
}
dl {
margin-left: 1em;
margin-right: 1em;
}
}
.pri-controls {
margin-bottom: .5em;
}
.sub-controls {
margin-left: 1em;
font-size: .9em;
opacity: 0;
transition: opacity .2s;
}
.control-label {
cursor: pointer;
display: inline-flex;
align-items: center;
&::before {
content: "";
width: 1.2em;
height: 1.2em;
margin-right: .25em;
border: 2px solid;
vertical-align: middle;
}
&.control-label--radio::before {
border-radius: 50%;
}
}
#revolution:checked ~ .controls [for="revolution"],
#revolution-dir--clockwise:checked ~ .controls [for="revolution-dir--clockwise"],
#revolution-dir--anticlockwise:checked ~ .controls [for="revolution-dir--anticlockwise"],
#rotation:checked ~ .controls [for="rotation"],
#rotation-dir--clockwise:checked ~ .controls [for="rotation-dir--clockwise"],
#rotation-dir--anticlockwise:checked ~ .controls [for="rotation-dir--anticlockwise"] {
&::before {
box-shadow:
inset 0 0 0 .2em $c-bgc,
inset 0 0 0 1em;
}
}
#revolution:checked ~ .controls .controls__revolution,
#rotation:checked ~ .controls .controls__rotation {
.sub-controls {
opacity: .8;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment