Skip to content

Commit 3e5d7a7

Browse files
authored
Merge pull request #855 from VINAYMADIVAL/feature/resizable-split-panel
Add Resizable Split Panel using only HTML+CSS
2 parents cba2282 + 5349ef1 commit 3e5d7a7

File tree

4 files changed

+187
-0
lines changed

4 files changed

+187
-0
lines changed

README.md

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -94,6 +94,7 @@ Please be aware that the demos may exhibit significant accessibility issues, suc
9494
- [Retro Loader](#RetroLoader)
9595
- [Ripple Effect](#ripple-effect)
9696
- [Redar Loader](#Redar-Loader)
97+
- [Resizable Split Panel](#resizable-split-panel)
9798
- [Scary Animation](#scary-animation)
9899
- [Scenery](#scenery)
99100
- [Scroll Video Cinematic Animation](#scroll-video-cinematic)
@@ -657,6 +658,14 @@ Your browser does not support the video tag.
657658

658659
---
659660

661+
## <a id="resizable-split-panel"></a>Resizable Split Panel
662+
663+
[<img src="images/resizable_panel_demo.gif" title="Resizable Split Panel Demo">](https://codepen.io/VINAY-MADIVAL/pen/ogboooB)
664+
665+
**[⬆ back to top](#quick-links)**
666+
667+
---
668+
660669
## <a id="login"></a>A login Page with Glassmorphism Effect
661670

662671
[<img src="Login_Page/log-in-6398177_1280.png" title="Responsive Login Page with Glassmorphism Effect">]

Resizable-Split-Panel/index.html

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
<!doctype html>
2+
<html lang="en">
3+
<head>
4+
<meta charset="utf-8" />
5+
<meta name="viewport" content="width=device-width,initial-scale=1" />
6+
<title>Resizable Split Panel</title>
7+
<link rel="stylesheet" href="style.css">
8+
</head>
9+
<body>
10+
<input class="sr-only" type="radio" name="pos" id="p20" />
11+
<input class="sr-only" type="radio" name="pos" id="p40" checked />
12+
<input class="sr-only" type="radio" name="pos" id="p60" />
13+
<input class="sr-only" type="radio" name="pos" id="p80" />
14+
15+
<main class="viewport">
16+
<div class="card" role="group" aria-label="Resizable split panel (CSS only)">
17+
<div class="split">
18+
<section class="panel left" aria-label="Left panel">
19+
<h2>Left panel</h2>
20+
<p class="muted">Adjustable sidebar area</p>
21+
</section>
22+
23+
<aside class="gutter" aria-hidden="false">
24+
<div class="vertical-controls" role="toolbar" aria-label="Resize controls">
25+
<label for="p20" class="btn btn-20" tabindex="0" aria-label="Set split to 20 percent">20%</label>
26+
<label for="p40" class="btn btn-40" tabindex="0" aria-label="Set split to 40 percent">40%</label>
27+
<label for="p60" class="btn btn-60" tabindex="0" aria-label="Set split to 60 percent">60%</label>
28+
<label for="p80" class="btn btn-80" tabindex="0" aria-label="Set split to 80 percent">80%</label>
29+
</div>
30+
</aside>
31+
32+
<section class="panel right" aria-label="Right panel">
33+
<h2>Right panel</h2>
34+
<p class="muted">Main content area</p>
35+
</section>
36+
</div>
37+
38+
<p class="instructions">Click a button on the divider to resize the panels.</p>
39+
<p class="instructions">Arrow-key navigation: use ← / → (or ↑ / ↓) to change the split.</p>
40+
</main>
41+
</body>
42+
</html>

Resizable-Split-Panel/style.css

Lines changed: 136 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,136 @@
1+
:root{
2+
--gutter: 64px; /* width reserved for vertical buttons */
3+
--left: 40%;
4+
--bg: #071027;
5+
--card-bg: linear-gradient(180deg, rgba(255,255,255,0.02), rgba(255,255,255,0.01));
6+
--muted: rgba(255,255,255,0.7);
7+
}
8+
9+
/* Basic page layout */
10+
*{box-sizing:border-box}
11+
html,body{height:100%;margin:0;font-family:Inter,system-ui,-apple-system,"Segoe UI",Roboto,Arial;background:linear-gradient(180deg,#071027,#051023);color:#e6eef8}
12+
.viewport{min-height:100vh;display:flex;align-items:center;justify-content:center;padding:36px}
13+
14+
.sr-only{ position:absolute !important; width:1px; height:1px; padding:0; margin:-1px; border:0; overflow:hidden; clip:rect(0 0 0 0); white-space:nowrap; }
15+
16+
/* card container */
17+
.card{
18+
width:88%;
19+
max-width:1100px;
20+
height:62vh;
21+
min-height:420px;
22+
padding:14px;
23+
border-radius:12px;
24+
background:var(--card-bg);
25+
box-shadow: 0 14px 50px rgba(2,6,23,0.7);
26+
display:flex;
27+
flex-direction:column;
28+
gap:12px;
29+
}
30+
31+
/* split layout: left | gutter | right */
32+
.split{
33+
flex:1;
34+
display:grid;
35+
grid-template-columns: var(--left) var(--gutter) 1fr;
36+
gap:0;
37+
align-items:stretch;
38+
width:100%;
39+
height:100%;
40+
}
41+
42+
/* panels */
43+
.panel{
44+
padding:28px;
45+
border-radius:8px;
46+
overflow:auto;
47+
display:flex;
48+
flex-direction:column;
49+
gap:12px;
50+
}
51+
.left{ background: linear-gradient(180deg,#0f1724,#0b1a26) }
52+
.right{ background: linear-gradient(180deg,#08111b,#06121a) }
53+
54+
h2{ margin:0; font-size:20px; color:#dff7f3 }
55+
.muted{ color:var(--muted); margin:0; }
56+
57+
/* gutter visuals */
58+
.gutter{
59+
position:relative;
60+
display:flex;
61+
align-items:center;
62+
justify-content:center;
63+
user-select:none;
64+
-webkit-user-select:none;
65+
}
66+
67+
/* vertical control column (stack of buttons) */
68+
.vertical-controls{
69+
position:relative;
70+
display:flex;
71+
flex-direction:column;
72+
align-items:center;
73+
justify-content:center;
74+
gap:10px;
75+
height:70%;
76+
pointer-events:auto;
77+
}
78+
79+
/* button labels (styled) */
80+
.btn{
81+
display:inline-flex;
82+
align-items:center;
83+
justify-content:center;
84+
width:44px;
85+
height:36px;
86+
border-radius:8px;
87+
background:transparent;
88+
color:var(--muted);
89+
border:1px solid rgba(255,255,255,0.04);
90+
cursor:pointer;
91+
user-select:none;
92+
transition: background 120ms, transform 120ms, color 120ms;
93+
text-decoration:none;
94+
font-weight:600;
95+
font-size:13px;
96+
outline: none;
97+
}
98+
99+
/* hover / focus */
100+
.btn:hover,
101+
.btn:focus{
102+
transform: translateY(-2px);
103+
background: rgba(255,255,255,0.035);
104+
color: #fff;
105+
box-shadow: 0 6px 18px rgba(2,6,23,0.35);
106+
}
107+
108+
/* visually indicate active button using radio checked + selector */
109+
#p20:checked ~ .viewport .card .btn-20,
110+
#p40:checked ~ .viewport .card .btn-40,
111+
#p60:checked ~ .viewport .card .btn-60,
112+
#p80:checked ~ .viewport .card .btn-80{
113+
background: linear-gradient(180deg, #e6fff7, #c5fff0);
114+
color:#02121a;
115+
border-color: rgba(0,0,0,0.06);
116+
transform: translateY(-2px) scale(1.03);
117+
}
118+
119+
/* set --left based on checked radio */
120+
#p20:checked ~ .viewport .card .split { --left:20%; }
121+
#p40:checked ~ .viewport .card .split { --left:40%; }
122+
#p60:checked ~ .viewport .card .split { --left:60%; }
123+
#p80:checked ~ .viewport .card .split { --left:80%; }
124+
125+
/* default */
126+
.split { --left:40%; }
127+
128+
/* instructions */
129+
.instructions{ margin:0; font-size:13px; color:var(--muted) }
130+
131+
/* small-screen fallback: stacked panels, hide gutter controls */
132+
@media (max-width:720px){
133+
.split{ grid-template-columns: 1fr; grid-auto-rows: 1fr; }
134+
.gutter, .vertical-controls { display:none; }
135+
.card { height: auto; min-height: 60vh; }
136+
}

images/resizable_panel_demo.gif

191 KB
Loading

0 commit comments

Comments
 (0)