Skip to content

Commit ce7ccfe

Browse files
committed
freeze headers
1 parent 4eaa3c6 commit ce7ccfe

1 file changed

Lines changed: 110 additions & 6 deletions

File tree

docs/datasets/index.html

Lines changed: 110 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ <h1> Currently Available Shared Neuroimaging Data Resources </h1>
2626
background: white;
2727
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
2828
position: relative;
29+
--sticky-top-offset: 70px;
2930
}
3031

3132
.datasets-table-container {
@@ -43,17 +44,13 @@ <h1> Currently Available Shared Neuroimaging Data Resources </h1>
4344
table-layout: auto;
4445
border: 2px solid #e8eaff;
4546
border-radius: 10px;
46-
overflow: hidden;
4747
margin: 0;
4848
padding: 0;
4949
}
5050

5151
.datasets-table thead {
5252
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
5353
color: white;
54-
position: sticky;
55-
top: 0;
56-
z-index: 10;
5754
}
5855

5956
.datasets-table th {
@@ -63,10 +60,31 @@ <h1> Currently Available Shared Neuroimaging Data Resources </h1>
6360
font-size: 14px;
6461
border: 1px solid #e8eaff;
6562
position: relative;
63+
background: inherit;
6664
white-space: normal;
6765
word-wrap: break-word;
6866
}
6967

68+
.datasets-table-sticky {
69+
position: fixed;
70+
top: var(--sticky-top-offset);
71+
left: 0;
72+
z-index: 50;
73+
pointer-events: none;
74+
visibility: hidden;
75+
overflow: hidden;
76+
}
77+
78+
.datasets-table-sticky table {
79+
margin: 0;
80+
border-collapse: separate;
81+
border-spacing: 0;
82+
}
83+
84+
.datasets-table-sticky thead {
85+
box-shadow: 0 6px 12px rgba(102, 126, 234, 0.35);
86+
}
87+
7088
/* Header color groups */
7189
.datasets-table th.structural {
7290
background: linear-gradient(135deg, #a8b5ff 0%, #8b9cff 100%);
@@ -88,7 +106,12 @@ <h1> Currently Available Shared Neuroimaging Data Resources </h1>
88106
text-align: left;
89107
position: sticky;
90108
left: 0;
91-
z-index: 20;
109+
z-index: 25;
110+
background: inherit;
111+
}
112+
113+
.datasets-table thead tr:nth-child(2) th:first-child {
114+
z-index: 24;
92115
}
93116

94117
.datasets-table th a {
@@ -252,7 +275,7 @@ <h1> Currently Available Shared Neuroimaging Data Resources </h1>
252275
{% endif %}
253276

254277
<tr>
255-
<td><a href="{{ dataset.website }}">{{ dataset.title }}</a></td>
278+
<td><a href="{{ dataset.website }}">{{ dataset.title }} {% if dataset.excerpt and dataset.excerpt != dataset.title %}({{ dataset.excerpt }}){% endif %}</a></td>
256279
<td>
257280
{% comment %}Prioritize front matter over CSV{% endcomment %}
258281
{% assign age_range_display = "" %}
@@ -615,5 +638,86 @@ <h1> Currently Available Shared Neuroimaging Data Resources </h1>
615638
});
616639
});
617640
});
641+
642+
const container = document.querySelector('.datasets-table-container');
643+
const thead = table.querySelector('thead');
644+
if (!container || !thead) return;
645+
646+
const stickyWrap = document.createElement('div');
647+
stickyWrap.className = 'datasets-table datasets-table-sticky';
648+
const stickyTable = document.createElement('table');
649+
stickyTable.appendChild(thead.cloneNode(true));
650+
stickyWrap.appendChild(stickyTable);
651+
document.body.appendChild(stickyWrap);
652+
653+
const stickyTopOffset = () => {
654+
const raw = getComputedStyle(table.closest('.datasets-table')).getPropertyValue('--sticky-top-offset');
655+
const val = parseFloat(raw);
656+
return Number.isFinite(val) ? val : 0;
657+
};
658+
659+
const syncSticky = () => {
660+
const tableRect = table.getBoundingClientRect();
661+
const containerRect = container.getBoundingClientRect();
662+
const headHeight = thead.getBoundingClientRect().height;
663+
const offset = stickyTopOffset();
664+
665+
const show = tableRect.top < offset && tableRect.bottom > offset + headHeight;
666+
stickyWrap.style.visibility = show ? 'visible' : 'hidden';
667+
if (!show) return;
668+
669+
stickyWrap.style.left = `${containerRect.left}px`;
670+
stickyWrap.style.width = `${containerRect.width}px`;
671+
stickyTable.style.width = `${tableRect.width}px`;
672+
stickyTable.style.transform = `translateX(${-container.scrollLeft}px)`;
673+
674+
const sourceHeaders = table.querySelectorAll('thead th');
675+
const stickyHeaders = stickyTable.querySelectorAll('thead th');
676+
const theadStyles = getComputedStyle(thead);
677+
const theadBgImage = theadStyles.backgroundImage;
678+
const theadBgColor = theadStyles.backgroundColor;
679+
sourceHeaders.forEach((th, idx) => {
680+
if (!stickyHeaders[idx]) return;
681+
const rect = th.getBoundingClientRect();
682+
const styles = getComputedStyle(th);
683+
const bgImage = styles.backgroundImage;
684+
const bgColor = styles.backgroundColor;
685+
const isTransparent =
686+
bgColor === 'transparent' ||
687+
bgColor === 'rgba(0, 0, 0, 0)' ||
688+
bgColor === 'rgba(0,0,0,0)';
689+
690+
stickyHeaders[idx].style.width = `${rect.width}px`;
691+
692+
if (bgImage && bgImage !== 'none') {
693+
stickyHeaders[idx].style.backgroundImage = bgImage;
694+
stickyHeaders[idx].style.backgroundColor = bgColor;
695+
stickyHeaders[idx].style.backgroundSize = styles.backgroundSize;
696+
stickyHeaders[idx].style.backgroundPosition = styles.backgroundPosition;
697+
stickyHeaders[idx].style.backgroundRepeat = styles.backgroundRepeat;
698+
} else if (!isTransparent) {
699+
stickyHeaders[idx].style.backgroundImage = 'none';
700+
stickyHeaders[idx].style.backgroundColor = bgColor;
701+
stickyHeaders[idx].style.backgroundSize = '';
702+
stickyHeaders[idx].style.backgroundPosition = '';
703+
stickyHeaders[idx].style.backgroundRepeat = '';
704+
} else {
705+
stickyHeaders[idx].style.backgroundImage = theadBgImage;
706+
stickyHeaders[idx].style.backgroundColor = theadBgColor;
707+
stickyHeaders[idx].style.backgroundSize = '';
708+
stickyHeaders[idx].style.backgroundPosition = '';
709+
stickyHeaders[idx].style.backgroundRepeat = '';
710+
}
711+
712+
stickyHeaders[idx].style.color = styles.color;
713+
stickyHeaders[idx].style.borderColor = styles.borderColor;
714+
});
715+
};
716+
717+
const scheduleSync = () => window.requestAnimationFrame(syncSticky);
718+
window.addEventListener('scroll', scheduleSync, { passive: true });
719+
window.addEventListener('resize', scheduleSync);
720+
container.addEventListener('scroll', scheduleSync, { passive: true });
721+
scheduleSync();
618722
});
619723
</script>

0 commit comments

Comments
 (0)