My implementation of a responsive web interface for a mobile photo gallery. Developed using HTML/CSS for the frontend UI and JavaScript for populating the carousel.
I started by laying out the basic image grid in HTML/CSS and defining breakpoints at which the grid would collapse into smaller columns upon resize. I then added functionality to make the carousel navigation work with click, swipe, and keyboard inputs, along with other helper functions.
After refactoring the code to make it more readable and reusable, I tested the site across various devices and browsers to make sure the experience was as uniform as possible across different platforms. I prioritized the user experience in desktop and mobile view, and focused on the main functionality of populating the carousel when a thumbnail is active.
To keep the HTML file simple and “DRY”, I populated both the image grid and the carousel content within the JS file. The styling and JavaScript implementations are separated into their respective files to keep an overall clean HTML page. I added ARIA roles and tab indexes where it made sense to account for accessibility.
I divided my code into four components (header, gallery, carousel, footer) and used the main
style.scss
to import all files. Even though some files are relatively short, I organized
the UI in a way that makes readability clearer. If this project grew to include a more complicated
interface, having this compartmentalization makes it easier for future developers to
pinpoint specific files.
I focused on writing efficient selectors, consistent class/ID names, and using variables/mixins where possible.
The JS code is organized into two classes. ImgGrid{}
contains a Carousel
within the class and has functions that relate to all but the carousel itself. Carousel{}
contains functions to populate the carousel, set the previous/next images, and swipe gestures.
The first variable defined in the document is imgArr
, which contains data about each image
loaded into the grid. When a new ImgGrid
is created, the constructor sets the data and
renders the web page accordingly.
The wrapper functions getElement()
and getElements()
act as a cache for the
document.querySelector()
function and are meant to increase efficiency in case DOM elements
are called more than once.
A couple functions to highlight:
setActiveImg()
:
Used mainly in conjunction with getNext()
and getPrev()
, this function takes
an index as an argument and sets the next image to be shown. To make the carousel a continuous loop,
getNext()
returns the index of the first image if the user is on the last slide, and
getPrev()
returns the index of the last image if the user is on the first slide. Within
this function, I also had to create a clone of my carouselImg
element to trigger a reset of
the CSS fade-in animation.
touchMove()
:
This function works in conjunction with updateImgFromTouch()
. Since the touchmove event
listener fires so many times with just one swipe gesture, I added a throttle function that triggers the
updateImgFromTouch()
function only once every 300 milliseconds by making use of
setTimeout()
. This results in less callbacks and overall greater efficiency.