Build a Psychology Portfolio Website
Build and deploy a psychology portfolio site live on GitHub Pages.
Introduction
30 Second Summary
Every professional needs an online presence, but website builders charge monthly fees and limit your creative control. What if you could build a polished portfolio site yourself and host it for free, forever?
In this project, you will build a professional psychology portfolio website from scratch using HTML and CSS, then deploy it live on the internet using GitHub Pages at zero cost.
What You'll Build
A clean, single-page portfolio website for a psychology practice, featuring a hero section, services grid, and contact details, all styled with responsive CSS and deployed live on the internet.
By the end of this project, you'll have:
- A complete index.html file with semantic HTML structure including navigation, hero, services, and contact sections.
- A styles.css file with professional responsive styling that looks great on both desktop and mobile.
- A live website hosted on GitHub Pages at your own yourusername.github.io URL, powered by a Git workflow that publishes changes automatically.
- Secret Mission: Add a dark mode toggle using JavaScript that remembers your visitor's preference.
Are there any prerequisites?
None. This project walks you through installing every tool you need, including VS Code and Git. All you need is a Mac and a web browser.
Before We Start
Before you can build your portfolio website, you need a few tools on your computer. These are all free and will take just a few minutes to install.
You need a code editor to write your HTML and CSS, a version control tool to track changes and publish your site, and a free account on the platform that will host your website.
In this step, get ready to:
- Install VS Code, your code editor.
- Install Git, your version control tool.
- Create a GitHub account and configure Git with your identity.
Install VS Code
VS Code is a free code editor made by Microsoft. It is where you will write all of the HTML and CSS for your portfolio website.
- Open your web browser and go to https://code.visualstudio.com/Download.
- Click the large macOS button to download the .zip file.
- Once the download finishes, double-click the .zip file in your Downloads folder to extract it.
- Drag Visual Studio Code.app into your Applications folder.
What is VS Code?
VS Code (Visual Studio Code) is a lightweight code editor that supports nearly every programming language. It gives you features like syntax highlighting, auto-complete, and a built-in terminal so you can do everything in one window.
- Press Cmd+Space to open Spotlight search.
- Type Visual Studio Code and press Enter to open it.
You should see the Welcome tab in the editor. This confirms VS Code is installed and ready to use.
VS Code not appearing in Spotlight?
If VS Code does not appear when you search for it, make sure you dragged Visual Studio Code.app into your Applications folder. Spotlight only indexes applications in that folder.
help me open VS Code after installing it on macOS
Install Git
Git is a version control tool that tracks every change you make to your code. You will use it to save your work and push your website files to the internet.
- macOS may already have Git installed. You will check in the next step.
- If it is not installed, macOS will prompt you to install the Xcode Command Line Tools, which includes Git.
What is version control?
Version control is a system that records changes to your files over time. If you ever break something, you can go back to a previous version that was working.
Git is the most popular version control tool in the world. Almost every software company uses it.
Now verify that Git installed correctly.
- Switch back to VS Code.
- Open a new terminal by clicking Terminal in the top menu bar, then clicking New Terminal.
- Check that Git is installed by running this command:
git --version
You should see output like git version 2.39.5. The exact number may differ slightly, but any version number means Git is working.
Seeing 'git' command not found?
If macOS says Git is not installed, it should show a dialog offering to install the Xcode Command Line Tools. Click Install and wait for it to finish, then try git --version again.
If no dialog appears, run this command to trigger the install manually:
xcode-select --install
help me install Git on macOS
Create a GitHub account and configure Git
GitHub is a website that stores your code online. Later in this project, you will push your website files to GitHub and it will host your live site for free.
- Go to https://github.com in your browser.
- Click Sign Up and follow the prompts to create a free account.
- Choose a username you will remember. Your portfolio website address will include this username.
Pick a professional username
Your GitHub username becomes part of your website URL (e.g. yourusername.github.io). Choose something professional since potential clients or employers will see it.
Now tell Git who you are so it can label your work with your name and email.
- Switch back to VS Code's terminal.
- Set your name by running this command:
git config --global user.name "[[YOUR_NAME="Your Name"]]"
- Set your email by running this command (use the same email you signed up to GitHub with):
git config --global user.email "[[YOUR_EMAIL="your-email@example.com"]]"
What do these commands do?
These commands save your name and email in Git's global configuration. Every time you save a snapshot of your code (called a "commit"), Git stamps it with this identity so you can see who made each change.
You only need to run these once per computer. They persist across all future projects.
- Confirm your name was saved by running:
git config --global user.name
You should see the name you entered printed back to you in the terminal.
Not seeing your name?
Make sure you included the --global flag in your earlier command. Without it, the setting only applies inside a specific project folder.
Also check that you wrapped your name in quotation marks. Run the git config --global user.name command again after fixing it.
help me configure my git username on macOS
Your development environment is ready. Next up, you will create your project files and start writing the HTML for your portfolio.
Install Your Tools
Before you can build your portfolio website, you need three tools installed on your computer.
VS Code is the code editor where you will write your HTML and CSS. Git tracks every change you make to your files. GitHub hosts your code online and publishes your finished site for free.
In this step, get ready to:
- Install VS Code, your code editor.
- Install Git, the tool that tracks changes to your files.
- Create a GitHub account and configure Git with your identity.
Install VS Code
VS Code is a free code editor from Microsoft. It gives you syntax highlighting, a built-in terminal, and helpful extensions all in one window.
- Open your web browser and go to https://code.visualstudio.com/Download.
- Click the large macOS button to download the .zip file.
- Once the download finishes, double-click the .zip file in your Downloads folder to extract it.
- Drag Visual Studio Code.app into your Applications folder.
- Open VS Code from your Applications folder or use Spotlight (Cmd+Space, type Visual Studio Code).
What does the download include?
The macOS download is a .zip archive that contains the full VS Code application. Once you drag it to Applications, it is ready to use. You can also add the code command to your terminal path later via the Command Palette.
You should see the VS Code Welcome tab open in a new window.
✔️ I see the Welcome tab
VS Code is ready to go. Move on to the next substep.
ⓧ VS Code didn't open
- Press Cmd+Space to open Spotlight search.
- Type Visual Studio Code and press Enter to launch it manually.
- If it still does not appear, make sure you dragged the app into your Applications folder.
Install Git
Git is a version control tool. It saves snapshots of your project so you can always revert to a previous state if something breaks.
- macOS may already have Git installed. You will check in the terminal next.
- If Git is not installed, macOS will prompt you to install the Xcode Command Line Tools, which includes Git.
What are the Xcode Command Line Tools?
The Xcode Command Line Tools are a lightweight package from Apple that includes essential developer tools like Git, a C compiler, and other utilities. You do not need the full Xcode app. The installation takes a few minutes and only needs to happen once.
- After the installer finishes, switch back to VS Code.
- Open a new terminal by clicking Terminal in the top menu bar, then clicking New Terminal.
- Verify Git is installed by running this command:
git --version
You should see output like git version 2.39.5 (Apple Git-154).
✔️ I see a version number
Git is installed and working. Move on to the next substep.
ⓧ Command not found
macOS does not have Git installed yet. You should see a dialog offering to install the Xcode Command Line Tools.
- Click Install in the dialog and wait for it to finish.
- If no dialog appears, run xcode-select --install in the terminal to trigger it manually.
- After installation completes, close the terminal panel and open a fresh one (Terminal > New Terminal).
- Run git --version again.
Create a GitHub account and configure Git
GitHub is the platform that will host your code and serve your finished website to the world for free.
- Go to https://github.com and click Sign Up.
- Follow the prompts to create a free account.
- Remember the username you choose. You will need it later when you create your repository.
Why does Git need your name and email?
Every time you save a snapshot (called a commit), Git attaches your name and email to it. This identifies who made each change. Use the same email you signed up with on GitHub so your commits are linked to your account.
- In VS Code's terminal, configure your Git identity by running these commands:
git config --global user.name "[[YOURNAME="Your Name"]]"
git config --global user.email "[[YOUREMAIL="your-email@example.com"]]"
What do these commands do?
The --global flag tells Git to save these values for every project on your computer. You only need to run this once.
- Confirm your name was saved by running:
git config --global user.name
You should see the name you just entered printed back in the terminal.
✔️ I see my name printed
Git is configured. You are all set for the next step.
ⓧ Nothing printed or I see the wrong name
- Re-run the git config --global user.name command with your name in quotes.
- Make sure you included the quotation marks around your name.
- Run git config --global user.name (without a value after it) again to verify it updated.
Your tools are ready. Next up, you will create your project folder and write the HTML that structures your portfolio.
Create Your Project and Write the HTML
Your tools are installed and ready to go. Now it's time to build your actual portfolio website.
Every website starts with an HTML file that defines the page's structure and content. In this step, you'll create your project folder, write the full HTML for your psychology portfolio, and preview it in the browser.
In this step, get ready to:
- Create a project folder with two starter files.
- Write the complete HTML structure for your portfolio page.
- Preview the unstyled site in your browser.
Create the project folder and files
You need a dedicated folder to hold your website files. You'll create this folder and open it in VS Code so everything stays organized.
- In VS Code, click File in the top menu bar.
- Click Open Folder.
- In the dialog that opens, navigate to your Desktop.
- Click the New Folder button at the bottom left of the dialog.
- Name the new folder portfolio and press Enter.
- With portfolio selected, click Open.
VS Code reloads with the portfolio folder open. You should see the folder name in the Explorer sidebar on the left.
What is the Explorer sidebar?
The Explorer is the file browser panel on the left side of VS Code. It shows all the files and folders in your project. You can open it anytime by pressing Cmd+Shift+E.
Now you'll create the two files your website needs.
- Hover over the PORTFOLIO heading in the Explorer sidebar. You'll see a row of small icons appear.
- Click the New File icon (the page with a plus sign).
- Type index.html and press Enter.
- Click the New File icon again.
- Type styles.css and press Enter.
- Confirm both files appear in the Explorer sidebar by checking the file list.
You should see index.html and styles.css listed under the portfolio folder.
Don't see the New File icon?
If the icons don't appear when hovering, right-click anywhere in the empty space of the Explorer sidebar and select New File from the menu instead.
If the Explorer sidebar is hidden entirely, press Cmd+Shift+E to bring it back.
help me find the New File option in VS Code
Write the HTML structure
HTML is the language that defines what content appears on a web page. Each section of your portfolio (navigation, hero, about, services, contact) is a building block in the HTML file.
- Click on index.html in the Explorer sidebar to open it in the editor.
- Add the document structure, navigation bar, and hero section by pasting this code:
<!DOCTYPE html>
<html lang="en">
<head>
<!-- Character encoding and responsive viewport -->
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Dr. Jane Smith - Psychologist</title>
<!-- Link to external stylesheet -->
<link rel="stylesheet" href="styles.css">
</head>
<body>
<!-- Navigation bar -->
<nav class="navbar">
<div class="nav-container">
<a href="#" class="nav-logo">Dr. Jane Smith</a>
<ul class="nav-links">
<li><a href="#about">About</a></li>
<li><a href="#services">Services</a></li>
<li><a href="#contact">Contact</a></li>
</ul>
</div>
</nav>
<!-- Hero section with name and title -->
<header class="hero">
<h1>Dr. Jane Smith</h1>
<p class="subtitle">Licensed Clinical Psychologist</p>
<p class="tagline">Helping individuals navigate life's challenges with evidence-based care.</p>
</header>
What does this code do?
This sets up the foundation of your web page:
- The <head> section contains metadata the browser needs (character encoding, viewport settings, page title, and a link to your stylesheet).
- The <nav> element creates a navigation bar with links that jump to each section of the page.
- The <header> with class hero is the large banner area visitors see first, with your name and professional title.
- Directly below the hero section, add the main content with the About and Services sections by pasting this code:
<!-- Main content area -->
<main>
<!-- About section -->
<section id="about" class="section">
<div class="container">
<h2>About Me</h2>
<p>I am a licensed clinical psychologist with over 10 years of experience helping adults and adolescents work through anxiety, depression, trauma, and relationship difficulties. My approach integrates cognitive-behavioral therapy (CBT) with mindfulness-based techniques to create personalized treatment plans.</p>
<p>I hold a Doctorate in Clinical Psychology and am committed to creating a warm, non-judgmental space where clients feel safe to explore their thoughts and emotions.</p>
</div>
</section>
<!-- Services section with card grid -->
<section id="services" class="section section-alt">
<div class="container">
<h2>Services</h2>
<div class="services-grid">
<div class="service-card">
<h3>Individual Therapy</h3>
<p>One-on-one sessions tailored to your unique needs, focusing on anxiety, depression, and personal growth.</p>
</div>
<div class="service-card">
<h3>Couples Counseling</h3>
<p>Strengthen communication and rebuild connection with your partner through guided therapeutic work.</p>
</div>
<div class="service-card">
<h3>Trauma Recovery</h3>
<p>Evidence-based approaches including EMDR and CBT to help process and heal from traumatic experiences.</p>
</div>
<div class="service-card">
<h3>Stress Management</h3>
<p>Develop practical coping strategies and mindfulness techniques for managing everyday stress.</p>
</div>
</div>
</div>
</section>
What does this code do?
This adds your two main content sections:
- The <section id="about"> holds your professional bio. The id attribute matches the navigation link so clicking "About" scrolls here.
- The <section id="services"> lists your practice areas. Each service sits inside its own service-card div, which you'll style as a card grid later.
- The container div wraps content inside each section. This gives you a hook to set a max-width in CSS so text doesn't stretch across the full screen.
- Complete the page by adding the Contact section, footer, and closing tags directly below the Services section:
<!-- Contact section -->
<section id="contact" class="section">
<div class="container">
<h2>Get in Touch</h2>
<p>Ready to take the first step? Reach out to schedule a free 15-minute consultation.</p>
<p class="contact-email">Email: <a href="mailto:drjanesmith@example.com">drjanesmith@example.com</a></p>
<p class="contact-phone">Phone: (555) 123-4567</p>
</div>
</section>
</main>
<!-- Page footer -->
<footer class="footer">
<p>2026 Dr. Jane Smith. All rights reserved.</p>
</footer>
</body>
</html>
What does this code do?
This finishes your page structure:
- The <section id="contact"> gives visitors a way to reach you. The mailto: link opens the visitor's email app automatically.
- The <footer> adds a copyright notice at the bottom of the page.
- The closing </body> and </html> tags complete the document. Every opening tag needs a matching closing tag.
- Save index.html by pressing Cmd+S.
Seeing red or yellow underlines in the code?
If VS Code highlights errors, check that every opening tag has a matching closing tag. Common mistakes include a missing </div> or </section> somewhere in the middle.
Also check that you pasted each chunk directly below the previous one, with no gaps or duplicate lines between them.
help me fix HTML errors in my index.html file
✔️ Awesome, I've got everything!
Great. Make sure you've saved index.html with Cmd+S.
ⓧ I'd like to double check the full code
Here is the complete index.html file. Compare your code against this:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Dr. Jane Smith - Psychologist</title>
<link rel="stylesheet" href="styles.css">
</head>
<body>
<nav class="navbar">
<div class="nav-container">
<a href="#" class="nav-logo">Dr. Jane Smith</a>
<ul class="nav-links">
<li><a href="#about">About</a></li>
<li><a href="#services">Services</a></li>
<li><a href="#contact">Contact</a></li>
</ul>
</div>
</nav>
<header class="hero">
<h1>Dr. Jane Smith</h1>
<p class="subtitle">Licensed Clinical Psychologist</p>
<p class="tagline">Helping individuals navigate life's challenges with evidence-based care.</p>
</header>
<main>
<section id="about" class="section">
<div class="container">
<h2>About Me</h2>
<p>I am a licensed clinical psychologist with over 10 years of experience helping adults and adolescents work through anxiety, depression, trauma, and relationship difficulties. My approach integrates cognitive-behavioral therapy (CBT) with mindfulness-based techniques to create personalized treatment plans.</p>
<p>I hold a Doctorate in Clinical Psychology and am committed to creating a warm, non-judgmental space where clients feel safe to explore their thoughts and emotions.</p>
</div>
</section>
<section id="services" class="section section-alt">
<div class="container">
<h2>Services</h2>
<div class="services-grid">
<div class="service-card">
<h3>Individual Therapy</h3>
<p>One-on-one sessions tailored to your unique needs, focusing on anxiety, depression, and personal growth.</p>
</div>
<div class="service-card">
<h3>Couples Counseling</h3>
<p>Strengthen communication and rebuild connection with your partner through guided therapeutic work.</p>
</div>
<div class="service-card">
<h3>Trauma Recovery</h3>
<p>Evidence-based approaches including EMDR and CBT to help process and heal from traumatic experiences.</p>
</div>
<div class="service-card">
<h3>Stress Management</h3>
<p>Develop practical coping strategies and mindfulness techniques for managing everyday stress.</p>
</div>
</div>
</div>
</section>
<section id="contact" class="section">
<div class="container">
<h2>Get in Touch</h2>
<p>Ready to take the first step? Reach out to schedule a free 15-minute consultation.</p>
<p class="contact-email">Email: <a href="mailto:drjanesmith@example.com">drjanesmith@example.com</a></p>
<p class="contact-phone">Phone: (555) 123-4567</p>
</div>
</section>
</main>
<footer class="footer">
<p>2026 Dr. Jane Smith. All rights reserved.</p>
</footer>
</body>
</html>
Preview your site in the browser
Your HTML is written. Time to see it in a browser and confirm all your content is showing up correctly.
- Open Finder by clicking the Finder icon in your Dock.
- Navigate to your Desktop and open the portfolio folder.
- Double-click index.html to open it in your default web browser.
You should see all your content displayed as plain, unstyled text. The navigation links, your name, the About section, all four services, and the contact details should all be visible on the page.
Why does it look so plain?
Right now you're seeing raw HTML without any styling applied. The browser displays the content in its default font with no colours, spacing, or layout. In the next step, you'll add CSS to transform this into a polished, professional-looking page.
🙋♀️ Don't see your content in the browser?
Make sure you saved index.html in VS Code (Cmd+S). A white dot on the file tab means unsaved changes.
If you see a blank page, right-click the file in Finder, select Open With, and choose your browser (Safari or Chrome).
help me preview my HTML file in a browser on macOS
Your HTML structure is complete. Next up, you'll add CSS styles to turn this plain text into a polished, professional portfolio.
Style Your Portfolio with CSS
Your HTML structure is complete. Every section of your portfolio is in place and visible in the browser.
The content is all there, but right now it looks like a plain document from the 1990s. CSS is what transforms raw HTML into a professional, visually polished design. In this step, you will write the entire stylesheet that gives your portfolio its colours, layout, and responsive behaviour.
In this step, get ready to:
- Define a colour palette and base typography using CSS custom properties.
- Style the navigation, hero section, content areas, and services grid.
- Add a responsive media query so the site looks great on mobile screens.
Set up your base styles
Every well-organized stylesheet starts with a design foundation. CSS custom properties (also called CSS variables) let you define your colour palette and fonts in one place, then reference them everywhere.
- Switch back to VS Code and click on styles.css in the Explorer sidebar to open it.
- Add your design foundation by pasting this code into the empty file:
:root {
--color-primary: #2b4c7e;
--color-primary-light: #3d6098;
--color-accent: #5b8fb9;
--color-bg: #ffffff;
--color-bg-alt: #f4f7fa;
--color-text: #333333;
--color-text-light: #666666;
--color-border: #e0e0e0;
--font-main: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
--max-width: 900px;
}
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
body {
font-family: var(--font-main);
line-height: 1.7;
color: var(--color-text);
background-color: var(--color-bg);
}
What does this code do?
The :root block defines 10 variables for your entire colour palette, font stack, and max content width. Changing a colour here updates it everywhere on the site at once.
The * selector resets all default browser margins and padding so spacing is predictable. The body rule applies your chosen font and text colour to the whole page.
- Save styles.css and refresh your browser.
- You should see the font change from the browser's default serif to a clean sans-serif. All extra spacing between elements disappears.
No font change after saving?
Make sure styles.css is saved (look for the dot or circle on the file tab in VS Code that indicates unsaved changes). Press Cmd+S to save.
Confirm that your index.html already has <link rel="stylesheet" href="styles.css"> in the <head> section. Without this link, the browser cannot find your stylesheet.
help me figure out why my CSS file is not loading
Style the navigation and hero section
The navigation bar is the first thing visitors see. A fixed nav bar stays visible as the user scrolls, keeping your links always accessible.
- Add the navigation styles below your existing code in styles.css:
/* Navigation */
.navbar {
position: fixed;
top: 0;
width: 100%;
background-color: var(--color-bg);
border-bottom: 1px solid var(--color-border);
z-index: 100;
}
.nav-container {
max-width: var(--max-width);
margin: 0 auto;
padding: 1rem 2rem;
display: flex;
justify-content: space-between;
align-items: center;
}
.nav-logo {
font-size: 1.2rem;
font-weight: 700;
color: var(--color-primary);
text-decoration: none;
}
.nav-links {
list-style: none;
display: flex;
gap: 2rem;
}
.nav-links a {
text-decoration: none;
color: var(--color-text-light);
font-weight: 500;
transition: color 0.2s;
}
.nav-links a:hover {
color: var(--color-primary);
}
What does this code do?
The .navbar uses position: fixed to stick to the top of the viewport as the user scrolls. The z-index: 100 ensures it stays above all other content.
The .nav-container uses flexbox to push the logo to the left and links to the right. The transition: color 0.2s on links creates a smooth colour change on hover.
- Save styles.css and refresh your browser.
- You should see a clean navigation bar pinned to the top of the page with your name on the left and links on the right. Hover over a link to see it change colour.
Content hidden behind the nav bar?
A fixed nav bar sits on top of the page content. The hero section's large top padding (which you will add next) pushes the content below the nav bar. If text is hiding behind it, keep going to the next chunk.
help me fix my fixed navigation bar overlapping content
Now add the hero section styles directly below the navigation styles:
- Paste the following hero styles below your navigation code in styles.css:
/* Hero Section */
.hero {
text-align: center;
padding: 8rem 2rem 4rem;
background-color: var(--color-bg-alt);
}
.hero h1 {
font-size: 2.5rem;
color: var(--color-primary);
margin-bottom: 0.5rem;
}
.subtitle {
font-size: 1.3rem;
color: var(--color-accent);
margin-bottom: 1rem;
}
.tagline {
font-size: 1.1rem;
color: var(--color-text-light);
max-width: 600px;
margin: 0 auto;
}
What does this code do?
The padding: 8rem 2rem 4rem on .hero creates generous whitespace. The 8rem top padding pushes content below the fixed nav bar.
The .tagline has a max-width: 600px with margin: 0 auto to keep it centred and readable rather than stretching across the full page width.
- Save styles.css and refresh your browser.
- You should see a large, centred heading with your name in a deep blue colour, a lighter blue subtitle, and a muted tagline. The hero section has a subtle off-white background.
Hero text not centred?
Check that your .hero selector exactly matches class="hero" in your HTML. CSS class names are case-sensitive.
help me debug why my hero section styles are not applying
Style the content sections and services grid
The main content sections need consistent spacing and a readable width. The services grid uses CSS Grid to arrange your practice areas into professional-looking cards.
- Add the section and container styles below your hero code in styles.css:
/* Sections */
.section {
padding: 4rem 2rem;
}
.section-alt {
background-color: var(--color-bg-alt);
}
.container {
max-width: var(--max-width);
margin: 0 auto;
}
.section h2 {
font-size: 1.8rem;
color: var(--color-primary);
margin-bottom: 1.5rem;
}
.section p {
margin-bottom: 1rem;
color: var(--color-text-light);
}
What does this code do?
The .container class limits content width to 900px and centres it with margin: 0 auto. This keeps text from stretching too wide on large screens, which hurts readability.
The .section-alt class adds an alternating background colour so the Services section stands apart visually from About and Contact.
- Now add the services grid, contact, and footer styles below your section code:
/* Services Grid */
.services-grid {
display: grid;
grid-template-columns: repeat(2, 1fr);
gap: 1.5rem;
margin-top: 1.5rem;
}
.service-card {
background-color: var(--color-bg);
border: 1px solid var(--color-border);
border-radius: 8px;
padding: 1.5rem;
}
.service-card h3 {
color: var(--color-primary);
margin-bottom: 0.5rem;
}
.service-card p {
font-size: 0.95rem;
}
/* Contact */
.contact-email a {
color: var(--color-accent);
text-decoration: none;
}
.contact-email a:hover {
text-decoration: underline;
}
/* Footer */
.footer {
text-align: center;
padding: 2rem;
border-top: 1px solid var(--color-border);
color: var(--color-text-light);
font-size: 0.9rem;
}
What does this code do?
The .services-grid uses CSS Grid with grid-template-columns: repeat(2, 1fr) to create a two-column layout. Each .service-card gets a border, rounded corners, and padding to look like a distinct card.
The footer has a top border line to separate it from the page content. The contact email link uses your accent colour for visual interest.
- Save styles.css and refresh your browser.
- You should see your services displayed as four cards in a two-column grid. The About and Contact sections have comfortable spacing, and the footer sits at the bottom with a thin border above it.
Services not showing as a grid?
Make sure your HTML has class="services-grid" on the <div> wrapping your four service cards. The CSS targets that exact class name.
Also confirm each card has class="service-card". A missing class means the border and padding will not appear.
help me debug why my CSS Grid is not creating columns
Add responsive design for mobile screens
Your site looks great on a wide screen, but many visitors will view it on a phone or tablet. A media query lets you override styles when the browser window is narrower than a certain width.
- Add the responsive media query at the very bottom of styles.css:
/* Responsive Design */
@media (max-width: 768px) {
.nav-container {
flex-direction: column;
gap: 1rem;
}
.nav-links {
gap: 1rem;
}
.hero {
padding: 7rem 1.5rem 3rem;
}
.hero h1 {
font-size: 2rem;
}
.services-grid {
grid-template-columns: 1fr;
}
.section {
padding: 3rem 1.5rem;
}
}
What does this code do?
The @media (max-width: 768px) block applies only when the screen is 768 pixels wide or narrower. Inside it, the nav stacks vertically, the services grid switches to a single column, and padding shrinks to fit smaller screens.
This single breakpoint handles tablets and phones. The layout stays readable without needing to pinch or scroll horizontally.
- Save styles.css and refresh your browser.
- Drag the edge of your browser window to make it narrower. When the window is below 768px wide, the navigation links should stack under the logo, and the service cards should switch to a single column.
Layout not changing when you resize?
Make sure the @media block is at the very bottom of your file. If other styles come after it, they can override the responsive rules.
Check that the opening and closing curly braces match. The media query has an outer pair of braces wrapping all the inner selectors, which each have their own braces.
help me debug why my responsive media query is not working
✔️ Awesome, I've got everything!
Great. Double check you have saved styles.css and that your site looks professional on both wide and narrow screens.
ⓧ I'd like to double check the full code
Here is the complete styles.css file. Compare it against yours:
:root {
--color-primary: #2b4c7e;
--color-primary-light: #3d6098;
--color-accent: #5b8fb9;
--color-bg: #ffffff;
--color-bg-alt: #f4f7fa;
--color-text: #333333;
--color-text-light: #666666;
--color-border: #e0e0e0;
--font-main: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
--max-width: 900px;
}
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
body {
font-family: var(--font-main);
line-height: 1.7;
color: var(--color-text);
background-color: var(--color-bg);
}
/* Navigation */
.navbar {
position: fixed;
top: 0;
width: 100%;
background-color: var(--color-bg);
border-bottom: 1px solid var(--color-border);
z-index: 100;
}
.nav-container {
max-width: var(--max-width);
margin: 0 auto;
padding: 1rem 2rem;
display: flex;
justify-content: space-between;
align-items: center;
}
.nav-logo {
font-size: 1.2rem;
font-weight: 700;
color: var(--color-primary);
text-decoration: none;
}
.nav-links {
list-style: none;
display: flex;
gap: 2rem;
}
.nav-links a {
text-decoration: none;
color: var(--color-text-light);
font-weight: 500;
transition: color 0.2s;
}
.nav-links a:hover {
color: var(--color-primary);
}
/* Hero Section */
.hero {
text-align: center;
padding: 8rem 2rem 4rem;
background-color: var(--color-bg-alt);
}
.hero h1 {
font-size: 2.5rem;
color: var(--color-primary);
margin-bottom: 0.5rem;
}
.subtitle {
font-size: 1.3rem;
color: var(--color-accent);
margin-bottom: 1rem;
}
.tagline {
font-size: 1.1rem;
color: var(--color-text-light);
max-width: 600px;
margin: 0 auto;
}
/* Sections */
.section {
padding: 4rem 2rem;
}
.section-alt {
background-color: var(--color-bg-alt);
}
.container {
max-width: var(--max-width);
margin: 0 auto;
}
.section h2 {
font-size: 1.8rem;
color: var(--color-primary);
margin-bottom: 1.5rem;
}
.section p {
margin-bottom: 1rem;
color: var(--color-text-light);
}
/* Services Grid */
.services-grid {
display: grid;
grid-template-columns: repeat(2, 1fr);
gap: 1.5rem;
margin-top: 1.5rem;
}
.service-card {
background-color: var(--color-bg);
border: 1px solid var(--color-border);
border-radius: 8px;
padding: 1.5rem;
}
.service-card h3 {
color: var(--color-primary);
margin-bottom: 0.5rem;
}
.service-card p {
font-size: 0.95rem;
}
/* Contact */
.contact-email a {
color: var(--color-accent);
text-decoration: none;
}
.contact-email a:hover {
text-decoration: underline;
}
/* Footer */
.footer {
text-align: center;
padding: 2rem;
border-top: 1px solid var(--color-border);
color: var(--color-text-light);
font-size: 0.9rem;
}
/* Responsive Design */
@media (max-width: 768px) {
.nav-container {
flex-direction: column;
gap: 1rem;
}
.nav-links {
gap: 1rem;
}
.hero {
padding: 7rem 1.5rem 3rem;
}
.hero h1 {
font-size: 2rem;
}
.services-grid {
grid-template-columns: 1fr;
}
.section {
padding: 3rem 1.5rem;
}
}
Your portfolio now looks polished and professional. Next up, you will push this site live on the internet using Git and GitHub Pages.
Push to GitHub and Deploy with GitHub Pages
Your portfolio looks great locally, but right now only you can see it. To share it with the world, you need to put your files somewhere the internet can access them.
In this step, you will use Git to track your project files, push them to GitHub, and turn on GitHub Pages to publish your site as a live website. All for free.
In this step, get ready to:
- Initialize a Git repository and make your first commit.
- Create a GitHub repository and push your code to it.
- Enable GitHub Pages so your site goes live on the internet.
Initialize a Git repository and make your first commit
Git needs to know which folder to track before it can save snapshots of your work. Initializing a repository tells Git to start watching the portfolio folder.
- In the VS Code terminal (which should already be open in your portfolio folder), initialize a Git repository, stage all your files, and make your first commit by running these commands:
git init
git add .
git commit -m "Initial commit: portfolio website"
What do these commands do?
- git init creates a hidden .git folder that turns your project into a Git repository.
- git add . stages all files in the folder, telling Git you want to include them in the next snapshot.
- git commit -m "..." saves a permanent snapshot of your staged files with a descriptive message.
- You should see output confirming that files were committed. Look for a message mentioning 2 files changed (your index.html and styles.css).
Seeing an error about identity?
If Git says it does not know who you are, your global config may not have saved properly from Step 1. Re-run the config commands from earlier:
git config --global user.name "Your Name"
git config --global user.email "your-email@example.com"
Then run the git commit command again.
Help me fix my Git identity error
Create a GitHub repository and push your code
Now your files are saved locally in Git. To get them onto the internet, you need to create a matching repository on GitHub and push your commit to it.
Why does the repository name matter?
GitHub Pages user sites require the repository to be named exactly yourusername.github.io (using your actual GitHub username). This special naming convention tells GitHub to automatically serve the files as a website at that URL.
- Open your browser and go to https://github.com.
- Click the + icon in the top right corner of the page.
- Click New repository.
- In the Repository name field, type your GitHub username followed by .github.io (for example, if your username is janedoe, type janedoe.github.io).
- Make sure Public is selected (GitHub Pages requires a public repository on free accounts).
- Do NOT check Add a README file. Leave all optional settings unchecked.
- Click Create repository.
GitHub now shows a page with setup instructions. You will use the commands under the heading that says something like "push an existing repository from the command line".
- Switch back to your VS Code terminal and connect your local repository to GitHub by running these commands:
git remote add origin https://github.com/[[GITHUB_USERNAME="your GitHub username"]]/[[GITHUB_USERNAME="your GitHub username"]].github.io.git
git branch -M main
git push -u origin main
What do these commands do?
- git remote add origin connects your local repository to the GitHub repository you just created.
- git branch -M main renames your default branch to main (the standard name GitHub expects).
- git push -u origin main uploads your committed files to GitHub.
💡 What is the browser sign-in window?
When you run the push command for the first time, Git Credential Manager will open a browser window asking you to sign in to GitHub. This is normal. Click the button to authorize the connection, then return to VS Code.
After signing in once, Git remembers your credentials so you will not be asked again.
- After the push completes, refresh your repository page on GitHub. You should see your index.html and styles.css files listed.
Push failed or permission denied?
Double-check that your repository name matches your GitHub username exactly (all lowercase). Also make sure you did not check the "Add a README" box when creating the repository.
If you see a credential error, try closing the browser sign-in window and running git push -u origin main again.
Help me fix my git push error
Enable GitHub Pages
Your code is on GitHub, but it is not yet being served as a website. You need to tell GitHub to treat this repository as a live site.
- On your repository page on GitHub, click Settings in the top navigation bar.
- In the left sidebar under Code and automation, click Pages.
- Under Build and deployment, find the Source dropdown and select Deploy from a branch.
- Under Branch, select main from the first dropdown. Leave the folder set to / (root).
- Click Save.
How long does deployment take?
GitHub Pages typically takes 1-2 minutes to build and deploy your site. It can take up to 10 minutes in some cases. Be patient if your site does not appear immediately.
- Wait 1-2 minutes, then open a new browser tab.
- Type your site URL in the address bar: https://your GitHub username.github.io and press Enter.
- You should see your complete portfolio website live on the internet.
Seeing a 404 page?
If you see a 404 error, wait a few more minutes and refresh. Deployment can take up to 10 minutes.
If it still does not work after 10 minutes, go back to Settings > Pages and confirm the branch is set to main and the folder is / (root). Also confirm your repository name is exactly yourusername.github.io (with your real username).
Help me fix my GitHub Pages 404 error
Your portfolio is live on the internet for anyone to see. Next up, take on the Secret Mission to add a dark mode toggle with JavaScript.
Secret mission
Add a Dark Mode Toggle
Your portfolio looks great, but what about visitors who prefer browsing at night? In this secret mission, you will add a dark mode toggle using JavaScript that remembers each visitor's preference across page refreshes.
Clean Up Your Resources
Clean Up Your Resources
This project runs entirely for free. Your GitHub Pages site, GitHub repository, and GitHub account are all on the free tier with no ongoing charges.
Decide whether to keep your resources running, pause them to come back later, or delete them entirely.
Resources you used:
- GitHub account (free, no charges).
- GitHub repository (free for public repositories).
- GitHub Pages site (free, no bandwidth charges for normal usage).
- Local portfolio folder on your Desktop.
Keep everything running
No action needed. Choose this if you are still actively building or want your portfolio to stay live.
- Your site stays live indefinitely at no cost.
- GitHub Pages has a soft bandwidth limit of 100 GB per month, which a personal portfolio will never approach.
- To update your site in the future, edit your files locally, then run git add ., git commit -m "description", and git push. Changes go live within 1-2 minutes.
Pause - I'll come back to this later
Your GitHub Pages site stays live with no ongoing cost, so there is nothing to pause on the hosting side. You can close VS Code and your terminal to free up local memory.
- Close VS Code.
- Your site remains live at your GitHub Pages URL until you decide to delete the repository.
- When you are ready to resume, open the portfolio folder in VS Code again and pick up where you left off.
Delete - I don't want to use this again
Remove all project resources and start fresh. This takes down your live site and removes the local files.
- Delete the GitHub repository (this also removes your GitHub Pages site):
- Go to your repository page on GitHub and click Settings.
- Scroll down to the Danger Zone section and click Delete this repository.
- Click I want to delete this repository, read the warnings, then click I have read and understand these effects.
- Type the name of your repository to confirm, then click Delete this repository.
- Delete the local portfolio folder from your Desktop by dragging it to the Trash in your Dock, or by right-clicking it in Finder and selecting Move to Trash.
What about your GitHub account?
Your GitHub account is free and useful for future projects. If you do want to delete it, go to Settings then Account, scroll to Delete account, and click Delete your account. This is permanent and cannot be undone.
Nice Work!
Nice Work!
Nice work! You just built and deployed a professional psychology portfolio website from scratch using only free tools. Your site is live on the internet for anyone to visit.
You've learned how to:
- Build a complete website using semantic HTML elements (header, nav, main, section, footer) to structure content meaningfully.
- Style a professional, responsive layout with CSS custom properties and media queries that adapt to any screen size.
- Set up Git version control and deploy a live website on GitHub Pages at zero cost.
- Secret Mission: Added a JavaScript dark mode toggle with localStorage persistence that remembers visitor preferences across page refreshes.
Ready to quiz yourself?