Resume Builder with HTML, CSS & JavaScript
40 DAYS 40 PROJECT CHALLENGE
Day #08
Project Overview
The Resume Builder is an interactive web application developed using HTML, CSS, and JavaScript. It allows users to create a professional resume by entering personal details, professional information, education, work experience, and skills. Users can select from three resume templates and after entering their information, they can generate a structured resume preview and download it as a PDF file.
JavaScript manages form data, updates the resume preview, saves information in LocalStorage, and loads previously saved details when the page opens. Additionally, users can rearrange resume sections through drag-and-drop functionality. This project is useful for learning dynamic form handling, DOM manipulation, LocalStorage, template switching, PDF generation, and interactive UI development.
Key Features
- Personal Information Form: Users can enter their full name, professional title, email address, phone number, and professional summary. These details are displayed in the resume preview after generation.
- Multiple Resume Templates: The application provides three template options: Harvard, Corporate, and Modern. Users can switch between these templates to change the visual appearance of their resume.
- Dynamic Education Entries: Users can add multiple education details using the Add Education button. JavaScript creates input fields dynamically, allowing users to enter their academic qualifications.
- Dynamic Experience Entries: The Add Experience button creates additional input fields for work experience. Users can include multiple professional experiences in their resume.
- Resume Generation: When users click the Generate Resume button, JavaScript collects the entered information and updates the resume preview with personal details, education, experience, and skills.
- Skills Management: Users can enter multiple skills separated by commas. JavaScript splits the input and displays each skill as an individual list item in the resume preview.
- Professional Resume Preview: The generated resume includes a sidebar for personal information and skills, along with a main section containing the professional summary, experience, and education.
- LocalStorage Data Saving: Resume information is stored in the browser using LocalStorage. This allows the application to preserve data and load it again when the page is reopened.
- PDF Download: Users can download their generated resume as a PDF file and it uses the
html2pdf.jslibrary to convert the resume preview into a downloadable document. - Drag-and-Drop Sections: Resume sections can be rearranged using drag-and-drop events. Users can move the summary, experience, and education sections into a different order.
- Responsive Form Layout: The input form and resume preview use structured layouts with spacing, padding, and flexible styling. The form container also supports scrolling when it contains many fields.
- Custom Template Styling: CSS classes such as
.template-corporateand.template-modernapply different sidebar and heading styles. This allows the resume preview to change its appearance based on the selected template.
What You'll Learn
- How to handle multiple form inputs with JavaScript.
- How to generate dynamic input fields using
createElement(). - How to update resume content using DOM manipulation.
- How to manage education and experience data using arrays.
- How to store resume information using LocalStorage.
- How to load saved data when the page opens.
- How to switch templates using CSS classes.
- How to integrate the
html2pdf.jslibrary. - How to implement drag-and-drop section reordering.
- How to use template literals for dynamic HTML generation.
HTML Code
The HTML structure creates the resume builder form and preview section. The main .container includes a template dropdown, personal information inputs, professional summary textarea, and skills input. These educationList and experienceList containers are initially empty. JavaScript adds input fields to these containers when users click the Add Education or Add Experience buttons. The Generate Resume and Download PDF buttons trigger their respective JavaScript functions.
The resume preview is placed inside the resumePreview element. It includes a sidebar containing the user’s name, professional title, contact details, and skills. The main section contains draggable sections for the professional summary, experience, and education. Finally, the HTML file imports the html2pdf.js library, external CSS file, and JavaScript file.
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Premium Resume Builder</title>
<link rel="stylesheet" href="style.css">
<script src="https://cdnjs.cloudflare.com/ajax/libs/html2pdf.js/0.10.1/html2pdf.bundle.min.js"></script>
</head>
<body>
<div class="container">
<h2>Resume Builder</h2>
<label>Template</label>
<select id="templateSelect">
<option value="harvard">Harvard</option>
<option value="corporate">Corporate</option>
<option value="modern">Modern</option>
</select>
<input id="name" placeholder="Full Name">
<input id="title" placeholder="Professional Title">
<input id="email" placeholder="Email">
<input id="phone" placeholder="Phone">
<textarea id="summary" placeholder="Professional Summary"></textarea>
<h3>Education</h3>
<div id="educationList"></div>
<button id="addEducation">Add Education</button>
<h3>Experience</h3>
<div id="experienceList"></div>
<button id="addExperience">Add Experience</button>
<input id="skills" placeholder="Skills (comma separated)">
<button id="generateBtn">Generate Resume</button>
<button id="downloadBtn">Download PDF</button>
</div>
<!-- Resume Preview -->
<div class="preview template-harvard" id="resumePreview">
<div class="sidebar">
<h1 id="pName">Your Name</h1>
<h3 id="pTitle"></h3>
<p id="pContact"></p>
<h2>Skills</h2>
<ul id="pSkills"></ul>
</div>
<div class="main" id="dragArea">
<div class="section" draggable="true">
<h2>Professional Summary</h2>
<p id="pSummary"></p>
</div>
<div class="section" draggable="true">
<h2>Experience</h2>
<div id="pExperience"></div>
</div>
<div class="section" draggable="true">
<h2>Education</h2>
<div id="pEducation"></div>
</div>
</div>
</div>
<script src="script.js"></script>
</body>
</html> CSS Code
The CSS code creates a two-section resume builder layout with a form panel and a resume preview and the body selector uses Flexbox, spacing, and a dark blue background to position both sections side by side, .container class styles the input form with a white background, padding, rounded corners, and scrolling support. These input, textarea, and select selectors provide consistent spacing, borders, and rounded edges for form controls.
The .preview class defines the resume document’s width, minimum height, white background, and Flexbox layout, while the .sidebar selector creates the left section containing personal information and skills, .main styles the primary resume content area and the .section class adds spacing between resume sections and uses cursor: move to indicate that the sections can be rearranged. The .section h2 selector adds a blue bottom border to each heading.
Template-specific selectors, including .template-corporate .sidebar and .template-modern .sidebar, change the sidebar colors. The .template-modern .section h2 selector also applies a different heading border color.
*{
margin:0;
padding:0;
box-sizing:border-box;
font-family:'Segoe UI',Arial;
}
body{
display:flex;
gap:30px;
padding:30px;
background:#042354;
justify-content:center;
}
/* Form */
.container{
width:35%;
background:white;
padding:25px;
border-radius:16px;
box-shadow:0 10px 30px rgba(0,0,0,0.08);
height:95vh;
overflow:auto;
}
input, textarea, select{
width:100%;
padding:10px;
margin-bottom:12px;
border:1px solid #e5e7eb;
border-radius:8px;
font-size:14px;
}
textarea{
resize:none;
height:80px;
}
button{
width:100%;
padding:10px;
border:none;
background:#2563eb;
color:white;
border-radius:8px;
cursor:pointer;
font-weight:600;
margin-bottom:10px;
}
button:hover{
background:#1d4ed8;
}
/* Resume */
.preview{
width:794px;
min-height:1123px;
background:white;
border-radius:10px;
overflow:hidden;
display:flex;
}
.sidebar{
width:30%;
background:#1e293b;
color:white;
padding:30px 20px;
}
.sidebar h1{
font-size:22px;
margin-bottom:5px;
}
.sidebar h3{
font-size:14px;
margin-bottom:15px;
color:#cbd5e1;
}
.sidebar p{
font-size:13px;
margin-bottom:6px;
}
.sidebar h2{
margin-top:20px;
margin-bottom:10px;
font-size:14px;
text-transform:uppercase;
border-bottom:1px solid rgba(255,255,255,0.2);
padding-bottom:5px;
}
.main{
width:70%;
padding:40px;
}
.section{
margin-bottom:25px;
cursor:move;
}
.section h2{
font-size:16px;
margin-bottom:10px;
border-bottom:2px solid #2563eb;
padding-bottom:5px;
}
.section p{
font-size:14px;
margin-bottom:8px;
line-height:1.5;
}
ul{
margin-left:18px;
}
ul li{
font-size:14px;
margin-bottom:6px;
}
/* Templates */
.template-corporate .sidebar{
background:#0f172a;
}
.template-modern .sidebar{
background:#111827;
}
.template-modern .section h2{
border-bottom:2px solid #38bdf8;
} Javascript Code
The JavaScript code manages form inputs, resume generation, data storage, template switching, PDF downloads, and drag-and-drop functionality. First, the code selects the input fields and preview elements using document.getElementById(). The createInput() function dynamically creates input fields for education and experience details. It assigns a placeholder, sets the initial value, adds an input event listener for saving data, and appends the field to the selected container.
The generateResume() function transfers the personal details into the preview using properties such as innerText. It also loops through the education and experience input fields and displays their values as paragraphs. Skills are separated using split(","), trimmed, and inserted into the skills list and the saveData() function creates a data object containing personal information, skills, education, and experience. It then converts the object into JSON using JSON.stringify() and stores it in LocalStorage under the resumeData key.
The loadData() function retrieves the saved information, restores the form values, recreates education and experience inputs, and generates the resume preview. Download PDF button uses html2pdf() with configured options for filename, image quality, canvas scale, and A4 page formatting. Finally, drag-and-drop event listeners allow users to rearrange resume sections by moving the dragged section before the selected section.
const nameInput = document.getElementById("name")
const titleInput = document.getElementById("title")
const emailInput = document.getElementById("email")
const phoneInput = document.getElementById("phone")
const summaryInput = document.getElementById("summary")
const skillsInput = document.getElementById("skills")
const pName = document.getElementById("pName")
const pTitle = document.getElementById("pTitle")
const pContact = document.getElementById("pContact")
const pSummary = document.getElementById("pSummary")
const pEducation = document.getElementById("pEducation")
const pExperience = document.getElementById("pExperience")
const pSkills = document.getElementById("pSkills")
const educationList = document.getElementById("educationList")
const experienceList = document.getElementById("experienceList")
/* Create Inputs */
function createInput(container,value=""){
const input = document.createElement("input")
input.placeholder="Enter details"
input.value=value
input.addEventListener("input", saveData)
container.appendChild(input)
}
document.getElementById("addEducation").onclick = ()=>createInput(educationList)
document.getElementById("addExperience").onclick = ()=>createInput(experienceList)
/* Generate Resume */
document.getElementById("generateBtn").onclick = generateResume
function generateResume(){
pName.innerText = nameInput.value || "Your Name"
pTitle.innerText = titleInput.value
pContact.innerText = emailInput.value + " | " + phoneInput.value
pSummary.innerText = summaryInput.value
pEducation.innerHTML=""
educationList.querySelectorAll("input").forEach(e=>{
if(e.value) pEducation.innerHTML += `<p>${e.value}</p>`
})
pExperience.innerHTML=""
experienceList.querySelectorAll("input").forEach(e=>{
if(e.value) pExperience.innerHTML += `<p>${e.value}</p>`
})
pSkills.innerHTML=""
skillsInput.value.split(",").forEach(s=>{
if(s.trim()) pSkills.innerHTML += `<li>${s.trim()}</li>`
})
saveData()
}
/* Save Data */
function saveData(){
const data = {
name:nameInput.value,
title:titleInput.value,
email:emailInput.value,
phone:phoneInput.value,
summary:summaryInput.value,
skills:skillsInput.value,
education:Array.from(educationList.querySelectorAll("input")).map(i=>i.value),
experience:Array.from(experienceList.querySelectorAll("input")).map(i=>i.value)
}
localStorage.setItem("resumeData", JSON.stringify(data))
}
/* Load Data */
function loadData(){
const data = JSON.parse(localStorage.getItem("resumeData"))
if(!data) return
nameInput.value=data.name
titleInput.value=data.title
emailInput.value=data.email
phoneInput.value=data.phone
summaryInput.value=data.summary
skillsInput.value=data.skills
data.education.forEach(val=>createInput(educationList,val))
data.experience.forEach(val=>createInput(experienceList,val))
generateResume()
}
/* Template Switch */
document.getElementById("templateSelect").onchange = function(){
document.getElementById("resumePreview").className =
"preview template-"+this.value
}
/* Download PDF */
document.getElementById("downloadBtn").onclick=function(){
const element=document.getElementById("resumePreview")
const opt={
margin:0,
filename:'resume.pdf',
image:{type:'jpeg',quality:1},
html2canvas:{scale:3},
jsPDF:{unit:'mm',format:'a4',orientation:'portrait'}
}
html2pdf().set(opt).from(element).save()
}
/* Drag Sections */
let dragSrc
document.querySelectorAll(".section").forEach(sec=>{
sec.addEventListener("dragstart",()=>{ dragSrc = sec })
sec.addEventListener("dragover",(e)=>{ e.preventDefault() })
sec.addEventListener("drop",()=>{
if(dragSrc !== sec){
sec.parentNode.insertBefore(dragSrc, sec)
}
})
})
loadData() Related Projects
Day 5 : Chat UI (Frontend Only)
A simple chat interface with message sending and display functionality.
Concepts: DOM manipulation, event handling, dynamic UI updates.
Day 6 : File Upload Progress Bar
File upload interface with a visual progress bar and smooth animation.
Concepts: File API, progress tracking, animations, event handling.
Day 10 : Portfolio Website Builder
Displays animated skeleton loaders while content is loading.
Concepts: Loading states, animations, UI placeholders.