Skip to content

Commit 09d2796

Browse files
Merge pull request #65 from Sanjhivvarshan-b-s/feature/back-to-top
Add floating "Back to Top" button to web app
2 parents 385deb4 + fb2f6b6 commit 09d2796

3 files changed

Lines changed: 72 additions & 1 deletion

File tree

web-app/css/styles.css

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -816,6 +816,45 @@ body {
816816
color: var(--secondary-color);
817817
}
818818

819+
/* Here is the Back to Top Button */
820+
.back-to-top {
821+
position: fixed;
822+
right: 1.5rem;
823+
bottom: 1.5rem;
824+
width: 3.25rem;
825+
height: 3.25rem;
826+
border: none;
827+
border-radius: 50%;
828+
background: linear-gradient(135deg, var(--primary-color), var(--secondary-color));
829+
color: white;
830+
box-shadow: var(--shadow);
831+
cursor: pointer;
832+
display: grid;
833+
place-items: center;
834+
font-size: 1.1rem;
835+
opacity: 0;
836+
transform: translateY(1rem) scale(0.9);
837+
pointer-events: none;
838+
transition: opacity 0.25s ease, transform 0.25s ease, box-shadow 0.25s ease;
839+
z-index: 1500;
840+
}
841+
842+
.back-to-top.visible {
843+
opacity: 1;
844+
transform: translateY(0) scale(1);
845+
pointer-events: auto;
846+
}
847+
848+
.back-to-top:hover {
849+
box-shadow: 0 12px 30px rgba(99, 102, 241, 0.45);
850+
transform: translateY(-3px) scale(1.05);
851+
}
852+
853+
.back-to-top:focus-visible {
854+
outline: 3px solid rgba(255, 255, 255, 0.85);
855+
outline-offset: 3px;
856+
}
857+
819858
/* Animations */
820859
@keyframes fadeIn {
821860
from {
@@ -876,6 +915,13 @@ body {
876915
font-size: 0.9rem;
877916
}
878917

918+
919+
.back-to-top {
920+
right: 1rem;
921+
bottom: 1rem;
922+
width: 3rem;
923+
height: 3rem;
924+
879925
.search-wrapper {
880926
max-width: 100%;
881927
padding: 0 1rem;
@@ -916,6 +962,7 @@ body {
916962

917963
.search-icon {
918964
font-size: 1rem;
965+
919966
}
920967
}
921968

web-app/index.html

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -252,6 +252,11 @@ <h2 id="modalDialogTitle" class="modal-dialog-title visually-hidden" tabindex="-
252252
</div>
253253
</div>
254254

255+
<!-- Back to Top Button -->
256+
<button type="button" class="back-to-top" id="backToTop" aria-label="Back to top" title="Back to top">
257+
<i class="fas fa-arrow-up" aria-hidden="true"></i>
258+
</button>
259+
255260
<!-- Footer -->
256261
<footer class="footer">
257262
<div class="container">

web-app/js/main.js

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,8 +44,27 @@ themeToggle.innerHTML =
4444
: '<i class="fas fa-moon" aria-hidden="true"></i>';
4545
updateThemeToggleAria(savedTheme === 'light');
4646

47+
48+
// Back to Top Button
49+
const backToTopButton = document.getElementById('backToTop');
50+
51+
const toggleBackToTopButton = () => {
52+
backToTopButton.classList.toggle('visible', window.scrollY > 300);
53+
};
54+
55+
window.addEventListener('scroll', toggleBackToTopButton, { passive: true });
56+
toggleBackToTopButton();
57+
58+
backToTopButton.addEventListener('click', () => {
59+
const prefersReducedMotion = window.matchMedia('(prefers-reduced-motion: reduce)').matches;
60+
window.scrollTo({ top: 0, behavior: prefersReducedMotion ? 'auto' : 'smooth' });
61+
});
62+
63+
// Category Filtering
64+
const tabs = document.querySelectorAll('.tab');
65+
4766
// Category Filtering (tabs)
48-
const tabs = Array.from(document.querySelectorAll('.tab[role="tab"]'));
67+
4968
const projectCards = document.querySelectorAll('.project-card');
5069
const tabs = document.querySelectorAll('.tab');
5170
const searchInput = document.getElementById('projectSearch');

0 commit comments

Comments
 (0)