Skip to content

Commit 705a5d7

Browse files
committed
fix: prevent layout shifting caused by scrollbar
1 parent ad00932 commit 705a5d7

File tree

2 files changed

+175
-147
lines changed

2 files changed

+175
-147
lines changed

templates/index.ejs

Lines changed: 88 additions & 74 deletions
Original file line numberDiff line numberDiff line change
@@ -13,79 +13,81 @@
1313
<title>Contents of /<%= directory.fullname %></title>
1414
</head>
1515
<body>
16-
<div class="container">
17-
<h1>Contents of
18-
<div>
19-
<span class="heading-textbg">/<%= directory.fullname %></span>
20-
<span class="heading-text">/<%= directory.fullname %></span>
21-
</div>
22-
</h1>
23-
24-
<nav class="hide-when-mobile">
25-
<ul>
26-
<li><a href="/">🌱</a></li>
27-
<% for (const pathSlice of directory.pathSlices) { %>
28-
<% const currentPath = pathSlice.split('/')[pathSlice.split('/').length - 1] %>
29-
30-
<li class="div">/</li>
31-
<li><a href="/<%= pathSlice %>/index.html"><%= currentPath %></a></li>
32-
<% } %>
33-
</ul>
34-
</nav>
35-
36-
<table>
37-
<thead>
38-
<tr>
39-
<td></td>
40-
<td>name</td>
41-
<td class="hide-when-mobile"><div>type</div></td>
42-
<td class="hide-when-mobile-xs"><div>size</div></td>
43-
<td class="hide-when-mobile"><div>modified</div></td>
44-
</tr>
45-
</thead>
46-
<tbody>
47-
<tr>
48-
<td>📁</td>
49-
<td class="nav-col"><div><a href="./index.html">.</a></div></td>
50-
<td class="hide-when-mobile"><div>DIR</div></td>
51-
<td class="hide-when-mobile-xs"><div>-</div></td>
52-
<td class="hide-when-mobile"><div>-</div></td>
53-
</tr>
54-
<tr>
55-
<td>📁</td>
56-
<td class="nav-col"><div><a href="../index.html">..</a></div></td>
57-
<td class="hide-when-mobile"><div>DIR</div></td>
58-
<td class="hide-when-mobile-xs"><div>-</div></td>
59-
<td class="hide-when-mobile"><div>-</div></td>
60-
</tr>
61-
<% for (const childDirectory of directory.directories.values()) { %>
16+
<div class="outer-container">
17+
<div class="container">
18+
<h1>Contents of
19+
<div>
20+
<span class="heading-textbg">/<%= directory.fullname %></span>
21+
<span class="heading-text">/<%= directory.fullname %></span>
22+
</div>
23+
</h1>
24+
25+
<nav class="hide-when-mobile">
26+
<ul>
27+
<li><a href="/">🌱</a></li>
28+
<% for (const pathSlice of directory.pathSlices) { %>
29+
<% const currentPath = pathSlice.split('/')[pathSlice.split('/').length - 1] %>
30+
31+
<li class="div">/</li>
32+
<li><a href="/<%= pathSlice %>/index.html"><%= currentPath %></a></li>
33+
<% } %>
34+
</ul>
35+
</nav>
36+
37+
<table>
38+
<thead>
39+
<tr>
40+
<td></td>
41+
<td>name</td>
42+
<td class="hide-when-mobile"><div>type</div></td>
43+
<td class="hide-when-mobile-xs"><div>size</div></td>
44+
<td class="hide-when-mobile"><div>modified</div></td>
45+
</tr>
46+
</thead>
47+
<tbody>
6248
<tr>
63-
<td>📂</td>
64-
<td class="nav-col"><div><a href="/<%= childDirectory.fullname %>/index.html"><%= childDirectory.name %>/</a></div></td>
49+
<td>📁</td>
50+
<td class="nav-col"><div><a href="./index.html">.</a></div></td>
6551
<td class="hide-when-mobile"><div>DIR</div></td>
6652
<td class="hide-when-mobile-xs"><div>-</div></td>
6753
<td class="hide-when-mobile"><div>-</div></td>
6854
</tr>
69-
<% } %>
70-
<% for (const file of directory.files.values()) { %>
7155
<tr>
72-
<td>📄</td>
73-
<% if (file.viewerAvailable) { %>
74-
<td class="nav-col"><div><a href="/<%= file.fullname %>/viewer.html"><%= file.name %></a></div></td>
75-
<% } else { %>
76-
<td class="nav-col"><div><a href="/<%= file.fullname %>"><%= file.name %></a></div></td>
77-
<% } %>
78-
<td class="hide-when-mobile"><div><%= file.contentType %></div></td>
79-
<td class="hide-when-mobile-xs"><div><%= file.size %></div></td>
80-
<td class="hide-when-mobile"><div><%= file.lastModified %></div></td>
56+
<td>📁</td>
57+
<td class="nav-col"><div><a href="../index.html">..</a></div></td>
58+
<td class="hide-when-mobile"><div>DIR</div></td>
59+
<td class="hide-when-mobile-xs"><div>-</div></td>
60+
<td class="hide-when-mobile"><div>-</div></td>
8161
</tr>
82-
<% } %>
83-
</tbody>
84-
</table>
62+
<% for (const childDirectory of directory.directories.values()) { %>
63+
<tr>
64+
<td>📂</td>
65+
<td class="nav-col"><div><a href="/<%= childDirectory.fullname %>/index.html"><%= childDirectory.name %>/</a></div></td>
66+
<td class="hide-when-mobile"><div>DIR</div></td>
67+
<td class="hide-when-mobile-xs"><div>-</div></td>
68+
<td class="hide-when-mobile"><div>-</div></td>
69+
</tr>
70+
<% } %>
71+
<% for (const file of directory.files.values()) { %>
72+
<tr>
73+
<td>📄</td>
74+
<% if (file.viewerAvailable) { %>
75+
<td class="nav-col"><div><a href="/<%= file.fullname %>/viewer.html"><%= file.name %></a></div></td>
76+
<% } else { %>
77+
<td class="nav-col"><div><a href="/<%= file.fullname %>"><%= file.name %></a></div></td>
78+
<% } %>
79+
<td class="hide-when-mobile"><div><%= file.contentType %></div></td>
80+
<td class="hide-when-mobile-xs"><div><%= file.size %></div></td>
81+
<td class="hide-when-mobile"><div><%= file.lastModified %></div></td>
82+
</tr>
83+
<% } %>
84+
</tbody>
85+
</table>
86+
</div>
8587
</div>
86-
87-
<img id="niko" src="/_/Niko_origin.webp" alt="Niko the Cat">
8888

