mixin cuboid(className)
.cuboid(class=className)
- let s = 0
while s < 6
.cuboid__side
- s++
.scene
.plane
.book
+cuboid('book__cover book__cover--front')
+cuboid('book__cover book__cover--rear')
+cuboid('book__spine')
.cuboid.book__spine
.cuboid__side
.cuboid__side
.cuboid__side
.cuboid__side
.avatar__holder
img(src="https://assets.codepen.io/605876/avatar.png")
.cuboid__side
.cuboid__side
+cuboid('book__pages')
View Compiled
*
box-sizing border-box
:root
--primary hsl(165, 67%, 43%)
--secondary hsl(175, 85%, 28%)
--tertiary hsl(165, 67%, 38%)
--exploded 1
--start-x -32
--start-y -42
body
min-height 100vh
display flex
align-items center
justify-content center
overflow hidden
background hsl(245, 50%, 15%)
.scene
perspective 800px
transform-style preserve-3d
height 100vh
width 100vw
display flex
align-items center
justify-content center
.plane
height 2vmin
width 14.8vmin
transform-style preserve-3d
// transform rotateX(-24deg) rotateY(-24deg) rotateX(90deg)
transform scale(var(--scale, 2)) rotateX(calc(var(--start-x) * 1deg)) rotateY(calc(var(--start-y) * 1deg)) rotateX(90deg) rotateX(calc(var(--x, 0) * 1deg)) rotateY(calc(var(--y, 0) * 1deg)) rotateZ(calc(var(--z, 0) * 1deg))
animation spin 2s infinite linear var(--state, paused)
@keyframes spin
from
transform scale(var(--scale, 2)) rotateX(calc(var(--start-x) * 1deg)) rotateY(calc(var(--start-y) * 1deg)) rotateX(90deg) rotateX(calc(var(--x, 0) * 1deg)) rotateY(calc(var(--y, 0) * 1deg)) rotateZ(calc(var(--z, 0) * 1deg))
to
transform scale(var(--scale, 2)) rotateX(calc(var(--start-x) * 1deg)) rotateY(calc(var(--start-y) * 1deg)) rotateX(90deg) rotateX(calc(var(--x, 0) * 1deg)) rotateY(calc(var(--y, 0) * 1deg)) rotateZ(calc(var(--z, 0) * 1deg)) rotateX(360deg) rotateY(360deg) rotateZ(360deg)
.cuboid
--width 15
--height 10
--depth 4
height calc(var(--depth) * 1vmin)
width calc(var(--width) * 1vmin)
transform-style preserve-3d
position absolute
font-size 1rem
transform translate3d(0, 0, 5vmin)
& > div:nth-of-type(1)
height calc(var(--height) * 1vmin)
width 100%
transform-origin 50% 50%
transform rotateX(-90deg)
position absolute
top 50%
left 50%
transform translate(-50%, -50%) rotateX(-90deg) translate3d(0, 0, calc((var(--depth) / 2) * 1vmin))
& > div:nth-of-type(2)
height calc(var(--height) * 1vmin)
width 100%
transform-origin 50% 50%
transform translate(-50%, -50%) rotateX(-90deg) rotateY(180deg) translate3d(0, 0, calc((var(--depth) / 2) * 1vmin))
position absolute
top 50%
left 50%
& > div:nth-of-type(3)
height calc(var(--height) * 1vmin)
width calc(var(--depth) * 1vmin)
transform translate(-50%, -50%) rotateX(-90deg) rotateY(90deg) translate3d(0, 0, calc((var(--width) / 2) * 1vmin))
position absolute
top 50%
left 50%
& > div:nth-of-type(4)
height calc(var(--height) * 1vmin)
width calc(var(--depth) * 1vmin)
transform translate(-50%, -50%) rotateX(-90deg) rotateY(-90deg) translate3d(0, 0, calc((var(--width) / 2) * 1vmin))
position absolute
top 50%
left 50%
& > div:nth-of-type(5)
height calc(var(--depth) * 1vmin)
width calc(var(--width) * 1vmin)
transform translate(-50%, -50%) translate3d(0, 0, calc((var(--height) / 2) * 1vmin))
position absolute
top 50%
left 50%
& > div:nth-of-type(6)
height calc(var(--depth) * 1vmin)
width calc(var(--width) * 1vmin)
transform translate(-50%, -50%) translate3d(0, 0, calc((var(--height) / 2) * -1vmin)) rotateX(180deg)
position absolute
top 50%
left 50%
.book
div
transition transform 0.25s
&__cover
--height 21
--width 14.8
--depth 0.2
top 50%
left 50%
div
background-color var(--primary)
background-size cover
&--front
transform translate3d(-50%, calc(((var(--exploded) * 5) + 1.1) * 1vmin), 0)
div:nth-of-type(1)
background-image url('https://assets.codepen.io/605876/How+to+Move+Things+with+CSS+-+Cover.png')
&--rear
transform translate3d(-50%, calc(((var(--exploded) * -5) - 1.1) * 1vmin), 0)
div:nth-of-type(2)
background-image url('https://assets.codepen.io/605876/How+to+Move+Things+with+CSS+-+Rear.png')
div:nth-of-type(3)
div:nth-of-type(4)
background-image linear-gradient(var(--tertiary) 80.1%, var(--secondary) 80.1%)
div:nth-of-type(6)
background-color var(--secondary)
&__pages
--height 20.5
--width 14.4
--depth 2
top 50%
left 50%
transform translate3d(-50%, -50%, 0)
div
&:nth-of-type(3)
&:nth-of-type(4)
background repeating-linear-gradient(90deg, hsl(0, 0%, 70%) 1px 2px, transparent 2px 4px), hsl(0, 0%, 95%)
&:nth-of-type(5)
&:nth-of-type(6)
background repeating-linear-gradient(0deg, hsl(0, 0%, 70%) 1px 2px, transparent 2px 4px), hsl(0, 0%, 95%)
&__spine
--height 21
--depth 2.2
--width 0.1
left 0
top 50%
transform translate3d(calc((var(--exploded) * 5) * -1vmin), -50%, 0)
div:not(.avatar__holder)
background var(--tertiary)
&:nth-of-type(4)
background linear-gradient(var(--tertiary) 80.1%, var(--secondary) 80.1%)
.avatar__holder
width 1.5vmin
height 1.5vmin
border-radius 50%
background-color hsl(0, 0%, 100%)
position absolute
top 90%
left 50%
transform translate(-50%, -50%)
display flex
align-items center
justify-content center
img
height 75%
View Compiled
const {
dat: { GUI },
} = window
const CONFIG = {
x: 0,
y: 0,
z: 0,
spin: false,
scale: 2,
exploded: true,
}
const UPDATE = () => {
document.documentElement.style.setProperty('--x', CONFIG.x)
document.documentElement.style.setProperty('--y', CONFIG.y)
document.documentElement.style.setProperty('--z', CONFIG.z)
document.documentElement.style.setProperty('--scale', CONFIG.scale)
document.documentElement.style.setProperty(
'--state',
CONFIG.spin ? 'running' : 'paused'
)
document.documentElement.style.setProperty(
'--exploded',
CONFIG.exploded ? 1 : 0
)
}
const CONTROLLER = new GUI()
const ROTATION = CONTROLLER.addFolder('Rotate')
ROTATION.add(CONFIG, 'x', 0, 360, 1)
.name('X')
.onChange(UPDATE)
ROTATION.add(CONFIG, 'y', 0, 360, 1)
.name('Y')
.onChange(UPDATE)
ROTATION.add(CONFIG, 'z', 0, 360, 1)
.name('Z')
.onChange(UPDATE)
CONTROLLER.add(CONFIG, 'exploded')
.name('Exploded')
.onChange(UPDATE)
CONTROLLER.add(CONFIG, 'spin')
.name('Spin')
.onChange(UPDATE)
CONTROLLER.add(CONFIG, 'scale', 0.5, 5, 0.1)
.name('Scale')
.onChange(UPDATE)
View Compiled
This Pen doesn't use any external CSS resources.