End to End: Building a Photography Website from Scratch

Personal Project — Live at thisfragileworld.com

Background

I designed and built this fragile world as a home for my photography—a site where viewers could experience images slowly and intentionally. What started as a personal project quickly became a crash course in full-stack development—from web-accessible code to custom CMS and back-end systems. I pushed the limits of my skill set, taught myself new tools, and crafted a site that showcases my work and reflects my values.

This project is currently live! You can check it out at thisfragileworld.com.

Roles

🎨 Graphic Design
🧩 UX and UI Design
🧑‍💻 Front-End Development
🛠️ Back-End Development

Tools

Coding Languages

Product Objective

I wanted to build a website to showcase my photography, focusing on cultivating meaningful viewer experiences. The website reflects my values and philosophies as a photographer and a designer.

Site Capabilities

📱 Fully responsive — works beautifully on web and mobile without separate codebases

🌗 Supports viewer preferences — light mode, dark mode, and high contrast mode

🔍 Zoom-friendly UI — fully accessible and error-free at any scale

⌨️ Keyboard & screen reader ready — seamless navigation and meaningful markup

Project Goals

🚀 Ship a solo project — design, develop, and launch a complete experience

Deepen accessibility skills — learn how inclusive design is implemented at the code level

🧑‍💻 Brush up & build out — polish my CSS, relearn JavaScript, and explore modern frameworks and dev tools

🤖 Integrate AI into workflows — experiment with co-coding, prototyping, and process support

Design and Front-End Implementation

The site supports both light and dark modes using system-aware media queries, ensuring a seamless experience that matches the user’s device preferences. Below are screenshots showing how the interface dynamically adapts to each mode.

Light Mode

Dark Mode

High Contrast Mode

High contrast mode enhances usability for people with low vision or contrast sensitivity by increasing legibility and visual clarity. I achieved this with strong color pairings, larger default text size, and visible focus outlines.

Mobile-Friendly and Zoom-Friendly by Default

A responsive website isn’t just about having a clean mobile experience. It also means ensuring your website is functional at all zoom levels. All of the content and the text of the page are coded to work dynamically with the viewing preferences of the user.

Using Code to Create Accessible Design Experience Parity

Accessibility wasn’t an afterthought—it was a foundational consideration from the first line of code. In addition to my usual design best practices (like WCAG AAA color contrast compliance and W3C interface guidance), I focused on both visible and invisible layers of accessibility to create a truly inclusive experience.

One of the essential ways of making a website accessible is through keyboard navigation. For my galleries, that meant that the user could press tab to move from image to image and enter to open up the lightbox.

But I quickly realized I had an issue. Tabbing from image to image would make the page jump if the picture wasn’t in the current window. This was far from the pleasant experience I want users to have of scrolling through the gallery.

To solve this, I added code to smoothly scroll and center the image as it became the focused object.

				
					// Figure out how far down the page the user has already scrolled
const viewportHeight = window.innerHeight;

// Measure the height of the visible part of the browser window (i.e. the viewport)
const scrollTop = window.pageYOffset || document.documentElement.scrollTop;

// Retrieve the position and size of the image relative to the current viewport
const rect = link.getBoundingClientRect();

// Store the height of the image so we can factor it into vertical centering
const imageHeight = rect.height;

// Use these numbers to calculate the scroll position that would center the image in the viewport
const idealCenter = scrollTop + rect.top - (viewportHeight / 2) + (imageHeight / 2);
				
			

By having the focused image always move to the center, I’ve not only created an equivalent aesthetic experience for keyboard users but also the same physical experience of eye movement.

Reducing this friction means that the user can move their eyes around the screen naturally and experience the gallery holistically, rather than having to spend their energy trying to realign themselves with the page’s shifted location.

Other Key Accessibility Features

🖼️ 190+ custom-written alt texts
Every gallery image is described with care for screen reader users.

