Portfolio Website Builder with HTML, CSS & JavaScript

40 DAYS 40 PROJECT CHALLENGE

Day #10

Project Overview

The Portfolio Website Builder is an interactive frontend project developed using HTML, CSS, and JavaScript. It allows users to create a personalized portfolio website by entering their name, professional role, introduction, skills, projects, and email address. Users can enter their information through a simple form and generate a complete portfolio website by clicking the Create Website button. JavaScript dynamically builds the website, including a navigation bar, hero section, About Me section, Skills section, Projects section, and Contact section.

This project is useful for learning form handling, dynamic HTML generation, template literals, string manipulation, DOM updates, CSS Flexbox, and responsive portfolio design.

Key Features

  • Personal Information Form: Users can enter their name, professional role, About Me description, skills, projects, and email address. These details are used to generate their personalized portfolio website.
  • Dynamic Portfolio Generation: It generates a complete portfolio webpage after users click the Create Website button. JavaScript dynamically replaces the existing page content with the generated website structure.
  • Hero Section: The generated website includes a hero section that displays the user’s name and professional role. A gradient background creates a visually appealing introduction area.
  • About Me Section: Users can provide a personal introduction through the About You textarea. The entered content is displayed in the About Me section of the generated portfolio.
  • Skills Display: Users can enter multiple skills separated by commas. JavaScript processes each skill and displays it as an individual rounded tag.
  • Interactive Skill Tags: The skill tags include hover effects that change their background color and slightly increase their size using the CSS transform property.
  • Project Showcase: Users can enter multiple project names separated by commas. JavaScript converts each project into an individual project card within the Projects section.
  • Contact Section: The generated portfolio displays the user’s email address inside the Contact section. If no email is provided, the application uses a default email placeholder.
  • Default Values: JavaScript provides fallback values such as “Your Name,” “Your Role,” and “About you” when users leave certain fields empty. This ensures that the generated website still contains basic content.
  • Modern Visual Design: The portfolio uses a dark color scheme, gradient hero background, rounded project cards, and blue interactive elements to create a contemporary appearance.
  • Responsive Structure: The generated website uses flexible sections and spacing to organize content. However, the provided CSS does not include a dedicated mobile media query, so additional responsive styling may be required for smaller screens.

What You'll Learn

  • How to collect user input using JavaScript.
  • How to use fallback values with the logical OR operator.
  • How to process comma-separated skills and projects.
  • How to use split(), filter(), and map() for data processing.
  • How to generate dynamic HTML using template literals.
  • How to replace webpage content using document.body.innerHTML.
  • How to create navigation links using HTML anchor elements.
  • How to style skill tags and project cards using CSS.

HTML Code

The HTML structure creates the initial portfolio builder form inside the .center and .form-box containers. It includes input fields for the user’s name, professional role, and email addres. This form also contains textareas for the About You description, skills, and projects. The skills and projects fields accept comma-separated values, which JavaScript later processes into individual elements.

The Create Website button calls the createWebsite() function through its onclick attribute. When the function runs, it collects the entered values and generates the portfolio website dynamically. Finally, the HTML file connects the external style.css and script.js files. The initial form is replaced by the generated portfolio after successful execution of the JavaScript function.

<!DOCTYPE html>
<html>
<head>
  <meta charset="UTF-8">
  <title>Premium Portfolio Generator</title>
  <link rel="stylesheet" href="style.css">
</head>
<body>

<div class="center">
  <div class="form-box">
    <h2>Create Your Premium Portfolio</h2>

    <input id="name" placeholder="Your Name">
    <input id="role" placeholder="Your Role">
    <textarea id="about" placeholder="About You"></textarea>
    <textarea id="skills" placeholder="Skills (comma separated)"></textarea>
    <textarea id="projects" placeholder="Projects (comma separated)"></textarea>
    <input id="email" placeholder="Your Email">

    <button onclick="createWebsite()">Create Website</button>
  </div>
</div>

<script src="script.js"></script>
</body>
</html>

CSS Code

The CSS code styles both the initial builder form and the generated portfolio website. The universal selector resets the margin and padding, applies box-sizing: border-box, and enables smooth scrolling through scroll-behavior: smooth. The body selector sets the font family, dark background color, and white text, .center class uses Flexbox to center the form vertically and horizontally across the viewport.

This .form-box class styles the builder form with a dark card background, padding, rounded corners, fixed width, and vertical spacing using display: flex and flex-direction: column. The input and textarea selectors provide consistent padding, border removal, and rounded corners, nav selector creates a fixed navigation bar at the top of the page. It uses Flexbox to position the portfolio name and navigation links, while backdrop-filter adds a blurred background effect.

The .skills span selector styles individual skill tags, including rounded borders and hover animations. Meanwhile, .project styles project cards with padding, spacing, rounded corners, and transition effects. Finally, the .contact class centers the contact section. The provided CSS focuses on the desktop layout and does not contain a specific media query for mobile responsiveness.

