Coding Diary: Setting Up an NFT Showcase Page in 7 Days
Coding Diary: Setting Up an NFT Showcase Page in 7 Days
A few weeks ago, a digital artist friend of mine named Marcus came to me with a problem. He had just finished creating a stunning new set of 3D digital sculptures that he wanted to sell as NFTs. He had already written his smart contracts and set up his digital wallets, but he had zero web design skills. He needed a clean, professional-looking website to show off his collection to collectors.
Because Marcus only had fifteen pieces in his collection, he did not need a heavy, database-driven backend framework like React or WordPress. A simple static website built with standard HTML and CSS was the perfect fit. It would be cheap to host, load incredibly fast, and require almost no maintenance.
To save us both time and keep the project on a tight budget, I decided to look for a pre-made design we could customize. I wanted something with a dark, futuristic look that would make his colorful 3D art stand out. I ended up choosing the Unitok – NFT Marketplace HTML Template. It had the exact dark aesthetic we were looking for.
Here is my honest, day-by-day diary of how I set up the website, the mobile layout bug I ran into, and the exact code I wrote to fix it.
---
Day 1: Unpacking the Code and Cleaning the Bloat
On my first day, I downloaded the source folder and unzipped it on my computer. The template is built with Bootstrap 5, standard CSS, and vanilla JavaScript. This is great because it means there are no complex build tools or dependencies to worry about. The folder structure was simple, with separate directories for styles, scripts, fonts, and images.
To make my work easier, I set up a quick local development server on my machine using Python. I opened my terminal, navigated to the project folder, and ran this command:
python3 -m http.server 8080
This allowed me to view the website in my web browser at http://localhost:8080 and see my changes live. The homepage loaded quickly and looked beautiful, but it was packed with layout files we did not need. The template came with over twenty different pages, including mock checkout screens, author profiles, dummy auction pages, and setting menus.
Since Marcus only needed a simple landing page to show his fifteen artworks and an about section, I spent the afternoon deleting the extra files. I removed the unused HTML pages, cleared out dummy image placeholders, and stripped out third-party JS scripts that we did not plan to use. This clean-up made the final directory light, organized, and much easier to manage.
---
Day 3: The Overlapping Mobile Layout Bug and the CSS Fix
On Day 3, I ran into my first major technical issue. I opened the website on my iPhone and an older Android test phone to make sure everything looked correct on mobile screens.
On desktop, the hero banner looked fantastic. It had a bold headline on the left and a large, floating 3D card image on the right. However, on smaller mobile screens (especially those around 375 pixels wide), the text and the image collided. The headline text was overlapping with the card image, making the main title completely unreadable. This happened because the template used a hardcoded negative margin in its CSS grid to create a layered look on desktop, but did not reset that margin for smaller viewports.
To solve this, I decided to rewrite the typography and spacing rules using fluid CSS properties. Instead of static margins and font sizes, I used the CSS clamp() function. This function lets you define a minimum, preferred, and maximum value, allowing elements to scale smoothly depending on the screen size.
Here is the CSS code I added to our custom stylesheet to fix the layout:
/* Mobile layout fix for hero section and text overlap */
.hero-section-title {
font-size: clamp(2rem, 4vw + 1rem, 4.2rem);
line-height: 1.15;
margin-bottom: clamp(1rem, 2vw, 2.5rem);
}
.hero-main-image {
margin-top: 0;
max-width: 100%;
height: auto;
}
/* Only apply the overlapping negative margin on larger desktops */
@media (min-width: 992px) {
.hero-main-image {
margin-top: -60px;
margin-left: -20px;
}
}
By using clamp(), the headline text automatically shrinks on mobile phones while remaining big and bold on desktop screens. Restricting the negative margin to screens wider than 992 pixels completely resolved the overlapping bug on mobile devices. The hero section now looked clean and balanced on every screen size I tested.
---
Day 5: Adding a Smooth Theme Toggle with Local Storage
By Day 5, I wanted to improve the user experience. The template had a built-in switch that let users swap between dark and light modes. However, the transition was incredibly sudden. When you clicked the button, the screen instantly flashed from bright white to dark gray. It was harsh on the eyes.
I wanted to make this transition feel premium and smooth. I wrote a small CSS snippet to transition the background colors and text colors over a short duration when the theme changed.
I also realized the template did not remember the user's choice. If a visitor preferred light mode, switched it on, and then refreshed the page or clicked to a different section, the site would reset back to dark mode. I wrote a simple vanilla JavaScript script to save the user's theme choice in their browser's local storage.
Here is the transition styling and the JavaScript I implemented:
/* Smooth color transitions for theme switching */
body, .nft-card, .btn, h1, h2, h3, p, span {
transition: background-color 0.28s ease, color 0.28s ease, border-color 0.28s ease;
}
// Theme toggle script with persistent local storage
document.addEventListener('DOMContentLoaded', () => {
const themeBtn = document.querySelector('#theme-switch-btn');
const savedTheme = localStorage.getItem('user-theme');
// Apply the saved theme if it exists
if (savedTheme) {
document.body.className = savedTheme;
}
if (themeBtn) {
themeBtn.addEventListener('click', () => {
if (document.body.classList.contains('light-theme')) {
document.body.classList.replace('light-theme', 'dark-theme');
localStorage.setItem('user-theme', 'dark-theme');
} else {
document.body.classList.add('light-theme');
localStorage.setItem('user-theme', 'light-theme');
}
});
}
});
Now, when a user changes the theme, the colors fade smoothly over a fraction of a second. Even better, their preference is saved, so the site loads in their preferred mode on their next visit.
---
Day 7: Performance Polish and Going Live
On the final day, I prepared the files for deployment. Because we were building a static website, speed was our main goal. I wanted the page to load almost instantly, even for players browsing on mobile connections while commuting.
I compressed Marcus's high-resolution 3D artwork images, converting them into the modern WebP format. This reduced the average image file size from 2.4 megabytes to under 200 kilobytes without losing any visible image quality.
Since the client wanted to host the site on their static server, I wrote a custom configuration file for their web server to handle browser caching and compression correctly. This ensures that static resources like web fonts, styles, and scripts are stored on the user's device, making subsequent page views instant.
Here is the server configuration block I created:
# Static asset optimization and browser caching rules
<IfModule mod_expires.c>
ExpiresActive On
ExpiresByType image/jpg "access plus 1 year"
ExpiresByType image/jpeg "access plus 1 year"
ExpiresByType image/png "access plus 1 year"
ExpiresByType image/webp "access plus 1 year"
ExpiresByType text/css "access plus 1 month"
ExpiresByType application/javascript "access plus 1 month"
ExpiresByType font/woff2 "access plus 1 year"
</IfModule>
When I ran the final site through speed testing tools, the performance score was 96 on mobile devices and 99 on desktop computers. The entire landing page loaded in less than one second, and the transitions felt incredibly smooth.
---
Objective Pros and Cons
After working with this setup for a full week, here is my balanced view of the design template.
The Positives:
Excellent Aesthetics: The dark-mode interface looks modern and high-end, which matches the digital art space perfectly.
Clean Code Structure: It is built with standard HTML5 and Bootstrap 5, making it very easy to read, edit, and strip down.
No Heavy Frameworks: It does not require complex build steps or continuous updates, which keeps hosting costs near zero.
The Negatives:
Mobile Spacing Bugs: The default desktop overlapping layouts broke on small phone screens, requiring custom CSS overrides.
Harsh Theme Switching: The default dark-to-light theme toggle was too fast and did not save user preferences out of the box.
---
The Result
Using a solid pre-made HTML layout saved us days of wireframing, designing, and coding grid systems. Instead of spending my time writing basic CSS reset rules, I was able to focus on resolving mobile rendering issues, adding user-friendly details like theme memory, and optimizing the server for speed.
The final website was delivered ahead of schedule. Marcus's 3D artwork looks fantastic, the site is responsive across all devices, and the page loading speed is exceptionally fast. Taking a practical shortcut with a well-designed template was the perfect choice for this project.
Replies