Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
138 changes: 138 additions & 0 deletions 3D Triangle/triangle-3d.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,138 @@
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width,initial-scale=1" />
<title>3D Triangle (CSS only)</title>
<style>
:root{
--size: 260px; /* width of triangle */
--depth: 48px; /* extrusion depth */
--bg: #071029;
--face: #06b6d4;
--face-2: #038aa6;
--shadow: rgba(2,6,23,0.6);
}

html,body{
height:100%;
margin:0;
font-family: system-ui, Arial;
background: linear-gradient(180deg, #03243a 0%, var(--bg) 100%);
display:grid;
place-items:center;
color:#fff;
}

.stage{
perspective: 900px;
}

/* container that preserves 3D children */
.prism {
width: var(--size);
height: calc(var(--size) * 0.86); /* approx triangle height */
position: relative;
transform-style: preserve-3d;
transform: rotateX(16deg) rotateY(-16deg);
transition: transform .45s cubic-bezier(.2,.9,.2,1);
filter: drop-shadow(0 18px 30px var(--shadow));
}

.stage:hover .prism{
transform: rotateX(6deg) rotateY(18deg) translateZ(8px);
}

/* front & back triangular faces */
.face {
position: absolute;
inset: 0;
width: 100%;
height: 100%;
-webkit-clip-path: polygon(50% 0%, 0% 100%, 100% 100%);
clip-path: polygon(50% 0%, 0% 100%, 100% 100%);
backface-visibility: hidden;
}

.face.front {
background: linear-gradient(180deg, var(--face) 0%, var(--face-2) 100%);
transform: translateZ(calc(var(--depth) / 2));
box-shadow: 0 6px 18px rgba(3,12,30,.45) inset;
}

.face.back {
background: linear-gradient(180deg, var(--face-2) 0%, var(--face) 100%);
transform: rotateY(180deg) translateZ(calc(var(--depth) / 2));
opacity: 0.96;
}

/* side panels: three trapezoids connecting front & back */
.side {
position: absolute;
width: 100%;
height: 100%;
transform-origin: center;
backface-visibility: hidden;
}

/* left side panel */
.side.left {
/* create a quadrilateral covering left edge */
-webkit-clip-path: polygon(50% 0%, 0% 100%, 0% 100%, 50% 0%);
clip-path: polygon(50% 0%, 0% 100%, 0% 100%, 50% 0%);
background: linear-gradient(90deg, rgba(0,0,0,.12), rgba(0,0,0,0));
transform: rotateY(90deg) translateX(calc(var(--size) / -2)) translateZ(calc(var(--depth) / -2));
opacity: 0.95;
}

/* right side panel */
.side.right {
-webkit-clip-path: polygon(50% 0%, 100% 100%, 100% 100%, 50% 0%);
clip-path: polygon(50% 0%, 100% 100%, 100% 100%, 50% 0%);
background: linear-gradient(90deg, rgba(0,0,0,0), rgba(0,0,0,.12));
transform: rotateY(-90deg) translateX(calc(var(--size) / 2)) translateZ(calc(var(--depth) / -2));
opacity: 0.95;
}

/* bottom side panel (base thickness) */
.side.bottom {
/* a thin band along base */
-webkit-clip-path: polygon(0% 100%, 50% 100%, 100% 100%, 100% 100%);
clip-path: polygon(0% 100%, 50% 100%, 100% 100%, 100% 100%);
background: linear-gradient(180deg, rgba(0,0,0,.12), rgba(255,255,255,0.02));
transform: rotateX(90deg) translateY(calc(var(--size) * 0.43)) translateZ(calc(var(--depth) / -2));
height: calc(var(--depth));
top: auto;
bottom: -1px;
}

/* simple label */
.label {
margin-top: 18px;
text-align: center;
font-size: 14px;
opacity: .85;
}

/* small responsive tweak */
@media (max-width:520px){
:root{ --size: 200px; --depth: 36px; }
}
</style>
</head>
<body>
<div class="stage">
<div class="prism" aria-hidden="true">
<div class="face front"></div>
<div class="face back"></div>

<!-- side panels: visual depth only -->
<div class="side left"></div>
<div class="side right"></div>
<div class="side bottom"></div>
</div>

<div class="label">Pure HTML & CSS — 3D triangle (extruded)</div>
</div>
</body>
</html>