89+
<img id="niko" src="/_/Niko_origin.webp" alt="Niko the Cat">
90+
8991
<style>
9092
:root {
9193
--bg-color: #f5f7fa;
@@ -103,15 +105,35 @@
103105
margin: 0;
104106
padding: 0;
105107
}
108+
109+
html, body {
110+
width: 100%;
111+
height: 100%;
112+
overflow-x: hidden;
113+
background-color: var(--bg-color);
114+
}
106115
107-
body {
116+
.outer-container {
108117
font-family: "JetBrains Mono", "Noto Emoji", monospace;
109118
font-optical-sizing: auto;
110119
111-
background: var(--bg-color);
112120
color: var(--text-color);
113121
line-height: 1.6;
114122
padding: 20px;
123+
height: 100%;
124+
125+
overflow: auto;
126+
scrollbar-gutter: stable;
127+
scrollbar-width: thin;
128+
scrollbar-color: var(--primary-color) transparent;
129+
}
130+
131+
.container {
132+
position: relative;
133+
z-index: 10;
134+
display: flex;
135+
flex-direction: column;
136+
gap: 1.5rem;
115137
}
116138
117139
h1 {
@@ -272,14 +294,6 @@
272294
}
273295
}
274296
275-
.container {
276-
position: relative;
277-
z-index: 10;
278-
display: flex;
279-
flex-direction: column;
280-
gap: 1.5rem;
281-
}
282-
283297
#niko {
284298
position: fixed;
285299
z-index: 0;

templates/viewer.ejs

