- Published on
Portfolio Project Deep Dive: Building a Professional Survey Form from Scratch
- Authors
- Name
- Md Nasim Sheikh
- @nasimStg
'Portfolio Project Deep Dive: Building a Professional Survey Form from Scratch'
A step-by-step guide to building a responsive, accessible, and visually appealing survey form for your web development portfolio using only HTML and CSS.
Table of Contents
- 'Portfolio Project Deep Dive: Building a Professional Survey Form from Scratch'
- Portfolio Project: How to Build a Professional Survey Form [Part 1]
- Section 1: The Blueprint - Planning Before You Code
- Defining the Purpose
- Sketching the Layout
- Section 2: Laying the Foundation with Semantic HTML
- Key HTML Elements Explained:
- Section 3: Bringing It to Life with Modern CSS
- Step 1: Global Styles and CSS Variables
- Step 2: Styling the Header and Form Container
- Step 3: Styling Form Groups and Controls
- Step 4: Custom Styling for Radio Buttons and Checkboxes
- Step 5: Styling the Submit Button
- Section 4: Ensuring Responsiveness with Media Queries
- Section 5: Best Practices and Final Touches
- Conclusion: Your New Portfolio Project
Portfolio Project: How to Build a Professional Survey Form [Part 1]
Welcome, developers! If you're looking for a project that's perfect for showcasing your foundational web development skills, you've come to the right place. A well-crafted survey form is more than just a simple webpage; it's a testament to your understanding of user experience, accessibility, and modern styling techniques. It's a project that every potential employer can immediately understand and appreciate.
Why is a survey form such a great portfolio piece? Because it demonstrates mastery over the essentials:
- Semantic HTML: Structuring content for meaning and accessibility.
- CSS Styling: From basic layout to advanced custom controls.
- Responsive Design: Ensuring a seamless experience on any device.
- User Experience (UX): Creating an intuitive and easy-to-use interface.
In this comprehensive guide, we'll walk through building a professional-looking "Developer Skills Survey" from the ground up, using only HTML and CSS. We'll focus on best practices that will make your project stand out. By the end, you'll have a polished, portfolio-ready project and a deeper understanding of front-end fundamentals.
Ready to build? Let's get started.
Section 1: The Blueprint - Planning Before You Code
Jumping straight into your code editor is tempting, but a little planning goes a long way. A solid plan ensures you build a logical, user-friendly form and saves you from refactoring headaches later.
Defining the Purpose
First, what information do we want to collect? For our project, we'll create a "Developer Skills Survey." Our goal is to gather:
- Basic Information: Name, Email, Age.
- Professional Role: Current job title.
- Skill Level: A rating of their experience.
- Favorite Technologies: Which languages/frameworks they enjoy.
- Recommendations: Would they recommend this field to others?
- Further Comments: An open-ended feedback area.
Sketching the Layout
You don't need to be a designer. A simple pen-and-paper sketch or a quick digital wireframe is enough. We'll adopt a mobile-first approach: design for a single-column layout on small screens and then adapt for larger screens.
Our sketch might look something like this:
- Header with a title and description.
- A container for the form.
- Groups of questions (e.g., "Your Details," "Your Skills").
- A prominent submit button at the bottom.
Section 2: Laying the Foundation with Semantic HTML
With our plan in place, it's time to write the HTML. We'll use semantic tags not just because it's a best practice, but because it provides a better experience for users of assistive technologies (like screen readers) and improves SEO.
Here's the complete HTML structure. We'll break it down piece by piece.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Developer Skills Survey</title>
<link rel="stylesheet" href="style.css">
</head>
<body>
<header class="header">
<h1 id="title">Developer Skills Survey</h1>
<p id="description">Thank you for taking the time to help us improve our community.</p>
</header>
<form id="survey-form">
<!-- Personal Details Group -->
<fieldset class="form-group">
<legend>Your Details</legend>
<div class="form-control">
<label for="name" id="name-label">Name</label>
<input type="text" id="name" placeholder="Enter your name" required>
</div>
<div class="form-control">
<label for="email" id="email-label">Email</label>
<input type="email" id="email" placeholder="Enter your email" required>
</div>
<div class="form-control">
<label for="number" id="number-label">Age (optional)</label>
<input type="number" id="number" placeholder="Age" min="10" max="99">
</div>
</fieldset>
<!-- Professional Details Group -->
<fieldset class="form-group">
<legend>Your Profession</legend>
<div class="form-control">
<label for="dropdown">Which option best describes your current role?</label>
<select id="dropdown">
<option disabled selected value>Select current role</option>
<option value="student">Student</option>
<option value="junior-dev">Junior Developer</option>
<option value="senior-dev">Senior Developer</option>
<option value="manager">Manager</option>
<option value="other">Other</option>
</select>
</div>
</fieldset>
<!-- Skills and Recommendations Group -->
<fieldset class="form-group">
<legend>Your Skills & Recommendations</legend>
<div class="form-control">
<p>Would you recommend web development to a friend?</p>
<label class="radio-label">
<input type="radio" name="recommend" value="definitely" checked> Definitely
</label>
<label class="radio-label">
<input type="radio" name="recommend" value="maybe"> Maybe
</label>
<label class="radio-label">
<input type="radio" name="recommend" value="not-sure"> Not sure
</label>
</div>
<div class="form-control">
<p>What languages and frameworks are you proficient in? <span class="label-info">(Check all that apply)</span></p>
<label class="checkbox-label"><input type="checkbox" name="skills" value="html"> HTML</label>
<label class="checkbox-label"><input type="checkbox" name="skills" value="css"> CSS</label>
<label class="checkbox-label"><input type="checkbox" name="skills" value="javascript"> JavaScript</label>
<label class="checkbox-label"><input type="checkbox" name="skills" value="react"> React</label>
<label class="checkbox-label"><input type="checkbox" name="skills" value="vue"> Vue.js</label>
<label class="checkbox-label"><input type="checkbox" name="skills" value="backend"> Backend (Node.js, Python, etc.)</label>
</div>
<div class="form-control">
<label for="comments">Any comments or suggestions?</label>
<textarea id="comments" placeholder="Enter your comments here..."></textarea>
</div>
</fieldset>
<button type="submit" id="submit">Submit Survey</button>
</form>
</body>
</html>
Key HTML Elements Explained:
<form id="survey-form">
: The container for our entire form. We give it an ID for easy targeting with CSS and JavaScript.<fieldset>
and<legend>
: These are accessibility power-ups.<fieldset>
groups related form controls, and<legend>
provides a caption for that group. Screen readers announce the legend, giving context to the user.<label for="name">
: This is non-negotiable for accessibility. Thefor
attribute must match theid
of the input it corresponds to. This links them semantically and also allows users to click the label to focus on the input field.placeholder
attribute: Provides a hint to the user about what to enter. Important: It's not a substitute for a<label>
.required
attribute: A simple form of browser-level validation. The form cannot be submitted if this field is empty.- Input Types: We use specific types like
email
andnumber
. This provides better user experience, especially on mobile devices where it can bring up a specialized keyboard. - Radio Buttons (
type="radio"
): Notice they all share the samename="recommend"
. This is crucial! It tells the browser that these buttons are part of a group, and only one can be selected at a time. - Checkboxes (
type="checkbox"
): Each checkbox can be selected independently. They share aname="skills"
to be grouped when the form data is processed. <select>
and<option>
: Creates a dropdown menu. Thedisabled selected value
attributes on the first option create a non-selectable placeholder.<textarea>
: For multi-line text input, perfect for comments.<button type="submit">
: The button to submit the form. Thetype="submit"
is important for it to function correctly within a<form>
tag.
Section 3: Bringing It to Life with Modern CSS
Now for the fun part: styling! A clean, professional design can make your form a pleasure to use. We'll use CSS custom properties (variables) for a maintainable and easily customizable stylesheet.
Create a file named style.css
and link it in your HTML's <head>
section.
Step 1: Global Styles and CSS Variables
Let's start by defining our color palette and fonts at the :root
level. This makes it incredibly easy to change the theme later.
/* Import a font from Google Fonts */
@import url('https://fonts.googleapis.com/css2?family=Poppins:wght@400;500;600;700&display=swap');
/* CSS Variables for easy theme management */
:root {
--color-primary: #1a2a4c;
--color-secondary: #2c3e50;
--color-accent: #3498db;
--color-text: #ecf0f1;
--color-light-gray: #bdc3c7;
--font-family: 'Poppins', sans-serif;
}
/* Basic Reset */
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
body {
font-family: var(--font-family);
font-size: 16px;
background-color: var(--color-primary);
color: var(--color-text);
line-height: 1.6;
}
Step 2: Styling the Header and Form Container
We'll center the content and give the form a distinct container style.
.header {
text-align: center;
padding: 40px 20px 20px;
}
#title {
font-size: 2.5rem;
font-weight: 700;
margin-bottom: 10px;
}
#description {
font-style: italic;
font-weight: 400;
color: var(--color-light-gray);
}
#survey-form {
max-width: 720px;
margin: 0 auto 40px auto;
padding: 40px;
background-color: var(--color-secondary);
border-radius: 8px;
box-shadow: 0 4px 15px rgba(0, 0, 0, 0.2);
}
Step 3: Styling Form Groups and Controls
This is where we style the core elements: labels, inputs, textareas, etc.
.form-group {
border: none; /* Remove default fieldset border */
margin-bottom: 25px;
}
.form-group legend {
font-size: 1.4rem;
font-weight: 600;
color: var(--color-accent);
margin-bottom: 15px;
border-bottom: 2px solid var(--color-accent);
padding-bottom: 5px;
width: 100%;
}
.form-control {
margin-bottom: 20px;
}
/* Style for text-based inputs and select */
.form-control input[type="text"],
.form-control input[type="email"],
.form-control input[type="number"],
.form-control select,
.form-control textarea {
width: 100%;
padding: 12px 15px;
font-family: inherit;
font-size: 1rem;
background-color: var(--color-primary);
border: 2px solid var(--color-light-gray);
border-radius: 5px;
color: var(--color-text);
transition: border-color 0.3s ease;
}
/* Focus state for better UX */
.form-control input:focus,
.form-control select:focus,
.form-control textarea:focus {
outline: none;
border-color: var(--color-accent);
box-shadow: 0 0 5px rgba(52, 152, 219, 0.5);
}
.form-control label {
display: block;
margin-bottom: 8px;
font-weight: 500;
}
.form-control textarea {
min-height: 120px;
resize: vertical; /* Allow vertical resizing */
}
Step 4: Custom Styling for Radio Buttons and Checkboxes
Default radio buttons and checkboxes can look inconsistent across browsers. A common professional technique is to hide the default input and style a custom one using pseudo-elements on the label. This gives you full control over their appearance.
/* Custom Radio and Checkbox Styling */
.radio-label, .checkbox-label {
display: flex;
align-items: center;
margin-bottom: 10px;
cursor: pointer;
position: relative;
}
.radio-label input[type="radio"],
.checkbox-label input[type="checkbox"] {
opacity: 0; /* Hide the default input */
position: absolute;
}
/* Custom appearance */
.radio-label::before, .checkbox-label::before {
content: '';
width: 20px;
height: 20px;
border: 2px solid var(--color-light-gray);
margin-right: 10px;
transition: all 0.2s ease;
}
.radio-label::before {
border-radius: 50%; /* Circles for radio buttons */
}
.checkbox-label::before {
border-radius: 4px; /* Squares for checkboxes */
}
/* Checked state */
.radio-label input[type="radio"]:checked + ::before,
.checkbox-label input[type="checkbox"]:checked + ::before {
background-color: var(--color-accent);
border-color: var(--color-accent);
}
/* Add the checkmark/dot */
.checkbox-label input[type="checkbox"]:checked + ::after {
content: '\2713'; /* Checkmark character */
position: absolute;
left: 4px;
top: 1px;
color: var(--color-secondary);
font-size: 14px;
font-weight: bold;
}
.radio-label input[type="radio"]:checked + ::after {
content: '';
position: absolute;
left: 6px;
top: 6px;
width: 10px;
height: 10px;
background-color: var(--color-secondary);
border-radius: 50%;
}
Step 5: Styling the Submit Button
Finally, let's make the submit button stand out with a clear call to action.
#submit {
display: block;
width: 100%;
padding: 15px;
font-size: 1.2rem;
font-weight: 600;
color: var(--color-text);
background-color: var(--color-accent);
border: none;
border-radius: 5px;
cursor: pointer;
transition: background-color 0.3s ease, transform 0.2s ease;
}
#submit:hover {
background-color: #2980b9; /* A slightly darker shade of accent */
transform: translateY(-2px);
}
Section 4: Ensuring Responsiveness with Media Queries
Our mobile-first approach means the form already looks great on small screens. Now, we'll use a media query to add some refinements for tablets and desktops.
For this simple layout, we don't need much. We'll mainly adjust the padding and font sizes to make better use of the larger screen real estate.
/* Media Query for larger screens (tablets and desktops) */
@media (min-width: 768px) {
#title {
font-size: 3rem;
}
#survey-form {
padding: 50px;
}
}
If you had a more complex form, you could use media queries to create multi-column layouts using Flexbox or Grid for certain sections.
Section 5: Best Practices and Final Touches
You've built a beautiful, functional form. Let's recap some of the key principles that elevate it from a simple page to a professional portfolio piece.
Accessibility (A11y) is Key: We've used
<label>
,<fieldset>
, and<legend>
to ensure our form is navigable for everyone. Our custom controls are built on top of native elements, so keyboard navigation still works perfectly. The high-contrast color scheme also aids readability.Thoughtful User Experience (UX): The form is logically grouped. Required fields are marked. Focus states provide clear visual feedback to the user, letting them know exactly where they are on the page. The
placeholder
text offers helpful hints without replacing the essential labels.Maintainable Code: Using CSS variables (
:root
) means you can re-theme the entire form by changing just a few lines of code. Try creating a light theme by swapping the variable values!Indicate Required Fields Visually: While we have the
required
attribute, it's good practice to add a visual cue. You can do this easily with CSS:/* Add an asterisk to required field labels */ .form-control label[for="name"]::after, .form-control label[for="email"]::after { content: ' *'; color: #e74c3c; /* A red color for the asterisk */ font-weight: bold; }
Conclusion: Your New Portfolio Project
Congratulations! You've successfully built a professional, responsive, and accessible survey form from scratch. You haven't just copied code; you've learned the why behind each choice—from semantic HTML for accessibility to custom CSS controls for a polished user experience.
This project is a fantastic addition to your portfolio. It's a clear, concise demonstration of your command over the fundamental building blocks of the web.
What's Next?
- Customize It! Change the colors, fonts, and questions to make it your own. Create a form for a different topic, like a user feedback form or a registration page.
- Challenge Yourself: Try creating a multi-column layout for some of the fields on larger screens using CSS Flexbox or Grid.
- Stay Tuned for Part 2! In a future article, we'll bring this form to life by adding client-side validation with JavaScript and exploring how to send the data to a backend service.
Happy coding!