🔧 Semantic HTML5 structure
Built from the ground up with accessible, meaningful markup.

🔊 ARIA labels on interactive elements
Enhances clarity for assistive tech without cluttering the visual UI.

🧭 Screen reader-friendly navigation
Smooth, contextual browsing without surprises or dead ends.

The final site passed accessibility testing for the U.S., Canadian, and EU regulatory standards—ensuring that users around the world can navigate and enjoy the site. Below are the test results from accessibilitychecker.org.

Developing My Own Content Management System

From the beginning, I knew that I didn’t want to be manually editing the HTML file for every gallery. 

At first, I thought I needed a full content management system that could manage my files while still letting me control the front end.

After testing WordPress and Strapi, I realized that a full CMS was more than I needed.

I took a step back and reframed the problem:

What’s the minimum viable content system that still feels robust?

The result: a lean setup using one structured JSON file and some JavaScript.

Each gallery pulls from a JSON file that organizes the images, sets their display order, and links alt text and metadata directly to each photo.

This approach keeps the site fast, portable, and easy to maintain.

And more importantly, it reflects how I work:

Identify the need, explore the space, learn how to question your assumptions from that exploration, and then build only what the project truly requires.

It’s not just “lightweight”—it’s intentionally designed to support my workflow as a designer and dev.

Co-Coding with ChatGPT: A Learning-First Approach

While I wrote every line of this site’s HTML, CSS, and JavaScript, I didn’t do it alone. This project was also an experiment in learning through co-coding—staying in flow, asking better questions, and building by doing.

I used ChatGPT like a project buddy. When I hit a challenge—like making the site fully keyboard navigable or refactoring a gnarly chunk of CSS—I’d talk it through. That helped me unblock faster, deepen my understanding, and keep momentum without getting derailed by rabbit holes.

When I had the idea for the interactive polaroid stack on the About page, I realized I’d reached the limit of what I could co-build. That’s when I turned to Cursor—an AI coding assistant built into a developer environment. Cursor helped me scaffold the more complex parts, and I used the process of debugging and modifying the feature to learn how it worked under the hood.

Between the two, I prefer the conversational co-coding process with ChatGPT—but having Cursor in my toolbox expanded what I could build and how fast I could build it. More importantly, both tools supported the kind of learning I care about most: identifying the problem, understanding the system, and growing my skill set through making.

What's next?

One of the things that’s most exciting about having built this website myself is that it’s now a sandbox for me to play and experiment with. I have many ideas for things I’d like to try, some practical and some simply exciting. 

💡 Lightbox Improvements
I would really love to implement a more interactive lightbox design with the ability to display additional information about the photograph, like title, location, and medium.

📚 Expand the Site: Blog, Zines, and Print Shop
Add a content layer with essays, behind-the-scenes breakdowns, downloadable zines, and a future print store. Let the site grow into a living archive of your creative practice.

🎧 Soundscape Galleries
I would love to make galleries that allow me to bring my background as a sound designer into my work as a photographer. A lot of my photography is rooted in the interplay between people and place, and soundscape is a perfect medium to continue to explore those ideas. 

🕶️ AR Experience Prototype
I would love to explore what it will look like to be able to experience photography in AR. I’m excited by the potential intersection between art and wearable headsets, and I think this fragile world could be an exciting place to explore that.

Personal Reflection

Relearning Coding

One of this project’s biggest challenges the constraints of minimal development resources. We had to go through a few rounds of narrowing down the MVP before we could find the balance between what really mattered and what we would be able to build. But it was exactly that process that made the modular form the heart of the product, and the reason for its success.

Why It Matters

This project isn’t just a portfolio piece. It’s proof that design and development don’t have to be separate. That accessibility isn’t a feature — it’s a philosophy. And anyone, including designers just starting to code, can build something meaningful.

In this fragile world, every detail matters. And every detail here was built with care.

Interested in working together? Want to chat about design or AI? Drop me a line!​