Lines changed: 87 additions & 73 deletions
Original file line numberDiff line numberDiff line change
@@ -13,75 +13,77 @@
1313
<title>Preview of <%= file.fullname %></title>
1414
</head>
1515
<body>
16-
<div class="container">
17-
<h1>Preview of
18-
<div>
19-
<span class="heading-textbg">/<%= file.fullname %></span>
20-
<span class="heading-text">/<%= file.fullname %></span>
21-
</div>
22-
</h1>
16+
<div class="outer-container">
17+
<div class="container">
18+
<h1>Preview of
19+
<div>
20+
<span class="heading-textbg">/<%= file.fullname %></span>
21+
<span class="heading-text">/<%= file.fullname %></span>
22+
</div>
23+
</h1>
2324

24-
<nav>
25-
<ul>
26-
<li><a href="/<%= file.fullname %>">View Original</a></li>
27-
<li><a href="/<%= file.fullname %>" download>Download</a></li>
25+
<nav>
26+
<ul>
27+
<li><a href="/<%= file.fullname %>">View Original</a></li>
28+
<li><a href="/<%= file.fullname %>" download>Download</a></li>
2829

29-
<% if (file.mediaType !== 'audio') { %>
30-
<li class="div hide-when-mobile">/</li>
31-
<li class="hide-when-mobile"><a href="javascript:" onclick="document.getElementById('media').style.width='auto'">Original Size</a></li>
32-
<li class="hide-when-mobile"><a href="javascript:" onclick="document.getElementById('media').style.width='100%'">w=full</a></li>
33-
<li class="hide-when-mobile"><a href="javascript:" onclick="document.getElementById('media').style.width='60%'">w=60%</a></li>
34-
<li class="hide-when-mobile"><a href="javascript:" onclick="document.getElementById('media').style.width='30%'">w=30%</a></li>
35-
<% } %>
36-
</ul>
37-
</nav>
30+
<% if (file.mediaType !== 'audio') { %>
31+
<li class="div hide-when-mobile">/</li>
32+
<li class="hide-when-mobile"><a href="javascript:" onclick="document.getElementById('media').style.width='auto'">Original Size</a></li>
33+
<li class="hide-when-mobile"><a href="javascript:" onclick="document.getElementById('media').style.width='100%'">w=full</a></li>
34+
<li class="hide-when-mobile"><a href="javascript:" onclick="document.getElementById('media').style.width='60%'">w=60%</a></li>
35+
<li class="hide-when-mobile"><a href="javascript:" onclick="document.getElementById('media').style.width='30%'">w=30%</a></li>
36+
<% } %>
37+
</ul>
38+
</nav>
3839