*{
margin:0;
padding:0;
box-sizing:border-box;
scroll-behavior:smooth;
}

body{
font-family:'Segoe UI',sans-serif;
background:#0f172a;
color:white;
}

/* FORM UI */

.center{
display:flex;
justify-content:center;
align-items:center;
height:100vh;
}

.form-box{
background:#1e293b;
padding:30px;
border-radius:12px;
width:380px;
display:flex;
flex-direction:column;
gap:10px;
}

input,textarea{
padding:10px;
border:none;
border-radius:6px;
}

textarea{
height:70px;
resize:none;
}

button{
padding:10px;
border:none;
border-radius:6px;
background:#3b82f6;
color:white;
font-weight:bold;
cursor:pointer;
}

button:hover{
background:#2563eb;
}

/* GENERATED WEBSITE */

nav{
position:fixed;
top:0;
width:100%;
background:rgba(15,23,42,0.9);
padding:15px 40px;
display:flex;
justify-content:space-between;
backdrop-filter:blur(10px);
z-index:1000;
}

nav a{
color:white;
text-decoration:none;
margin-left:20px;
}

.hero{
height:800px;
background:linear-gradient(135deg,#3b82f6,#9333ea);
display:flex;
flex-direction:column;
justify-content:center;
align-items:center;
font-size: 40px;
}

section{
padding:100px 40px;
max-width:1000px;
margin:auto;
}

section#skills, section#projects, section#contact {
    padding-top: 0px;
}


.skills span{
display:inline-block;
background:#3b82f6;
padding:8px 15px;
margin:8px;
border-radius:30px;
transition:0.3s;
}

.skills span:hover{
background:#2563eb;
transform:scale(1.1);
}

.project{
background:#1e293b;
padding:20px;
margin-top:20px;
border-radius:10px;
transition:0.3s;
}

.project:hover{
transform:translateY(-5px);
background:#334155;
}

.contact{
text-align:center;
}

Javascript Code

The JavaScript code collects user information and dynamically generates the portfolio website. The createWebsite() function retrieves the name, role, About Me content, and email using document.getElementById().value. If a field is empty, the logical OR operator provides a default value. The skills input is processed using split(","), which converts the comma-separated text into an array, filter() method removes empty values, while map() creates a <span> element for each skill. The resulting elements are combined using join("").

Similarly, the projects input is split into an array and processed using filter() and map(). Each project is converted into a <div class="project"> element, and the generated project elements are joined into one HTML string. The function then replaces the entire document body using document.body.innerHTML. It creates a navigation bar with links to the About, Skills, Projects, and Contact sections. It also generates a hero section containing the user’s name and role.

The About Me section displays the entered description, while the Skills section inserts the generated skill tags. The Projects section displays the dynamically created project cards, and the Contact section shows the user’s email address.

function createWebsite(){

const name=document.getElementById("name").value || "Your Name"
const role=document.getElementById("role").value || "Your Role"
const about=document.getElementById("about").value || "About you"
const email=document.getElementById("email").value || "example@email.com"

const skills=document.getElementById("skills").value
.split(",")
.filter(s=>s.trim()!=="")
.map(s=>`<span>${s.trim()}</span>`)
.join("")

const projects=document.getElementById("projects").value
.split(",")
.filter(p=>p.trim()!=="")
.map(p=>`<div class="project">${p.trim()}</div>`)
.join("")

document.body.innerHTML=`

<nav>
<div><strong>${name}</strong></div>

<div>
<a href="#about">About</a>
<a href="#skills">Skills</a>
<a href="#projects">Projects</a>
<a href="#contact">Contact</a>
</div>
</nav>


<div class="hero">
<h1>${name}</h1>
<h3>${role}</h3>
</div>


<section id="about">
<h2>About Me</h2>
<p>${about}</p>
</section>


<section id="skills">
<h2>Skills</h2>
<div class="skills">
${skills}
</div>
</section>


<section id="projects">
<h2>Projects</h2>
${projects}
</section>


<section id="contact" class="contact">
<h2>Contact</h2>
<p>Email: ${email}</p>
</section>

`

}
Subscribe
Notify of
guest
0 Comments
Oldest
Newest Most Voted
Inline Feedbacks
View all comments

Related Projects

Day 7 : Survey / Poll App

Switches content dynamically using a tab-based navigation UI.

Concepts: DOM manipulation, event handling, UI state management.

Day 8 : Resume Builder

Interactive resume builder with live preview and editable sections.

Concepts: User input handling, dynamic rendering, state management.

Day 12 : AI Cover Letter Generator UI

Interactive comment/input system with real-time display updates.

Concepts: DOM manipulation, event handling, dynamic content updates.