پیشنمایش زنده
کد HTML
<div class="combination-lock">
<div class="dial">
<div class="nonagon">
<div class="face face-0">
<input type="radio" name="wheel-1" class="radio radio-0" />
<span>0</span>
</div>
<div class="face face-1">
<input type="radio" name="wheel-1" class="radio radio-1" />
<span>1</span>
</div>
<div class="face face-2">
<input type="radio" name="wheel-1" class="radio radio-2" />
<span>2</span>
</div>
<div class="face face-3">
<input type="radio" name="wheel-1" class="radio radio-3" checked="" />
<span>3</span>
</div>
<div class="face face-4">
<input type="radio" name="wheel-1" class="radio radio-4" />
<span>4</span>
</div>
<div class="face face-5">
<input type="radio" name="wheel-1" class="radio radio-5" />
<span>5</span>
</div>
<div class="face face-6">
<input type="radio" name="wheel-1" class="radio radio-6" />
<span>6</span>
</div>
<div class="face face-7">
<input type="radio" name="wheel-1" class="radio radio-7" />
<span>7</span>
</div>
<div class="face face-8">
<input type="radio" name="wheel-1" class="radio radio-8" />
<span>8</span>
</div>
<div class="face face-9">
<input type="radio" name="wheel-1" class="radio radio-9" />
<span>9</span>
</div>
</div>
</div>
<div class="dial">
<div class="nonagon">
<div class="face face-0">
<input type="radio" name="wheel-2" class="radio radio-0" />
<span>0</span>
</div>
<div class="face face-1">
<input type="radio" name="wheel-2" class="radio radio-1" />
<span>1</span>
</div>
<div class="face face-2">
<input type="radio" name="wheel-2" class="radio radio-2" />
<span>2</span>
</div>
<div class="face face-3">
<input type="radio" name="wheel-2" class="radio radio-3" />
<span>3</span>
</div>
<div class="face face-4">
<input type="radio" name="wheel-2" class="radio radio-4" checked="" />
<span>4</span>
</div>
<div class="face face-5">
<input type="radio" name="wheel-2" class="radio radio-5" />
<span>5</span>
</div>
<div class="face face-6">
<input type="radio" name="wheel-2" class="radio radio-6" />
<span>6</span>
</div>
<div class="face face-7">
<input type="radio" name="wheel-2" class="radio radio-7" />
<span>7</span>
</div>
<div class="face face-8">
<input type="radio" name="wheel-2" class="radio radio-8" />
<span>8</span>
</div>
<div class="face face-9">
<input type="radio" name="wheel-2" class="radio radio-9" />
<span>9</span>
</div>
</div>
</div>
<div class="dial">
<div class="nonagon">
<div class="face face-0">
<input type="radio" name="wheel-3" class="radio radio-0" />
<span>0</span>
</div>
<div class="face face-1">
<input type="radio" name="wheel-3" class="radio radio-1" />
<span>1</span>
</div>
<div class="face face-2">
<input type="radio" name="wheel-3" class="radio radio-2" />
<span>2</span>
</div>
<div class="face face-3">
<input type="radio" name="wheel-3" class="radio radio-3" />
<span>3</span>
</div>
<div class="face face-4">
<input type="radio" name="wheel-3" class="radio radio-4" />
<span>4</span>
</div>
<div class="face face-5">
<input type="radio" name="wheel-3" class="radio radio-5" checked="" />
<span>5</span>
</div>
<div class="face face-6">
<input type="radio" name="wheel-3" class="radio radio-6" />
<span>6</span>
</div>
<div class="face face-7">
<input type="radio" name="wheel-3" class="radio radio-7" />
<span>7</span>
</div>
<div class="face face-8">
<input type="radio" name="wheel-3" class="radio radio-8" />
<span>8</span>
</div>
<div class="face face-9">
<input type="radio" name="wheel-3" class="radio radio-9" />
<span>9</span>
</div>
</div>
</div>
<div class="dial">
<div class="nonagon">
<div class="face face-0">
<input type="radio" name="wheel-4" class="radio radio-0" />
<span>0</span>
</div>
<div class="face face-1">
<input type="radio" name="wheel-4" class="radio radio-1" />
<span>1</span>
</div>
<div class="face face-2">
<input type="radio" name="wheel-4" class="radio radio-2" />
<span>2</span>
</div>
<div class="face face-3">
<input type="radio" name="wheel-4" class="radio radio-3" />
<span>3</span>
</div>
<div class="face face-4">
<input type="radio" name="wheel-4" class="radio radio-4" />
<span>4</span>
</div>
<div class="face face-5">
<input type="radio" name="wheel-4" class="radio radio-5" />
<span>5</span>
</div>
<div class="face face-6">
<input type="radio" name="wheel-4" class="radio radio-6" />
<span>6</span>
</div>
<div class="face face-7">
<input type="radio" name="wheel-4" class="radio radio-7" checked="" />
<span>7</span>
</div>
<div class="face face-8">
<input type="radio" name="wheel-4" class="radio radio-8" />
<span>8</span>
</div>
<div class="face face-9">
<input type="radio" name="wheel-4" class="radio radio-9" />
<span>9</span>
</div>
</div>
</div>
<div class="help">Hint: 3562</div>
<div class="light"></div>
<div class="arrow left"></div>
<div class="arrow right"></div>
</div>
کد CSS
.combination-lock {
position: relative;
display: flex;
gap: 1.075rem;
user-select: none;
}
.dial {
width: 40px;
height: 120px;
overflow: hidden;
perspective: 500px;
border-radius: 10px / 250px;
outline: solid 3px #000;
outline-offset: 1px;
filter: drop-shadow(4px 0 0px #0006) drop-shadow(8px -1px 1px #0003)
drop-shadow(8px 10px 1px #0003)
drop-shadow(12px 16px 30px rgba(177, 175, 174, 0.1))
drop-shadow(-12px -16px 36px rgba(255, 255, 255, 0.1)) contrast(1.5)
sepia(0.2);
box-shadow:
-2px -3px 0 4px #1115,
0 -3px 0 2px #fff,
0 2px 0 3px #eee,
0 4px 0 4px #0009;
}
.dial::after {
content: "";
position: absolute;
inset: 0;
background-image: radial-gradient(circle at 50% 50%, #000 40%, 40.5%, #fff0),
linear-gradient(to bottom, #fff, 50%, #111);
background-position:
0 16px,
0 0;
background-repeat: no-repeat;
mix-blend-mode: soft-light;
pointer-events: none;
}
.nonagon {
width: 100%;
height: 100%;
position: relative;
top: 36px;
transform-style: preserve-3d;
transform-origin: 0 24px;
transform: rotateX(0deg);
transition: transform 300ms ease;
}
.face {
position: absolute;
display: grid;
place-items: center;
width: 40px;
height: 47px;
background-color: #c4c2bd;
box-shadow:
0 -3px 1px 2px #000a,
0 0px 1px 3px #fffa;
font-family: "Lucida Console", Courier, monospace;
font-size: 1.75em;
font-weight: bold;
text-shadow:
1px 1px 0.5px #fff,
-1px -1px 0.5px #ccc,
-0.5px -0.5px 0.5px #0005;
color: rgba(65, 58, 36, 0.9);
-webkit-text-stroke: 01px #aaa6;
}
.face::before,
.face::after {
content: "";
position: absolute;
height: 100%;
width: 4px;
border: 0.5px solid #0005;
}
.face::before {
left: 0;
background-color: #fff;
}
.face::after {
right: 0;
background-color: #0004;
}
.face span {
position: absolute;
pointer-events: none;
}
.face .radio {
position: absolute;
width: 100%;
height: 100%;
cursor: pointer;
appearance: none;
opacity: 0.5;
z-index: 0;
}
.nonagon:has(.radio-0:checked) {
transform: rotateX(0deg);
}
.nonagon:has(.radio-1:checked) {
transform: rotateX(36deg);
}
.nonagon:has(.radio-2:checked) {
transform: rotateX(72deg);
}
.nonagon:has(.radio-3:checked) {
transform: rotateX(108deg);
}
.nonagon:has(.radio-4:checked) {
transform: rotateX(144deg);
}
.nonagon:has(.radio-5:checked) {
transform: rotateX(180deg);
}
.nonagon:has(.radio-6:checked) {
transform: rotateX(216deg);
}
.nonagon:has(.radio-7:checked) {
transform: rotateX(252deg);
}
.nonagon:has(.radio-8:checked) {
transform: rotateX(288deg);
}
.nonagon:has(.radio-9:checked) {
transform: rotateX(324deg);
}
.face-0 {
transform: rotateX(0deg) translateZ(71px);
}
.face-1 {
transform: rotateX(-36deg) translateZ(71px);
}
.face-2 {
transform: rotateX(-72deg) translateZ(71px);
}
.face-3 {
transform: rotateX(-108deg) translateZ(71px);
}
.face-4 {
transform: rotateX(-144deg) translateZ(71px);
}
.face-5 {
transform: rotateX(-180deg) translateZ(71px);
}
.face-6 {
transform: rotateX(-216deg) translateZ(71px);
}
.face-7 {
transform: rotateX(-252deg) translateZ(71px);
}
.face-8 {
transform: rotateX(-288deg) translateZ(71px);
}
.face-9 {
transform: rotateX(-324deg) translateZ(71px);
}
.help {
position: absolute;
width: 100%;
transform: translateY(-50px);
text-align: center;
bottom: -40;
text-wrap: nowrap;
font-family: "Gill Sans", "Gill Sans MT", Calibri, "Trebuchet MS", sans-serif;
font-weight: light;
font-size: 1em;
font-style: italic;
color: rgba(240, 225, 211, 0.467);
}
/* password check */
.combination-lock:has(.dial:nth-child(1) .radio-3:checked):has(
.dial:nth-child(2) .radio-5:checked
):has(.dial:nth-child(3) .radio-6:checked):has(
.dial:nth-child(4) .radio-2:checked
)
.light {
color: rgb(150, 255, 179);
}
.light {
position: absolute;
left: 50%;
width: 16px;
height: 16px;
bottom: -48px;
transform: translateX(-8px);
color: rgb(248, 60, 40);
background-color: currentColor;
background-image: radial-gradient(circle at 50% 40%, #fff6 1px, currentColor);
border-radius: 50%;
border: 3px dotted #fff5;
outline: 3px solid #0003;
transition:
background-color 400ms ease,
color 400ms ease;
box-shadow:
1px 1px 2px 1px #0005 inset,
-1px -1px 2px 1px #0005 inset,
0 0 2px 1px currentColor,
0 0 16px 0px currentColor,
0 0 24px 3px currentColor,
0 0 48px 8px rgba(255, 231, 201, 1);
filter: drop-shadow(2px 0 0px #0006) drop-shadow(3px 6px 1px #0004)
drop-shadow(12px 16px 32px rgba(255, 231, 201, 0.5))
drop-shadow(-12px -16px 64px rgba(255, 231, 201, 0.5)) contrast(1.1)
brightness(1.3);
}
.arrow {
position: absolute;
width: 0;
height: 0;
filter: drop-shadow(0 0 4px #0009);
top: calc(50% - 14px);
z-index: -1;
}
.arrow.left {
border-top: 12px solid transparent;
border-bottom: 12px solid transparent;
border-left: 12px solid rgba(255, 91, 72, 0.6);
left: -26px;
}
.arrow.right {
border-top: 12px solid transparent;
border-bottom: 12px solid transparent;
border-right: 12px solid rgba(255, 91, 72, 0.6);
right: -26px;
}