39-
<table>
40-
<thead>
41-
<tr>
42-
<td></td>
43-
<td>name</td>
44-
<td class="hide-when-mobile"><div>type</div></td>
45-
<td class="hide-when-mobile-xs"><div>size</div></td>
46-
<td class="hide-when-mobile"><div>modified</div></td>
47-
</tr>
48-
</thead>
49-
<tbody>
50-
<tr>
51-
<td>📁</td>
52-
<td class="nav-col"><div><a href="./viewer.html">.</a></div></td>
53-
<td class="hide-when-mobile"><div>DIR</div></td>
54-
<td class="hide-when-mobile-xs"><div>-</div></td>
55-
<td class="hide-when-mobile"><div>-</div></td>
56-
</tr>
57-
<tr>
58-
<td>📁</td>
59-
<td class="nav-col"><div><a href="../index.html">..</a></div></td>
60-
<td class="hide-when-mobile"><div>DIR</div></td>
61-
<td class="hide-when-mobile-xs"><div>-</div></td>
62-
<td class="hide-when-mobile"><div>-</div></td>
63-
</tr>
64-
<tr>
65-
<td>📄</td>
66-
<td><%= file.name %></td>
67-
<td class="hide-when-mobile"><div><%= file.contentType %></div></td>
68-
<td class="hide-when-mobile-xs"><div><%= file.size %></div></td>
69-
<td class="hide-when-mobile"><div><%= file.lastModified %></div></td>
70-
</tr>
71-
</tbody>
72-
</table>
40+
<table>
41+
<thead>
42+
<tr>
43+
<td></td>
44+
<td>name</td>
45+
<td class="hide-when-mobile"><div>type</div></td>
46+
<td class="hide-when-mobile-xs"><div>size</div></td>
47+
<td class="hide-when-mobile"><div>modified</div></td>
48+
</tr>
49+
</thead>
50+
<tbody>
51+
<tr>
52+
<td>📁</td>
53+
<td class="nav-col"><div><a href="./viewer.html">.</a></div></td>
54+
<td class="hide-when-mobile"><div>DIR</div></td>
55+
<td class="hide-when-mobile-xs"><div>-</div></td>
56+
<td class="hide-when-mobile"><div>-</div></td>
57+
</tr>
58+
<tr>
59+
<td>📁</td>
60+
<td class="nav-col"><div><a href="../index.html">..</a></div></td>
61+
<td class="hide-when-mobile"><div>DIR</div></td>
62+
<td class="hide-when-mobile-xs"><div>-</div></td>
63+
<td class="hide-when-mobile"><div>-</div></td>
64+
</tr>
65+
<tr>
66+
<td>📄</td>
67+
<td><%= file.name %></td>
68+
<td class="hide-when-mobile"><div><%= file.contentType %></div></td>
69+
<td class="hide-when-mobile-xs"><div><%= file.size %></div></td>
70+
<td class="hide-when-mobile"><div><%= file.lastModified %></div></td>
71+
</tr>
72+
</tbody>
73+
</table>
7374

74-
<% if (file.mediaType === 'image') { %>
75-
<img id="media" src="/<%= file.fullname %>" alt="<%= file.name %>" />
76-
<% } else if (file.mediaType === 'video') { %>
77-
<video id="media" controls autoplay src="/<%= file.fullname %>" />
78-
<% } else if (file.mediaType === 'audio') { %>
79-
<audio id="media" controls autoplay src="/<%= file.fullname %>" />
80-
<% } %>
75+
<% if (file.mediaType === 'image') { %>
76+
<img id="media" src="/<%= file.fullname %>" alt="<%= file.name %>" />
77+
<% } else if (file.mediaType === 'video') { %>
78+
<video id="media" controls autoplay src="/<%= file.fullname %>" />
79+
<% } else if (file.mediaType === 'audio') { %>
80+
<audio id="media" controls autoplay src="/<%= file.fullname %>" />
81+
<% } %>
82+
</div>
8183
</div>
82-
83-
<img id="niko" src="/_/Niko_origin.webp" alt="Niko the Cat">
8484

85+
<img id="niko" src="/_/Niko_origin.webp" alt="Niko the Cat">
86+
8587
<style>
8688
:root {
8789
--bg-color: #f5f7fa;
@@ -99,15 +101,35 @@
99101
margin: 0;
100102
padding: 0;
101103
}
104+
105+
html, body {
106+
width: 100%;
107+
height: 100%;
108+
overflow-x: hidden;
109+
background-color: var(--bg-color);
110+
}
102111
103-
body {
112+
.outer-container {
104113
font-family: "JetBrains Mono", "Noto Emoji", monospace;
105114
font-optical-sizing: auto;
106115
107-
background: var(--bg-color);
108116
color: var(--text-color);
109117
line-height: 1.6;
110118
padding: 20px;
119+
height: 100%;
120+
121+
overflow: auto;
122+
scrollbar-gutter: stable;
123+
scrollbar-width: thin;
124+
scrollbar-color: var(--primary-color) transparent;
125+
}
126+
127+
.container {
128+
position: relative;
129+
z-index: 10;
130+
display: flex;
131+
flex-direction: column;
132+
gap: 1.5rem;
111133
}
112134
113135
h1 {
@@ -274,14 +296,6 @@
274296
}
275297
}
276298
277-
.container {
278-
position: relative;
279-
z-index: 10;
280-
display: flex;
281-
flex-direction: column;
282-
gap: 1.5rem;
283-
}
284-
285299
#niko {
286300
position: fixed;
287301
z-index: 0;

0 commit comments

Comments
 (0)