- const randomInRange = (min, max) => Math.floor(Math.random() * (max - min + 1)) + min
- const hue = randomInRange(0, 360)
label(for='toggle') Turn shading off
input#toggle(type='checkbox')
.cauldron(style=`--potion-hue: ${hue}`)
.cauldron__opening
- let b = 0
while b < 25
- const speed = randomInRange(5, 10)
- const scale = randomInRange(50, 150) / 100
- const delay = randomInRange(0, 10)
- const x = randomInRange(25, 75)
.cauldron__bubble(style=`--delay: ${delay}; --scale: ${scale}; --speed: ${speed}; --x: ${x}`)
- b++
.cauldron__handle.cauldron__handle--left
.cauldron__handle.cauldron__handle--right
.cauldron__foot.cauldron__foot--left
.cauldron__foot.cauldron__foot--right
.cauldron__eye.cauldron__eye--left
.cauldron__eye.cauldron__eye--right
.cauldron__mouth
View Compiled
*
box-sizing border-box
transition background .15s ease, box-shadow .15s ease
:root
--cauldron-hue 34
--potion-hue 120
--size 200
--bg #111
label
font-weight bold
color hsl(0, 0%, 99%)
margin-bottom 0.5rem
[type='checkbox']
margin-bottom 2rem
:checked ~ .cauldron
background var(--cauldron-color)
.cauldron__opening
background var(--potion-color)
box-shadow none
&:after
&:before
background var(--potion-color)
box-shadow none
&:before
background transparent
.cauldron__handle
background var(--rim-color)
.cauldron__eye
box-shadow none
.cauldron__mouth
box-shadow none
.cauldron__foot
background var(--inner-rim-color)
.cauldron__bubble
background var(--potion-color)
body
align-items center
display flex
justify-content center
min-height 100vh
background var(--bg)
flex-direction column
.cauldron
--rim-color 'hsl(%s, 100%, 60%)' % (var(--cauldron-hue))
--inner-rim-color 'hsl(%s, 100%, 25%)' % (var(--cauldron-hue))
--potion-color 'hsl(%s, 100%, 50%)' % (var(--potion-hue))
--cauldron-color 'hsl(%s, 100%, 50%)' % (var(--cauldron-hue))
--darkness 'hsl(%s, 100%, 10%)' % (var(--cauldron-hue))
--lightness 'hsl(%s, 100%, 85%)' % (var(--cauldron-hue))
--potion-stain-light 'hsl(%s, 100%, 70%)' % (var(--potion-hue))
--potion-stain-dark 'hsl(%s, 100%, 30%)' % (var(--potion-hue))
border-radius 100%
height calc(var(--size) * 1px)
width calc(var(--size) * 1px)
background radial-gradient(25% 25% at 25% 55%, var(--rim-color), transparent), radial-gradient(100% 100% at -2% 50%, transparent, transparent 92%, var(--cauldron-color)), radial-gradient(100% 100% at -5% 50%, transparent, transparent 80%, var(--darkness)), linear-gradient(310deg, var(--inner-rim-color) 25%, transparent), var(--cauldron-color)
position relative
&__opening
width 100%
position absolute
top 0
left 0
height 35%
background linear-gradient(90deg, transparent, var(--potion-stain-dark)), var(--potion-color)
border calc(var(--size) * 0.05px) solid var(--rim-color)
box-shadow 0 0px calc(var(--size) * 0.05px) calc(var(--size) * 0.005px) var(--rim-color) inset,
0 calc(var(--size) * 0.025px) 0 calc(var(--size) * 0.025px) var(--inner-rim-color) inset,
0 10px 20px 0px var(--darkness),
0 10px 20px -10px var(--inner-rim-color)
border-radius 100%
&:after
content ''
position absolute
background linear-gradient(90deg, transparent, var(--potion-stain-dark), transparent, var(--potion-stain-light), transparent, var(--potion-stain-dark), transparent)
border-radius 100%
top 8px
right 0
bottom 4px
left 0
&:before
content ''
position absolute
box-shadow 0 0 calc(var(--size) * 0.025px) 0 var(--darkness) inset,
0 -1px calc(var(--size) * 0.015px) 0px var(--darkness) inset,
0 2px calc(var(--size) * 0.015px) 0px var(--lightness) inset,
0 0 calc(var(--size) * 0.075px) calc(var(--size) * 0.05px) var(--rim-color) inset
border-radius 100%
top calc(var(--size) * -0.05px)
right calc(var(--size) * -0.05px)
bottom calc(var(--size) * -0.05px)
left calc(var(--size) * -0.05px)
&__handle
height calc(var(--size) * 0.3px)
width calc(var(--size) * 0.3px)
position absolute
// border calc(var(--size) * 0.075px) solid var(--rim-color)
background linear-gradient(0deg, var(--darkness), transparent), radial-gradient(100% 100% at 50% 50%, var(--inner-rim-color), transparent), var(--rim-color)
border-radius 100%
top 30%
z-index -1
&:after
content ''
background var(--bg)
height 50%
width 50%
position absolute
top 50%
left 50%
transform translate(-50%, -50%)
border-radius 100%
&--left
left -14%
&--right
right -14%
&__foot
background var(--inner-rim-color)
position absolute
z-index -1
height calc(var(--size) * 0.3px)
width calc(var(--size) * 0.3px)
bottom -5%
border-radius 200% 0 200% 50%/200% 0 200% 50%
&--left
left 10%
background radial-gradient(110% 110% at 25% 50%, transparent, var(--darkness) 75%), var(--inner-rim-color)
&--right
right 10%
background radial-gradient(110% 110% at 25% 50%, transparent, var(--darkness)), var(--inner-rim-color)
transform rotateY(180deg)
&__bubble
height calc(var(--size) * .2px)
width calc(var(--size) * .2px)
position absolute
border-radius 100%
top 0
left calc(var(--x) * 1%)
border 1px solid var(--potion-stain-light)
background radial-gradient(100% 115% at 25% 25%, #fff, transparent 33%), radial-gradient(15% 15% at 75% 75%, var(--cauldron-color), transparent), radial-gradient(100% 100% at 50% 25%, transparent, var(--potion-color) 98%)
pointer-events none
animation rise calc(var(--speed) * 1s) calc(var(--delay) * -1s) infinite ease
&__mouth
position absolute
top 60%
left 50%
transform translate(-50%, 0)
height calc(var(--size) * .1px)
width calc(var(--size) * .15px)
border-radius 100%
border-bottom 4px solid black
box-shadow 0px 1px 0 0 var(--lightness)
-webkit-clip-path inset(50% 0 -10% 0)
clip-path inset(50% 0 -10% 0)
&__eye
height calc(var(--size) * .075px)
width calc(var(--size) * .075px)
background #111
border-radius 100%
position absolute
top 50%
box-shadow 1px 1px 1px 0px var(--lightness), -1px -1px 1px 0 var(--inner-rim-color)
animation blink 4s infinite linear both
&--left
left 20%
&--right
right 20%
@keyframes rise
0%
transform scale(0) translate(-50%, 0)
100%
transform scale(var(--scale)) translate(-50%, -50vh)
opacity 0
@keyframes blink
9%
transform scaleY(1)
10%
transform scaleY(0)
11%
transform scaleY(1)
12%
transform scaleY(0)
13%
transform scaleY(1)
View Compiled
/**
* I take no credit for the brilliant work of Gal Shir:
* https://dribbble.com/shots/7664202-Cauldron
* This is purely a recreation with CSS to practice lighting etc.
*/
View Compiled
This Pen doesn't use any external CSS resources.
This Pen doesn't use any external JavaScript resources.