What I learned about CSS by Recreating Notion's Homepage

Deciding what to build to showoff my front-end skills

When I first decided to build something for the Digital Ocean Hackathon to show off my front-end webdev skills, I asked myself "What would be useful for a real business?"

The answer I came to is recreating the website of a real business, a business whose website is so important to them that it serves as a foundation of how they do business and serve their customers.

The first criteria I had was obvious to me: the business whose website I chose to recreate had to be huge, or at least hugely valuable.

The second criteria was less obvious: the business' website had to not depend on the use of outside assets and graphics to make it look nice. Pretty assets don't show off my front-end skills and don't show off how I can best help businesses.

So I wanted to recreate an existing successful business' website that uses a variety of CSS skills: flexbox, grid, and a variety of styles for images, text, and a lot of data that needed to be managed in a robust way.

After all, part of the reason I decided to recreate a serious internet business' homepage, is that I wanted to improve my front-end webdev process and this offered me the perfect challenge: totally doable, yet more complicated than any page I've created before.

I looked at a few sites before I chose one:

First I looked at Nike because I like their branding, but after looking at their website, I realized most of the work recreating Nike's website design would just be copying their media assets.

Nike's homepage

I could recreate the Nike website's navigation menus using flexbox and product displays using grid, but most of my design work wouldn't show through.

Second, I looked at Stripe. Stripe's website is beautiful, but it's very complicated and, secondly, it has the same problem that Nike's website does: Stripe's website uses a lot of image assets, except its website's assets are harder to work with because they're harder to access and implement.

Stripe's homepage

Still, Stripe's website uses some pretty cool layouts designs I could recreate using grid. Maybe this is something I'll revisit later.

Lastly, I looked at Notion. Notion's website, like their application, is beautiful, friendly, and accessible. It uses a bunch of assets, but, unlike Stripe and Nike's websites, doesn't entirely rely on them. It uses modern CSS skills like flexbox and grid and a lot of text data that's managed best dynamically using components.

Notion's homepage was the clear and obvious winner.

My website building process

One thing I decided early on was that I wasn't going to look at the original website's code. If someone wants to hire me to create a website for them, I don't think they'll have any starting code to work with so I'm not going to use that here either. They'll simply hand me off some wireframes from Figma or Sketch with the assets I need to implement and/or a validated product spec.

I recreated all of Notion's webpage designs and layout by sight. No inspecting code, no copying code. All translating what I visually see into what code I write.

I know know one good solution for designing with code and that's using the Tailwind CSS framework.

Tailwind is great because it solves a major problem with writing global CSS: naming and managing CSS classes.

Next, I thought about how I should manage my website's content data. Hardcoding content data was a clear no go. It's easy for hardcoded data to be overlooked when updating a website. All content data should be managed dynamically using components.

A component

Design and data should be managed independently. This makes it easier to read your design and content code and keeps both safe from making accidental changes.

The data the component uses

Next I thought about how to avoid duplicating code. Code duplication makes your website's code harder to read and easy to mess up. Components reduce code duplication and makes managing your website's design and data scalable.

The finished result

I used Vue JS to build out this website. Its fast modern website and web app framework that makes managing data easy and reliable.

But there's one problem with Vue JS and that's SEO. Vue JS, like React and Angular, render webpage content dynamically when websites load using javascript. Google doesn't like javascript, so these frameworks aren't good for SEO.

To solve this problem, my next steps are rebuilding this site using NUXT JS, which builds static HTML pages to get all the benefits of dynamic rendering and offers component organization from Vue JS with all the SEO benefits of static HTML.

a modern modular web framework called Nuxt JS to build my website, but another popular framework for building entreprise grade business websites that are still fast is Next JS.

CSS Properties I Learned

pointer-events-none

Prevents users from easily copying your website's text and images. When it's applied users will have to inspect the website's code using their browser.

CSS Properties I knew, but hadn't used before

flex-row-reverse

Useful for conditionally reversing the orientation of your footer elements on mobile, such as when you want to show a copyright notice on the left in your footer on desktop, but below everything else on mobile.

View the Project:

My Recreation of Notion's Homepage

Compare it to the Original

Notion's Homepage