Skip to content

Practice: Build an HTML profile page

Build a complete HTML-only profile page. The page will introduce a person or professional role, show skills and practice projects, provide working page navigation, and use semantic elements to describe each content region.

This assignment is an independent practice project. The requirements define the result, but you choose the profile content and write the HTML. Use the assistance levels when you want more structure.

What you will practice

  • Plan a page from its content and turn that plan into a complete HTML document.
  • Choose semantic elements from the purpose of each content region.
  • Build fragment navigation that connects links to named sections.
  • Verify document structure, heading order, nesting, lists, and links in the browser.
  • Record and push meaningful project checkpoints with Git and GitHub.

A profile page uses the same HTML decisions as a portfolio, team page, consultant biography, or staff directory entry. The page also gives you a stable document that you can style when you begin CSS.

  • New: Planning and completing a multi-section page without copying a full worked example, while choosing useful version-control checkpoints.
  • Reused: The HTML document structure, tags, attributes, nesting, headings, paragraphs, lists, links, semantic regions, and fragment links from the preceding lessons, plus the solo Git and GitHub workflow.

Starting point

Before you start

  • VS Code and a current version of Edge, Chrome, or Firefox.
  • Git is installed and your commit identity is configured.
  • A GitHub account that you can sign in to.
  • A course folder where you can create a new exercise project.
  • The completed HTML, Git, and GitHub lessons for reference.
  • No starter files are required.
Current state
You have HTML examples and one GitHub repository from the lessons, but the html-profile folder, its index.html file, and its repository do not exist yet.
First action
Create a folder named html-profile, open that folder in VS Code, and create index.html.
First checkpoint
The browser opens index.html, and the first working document commit appears in the private html-profile repository on GitHub.
Help trigger
Open the assistance inside the current checkpoint or ask for help if the browser result differs from the stated check or you do not know which test to run next.

Requirements

The required assignment is complete when every applicable criterion below is met.

Required page behavior

  • index.html opens as a web page and shows a page title in the browser tab.
  • The page navigation contains links to About, Skills, Projects, and Contact content on the same page.
  • Each navigation link has an href value that exactly matches one unique section id.
  • The page contains an About paragraph, a skills list with at least four items, two project entries, a current-focus note, and one descriptive contact or professional-profile link.

Semantic HTML and accessibility

  • The document declares HTML, uses html lang="en", and contains head and body elements.
  • The page-level structure uses header, nav, main, and footer for content that matches those purposes.
  • About, Skills, Projects, and Contact use section elements with headings.
  • Each project entry uses an article element, and the related current-focus note uses an aside element.
  • The page has one h1. Section headings use h2, and project headings use h3.
  • Link text identifies its destination or purpose without relying on surrounding text.

Technical constraints

  • Build the required page with HTML only. Do not add CSS or JavaScript in this assignment because the current assessment concerns HTML structure.
  • Keep all required page content in html-profile/index.html.
  • Indent nested elements consistently so the source structure remains readable.
  • Use elements for their meaning. Do not use br elements to create visual spacing or heading levels to choose a text size.

Version control and GitHub

  • html-profile is a Git repository on main with a private GitHub repository connected as origin.
  • The repository contains separate commits for the working document, the navigation and regions, and the complete profile content.
  • Each commit contains only the intended saved version of index.html and uses the checkpoint message stated in this assignment.
  • The final local working tree is clean, and the GitHub main branch contains the latest required commit.

Design and content freedom

  • Choose a real, fictional, or role-based profile.
  • Choose the name, introduction, skills, project topics, current focus, and safe contact method.
  • Write original content or adapt the reference content. Keep the required section purposes and heading hierarchy.

Out of scope

  • The required page does not need visual styling, columns, responsive layout, images, icons, animation, or custom fonts.
  • The required page does not need a contact form, data storage, JavaScript behavior, hosting, or a public URL.
  • The required Git workflow does not use a feature branch, pull request, merge, or public repository.
  • You do not need to complete an optional extension.

The required assignment is complete when every requirement applies to the saved index.html, all four navigation links reach the correct content, the Git history contains the three required checkpoint commits, the private GitHub repository contains the latest commit, the complete self-check passes, and you can explain two semantic element choices from the purpose of their content.

The browser will use its default appearance because the project contains no CSS. That unstyled result is expected for this assignment.

Choose the profile type before you write the page content:

  1. Personal profile: Use information you are comfortable showing in class.
  2. Fictional profile: Invent a person and realistic practice projects.
  3. Role profile: Describe a role such as “Web development student” without presenting it as a specific real person.

Prepare these content parts:

  • one profile name and one-sentence introduction;
  • one About paragraph of two to four sentences;
  • at least four skills;
  • two practice projects, each with a name and short description;
  • one current learning focus; and
  • one safe contact method or public professional-profile link.

If content choice blocks the start, use the fictional profile from the assignment-wide reference solution and change the wording after the structure works. The assignment assesses the HTML structure, not the amount of personal information.

Complete the browser check first. Then use Git to record that working state before you begin the next checkpoint.

Working state Required commit message
The first HTML document opens Create profile page document
The semantic regions and navigation work Add profile navigation and regions
The complete profile content appears Add complete profile content

For each commit, save index.html, inspect git status and git diff, stage only index.html, inspect git diff --staged, commit with the stated message, and push. This repetition is the Git practice for the project.

Checkpoint 1: Open a working HTML document

Section titled “Checkpoint 1: Open a working HTML document”
  1. Create html-profile inside your Level 1 exercises folder.
  2. Open html-profile as the workspace root in VS Code.
  3. Create index.html.
  4. Add the document declaration and the html, head, and body elements.
  5. Set lang="en" on the html element.
  6. In head, add UTF-8 character encoding, a browser-tab title, and this viewport setting:
Required viewport setting
<meta name="viewport" content="width=device-width, initial-scale=1">

The viewport setting tells mobile browsers to use the device width when the page receives responsive CSS later.

  1. In body, add one h1 with the profile name or role.
  2. Save index.html and open it in the browser.

The browser tab shows the title from the title element. The page area shows the text from the h1 element. The browser does not show raw tags.

Open the VS Code terminal and run:

Create the repository and first commit
git init -b main
git status
git add index.html
git diff --staged
git commit -m "Create profile page document"

Create an empty private GitHub repository named html-profile. Do not add a README, .gitignore, or license on GitHub. Copy its HTTPS URL, then replace the URL in the first command below with the value you copied:

Connect and push the repository
git remote add origin https://github.com/YOUR-USERNAME/html-profile.git
git remote -v
git push -u origin main

Reload the private GitHub repository. Confirm that it shows index.html and the commit message Create profile page document.

Open this support if the document does not produce the expected browser result. For a supplied page structure, use the assignment-wide assistance.

Assistance 1 — Confirm the file and the current target

Work only in html-profile/index.html. The current target is a saved HTML document that shows a tab title and one visible main heading in the browser. Do not add the page regions or navigation until this result works.

Assistance 2 — Check why the document does not render as expected

Compare the browser result with these checks:

  • If the browser shows HTML source as text, confirm that the exact file name ends with .html and not .txt.
  • If the browser tab has no useful title, confirm that title is inside head.
  • If the page has no visible main heading, confirm that h1 is inside body.
  • If a recent change does not appear, save index.html and reload the same file in the browser.

Repeat the Checkpoint 1 test after you change one item.

Checkpoint: The profile document opens

What now works
index.html opens in the browser, the tab has a profile title, the page shows one main heading, and the first commit appears in the private GitHub repository.
Files changed
html-profile/index.html, html-profile/.git/
What remains
Add the page-level semantic regions, named content sections, and fragment navigation.
Next action
Inside body, place the page-level header before main and the page-level footer after main.
If it does not work
Confirm that the file is named index.html, save it, and check that title is inside head while h1 is inside body.

This is a safe stopping point. If you stop here, record: The document opens. Next, add header, nav, main, and footer inside body.

Checkpoint 2: Build the page regions and navigation

Section titled “Checkpoint 2: Build the page regions and navigation”

Organize the body in this order:

  1. A page-level header that contains a short profile label and the primary nav.
  2. One main element that contains the unique profile content.
  3. A page-level footer that contains closing information.

Inside nav, add links for these four destinations:

Link text href value Matching section attribute
About #about id="about"
Skills #skills id="skills"
Projects #projects id="projects"
Contact #contact id="contact"

Place the links inside a ul. Navigation order does not represent a required sequence, so an unordered list is appropriate.

Inside main, keep the existing h1 and add four section elements. Give each section the matching id from the table and an h2 heading that names the section.

Save and reload the page. Select each navigation link. The browser URL must end with the matching fragment, such as #projects. The browser moves to the target when the page is long enough to scroll.

If the full page fits in the browser window, the URL can change without visible movement. Make the window shorter to observe the movement.

After all four navigation links pass the check, run:

Commit the semantic outline
git status
git diff
git add index.html
git diff --staged
git commit -m "Add profile navigation and regions"
git push

Confirm that GitHub shows Add profile navigation and regions as the newest commit.

Open the level that matches the current problem. For a supplied page structure, use the assignment-wide assistance.

Assistance 2 — Match each navigation link with one section

Remove the # from a link’s href value. The remaining text must equal the target section’s id value. For example, href="#skills" connects to id="skills".

Check one pair at a time. Save, reload, and select that link before you inspect the next pair.

Assistance 3 — Build the page regions in a stable order

Use this order if the elements have become difficult to place:

  1. Keep header, main, and footer as siblings inside body.
  2. Put nav and its ul inside header.
  3. Keep the existing h1 inside main.
  4. Add the About, Skills, Projects, and Contact sections inside main.
  5. Add one matching navigation link for each section.
  6. Save and test all four links in the browser.

Checkpoint: The semantic outline and navigation work

What now works
The body contains header, nav, main, four named sections, and footer. Each navigation link updates the URL with the matching fragment, and GitHub shows the second checkpoint commit.
Files changed
html-profile/index.html, html-profile/.git/
What remains
Replace the section placeholders with complete profile content, project articles, a related aside, and a descriptive link.
Next action
Find the About section and write its paragraph below the h2 heading.
If it does not work
Compare each href value with its target id character by character, then confirm that every section remains inside main.

This is a safe stopping point. If you stop here, record the first section that still needs content and the exact next element you will add.

Checkpoint 3: Add the complete profile content

Section titled “Checkpoint 3: Add the complete profile content”

Work through one content type at a time. Keep one active checkpoint instead of changing several sections at once.

Directly after the h1, add a short paragraph that states the profile role or focus. In the About section, add one paragraph of two to four sentences.

The h1 identifies the complete page. The h2 identifies the About section within that page.

Inside the Skills section, add a ul with at least four li elements. Use an unordered list because the skills do not form a sequence.

Inside the Projects section, add at least two article elements. Each article must contain:

  • an h3 project name; and
  • a paragraph that states what the project contains or what you practiced.

Use article because each project entry is a self-contained item that could make sense in another project list or on its own page.

Add one aside inside main, after the Projects section. Give it an h2 named Current focus and a short paragraph.

Use aside because the note is related to the profile but is not one of the four primary profile sections. The profile still makes sense without it.

Inside the Contact section, add a paragraph and one descriptive link. You can link to:

  • a school-approved public profile;
  • a professional platform page;
  • a project page; or
  • a practice email address such as hello@example.com with href="mailto:hello@example.com".

Use link text such as Email Sam Rivera or View Sam Rivera’s GitHub profile. Do not use click here because it does not identify the destination when read by itself.

Add one short paragraph to the page-level footer. Use stable closing text, such as Built as an HTML practice project. A current date is optional.

Read the rendered page from top to bottom. Confirm that it contains all required content. Then read the source from the opening body tag to the closing body tag and match each opening tag with its closing tag.

After the content check passes, run:

Commit the complete content
git status
git diff
git add index.html
git diff --staged
git commit -m "Add complete profile content"
git push

Confirm that GitHub shows Add complete profile content as the newest commit.

Open the level that provides the structure you need. For a supplied page structure or complete fictional content, use the assignment-wide assistance.

Assistance 2 — Review which element holds each content type

Match each content type with its purpose:

  • section: one named primary profile topic;
  • ul: skills that do not form a sequence;
  • article: one project entry that can stand on its own;
  • aside: the related Current focus note;
  • footer: closing information for the complete page.

Use link text that identifies its destination or action without the surrounding sentence.

Assistance 3 — Add and test one content group at a time

Complete the content in this order:

  1. Add the introduction and About paragraph.
  2. Add the skills list.
  3. Add the first project article, then the second project article.
  4. Add the Current focus aside.
  5. Add the descriptive contact or profile link.
  6. Add the page footer.

Save and inspect each content group before you continue to the next one.

Checkpoint: The profile content is complete

What now works
The page shows all required profile content, and GitHub shows the third checkpoint commit.
Files changed
html-profile/index.html, html-profile/.git/
What remains
Verify the heading hierarchy, element purposes, link targets, nesting, and saved browser result.
Next action
List the page headings in source order and confirm that they form one h1, section h2 headings, and project h3 headings.
If it does not work
Check one section at a time. Confirm its heading first, then its required content, then its closing section tag.

This is a safe stopping point. If you stop here, record the first unchecked item from the final self-check.

Checkpoint 4: Review the document as a developer

Section titled “Checkpoint 4: Review the document as a developer”

Complete these focused reviews in order.

Write down or read the headings in source order. The hierarchy must use:

Required heading hierarchy
h1: Profile name or role
h2: About
h2: Skills
h2: Projects
h3: First project name
h3: Second project name
h2: Current focus
h2: Contact

The heading level describes the content hierarchy. It does not select a visual size.

Confirm these relationships in the source:

  • header, main, and footer are siblings inside body;
  • nav is inside the page-level header;
  • the four primary section elements and the aside are inside main;
  • both article elements are inside the Projects section; and
  • each li is inside a ul.

Select all four navigation links in the browser. Then select the contact or professional-profile link.

For a mailto: link, the browser can ask which email application to use. That prompt confirms that the browser recognized the link. You do not need to send a message.

Change one word in a project description. Save index.html, reload the browser, and confirm that the new word appears. Restore the wording if the change was only a test.

Run git status. If a required repair changed index.html, inspect, stage, and commit that repair with a message that states what you fixed. Push the new commit. If no repair was necessary, the working tree should already be clean.

Run git log --oneline and confirm that it contains the three required checkpoint messages. Run git push once more and confirm that Git reports no new local commits to send.

Open this support when a review fails or when the next repair is unclear. The assignment-wide reference solution provides one complete structure for comparison.

Assistance 1 — Identify the first failed review

Choose the first statement that does not describe the current page:

  • The browser does not show the complete page: return to Checkpoint 1 or 3.
  • A navigation link does not reach its section: return to Checkpoint 2.
  • A heading has the wrong level: repair the heading hierarchy review.
  • An element closes in the wrong place: repair the page outline review.
  • The saved change does not appear: repair the saving and reloading review.

Work on that result only. Repeat its test before you continue.

Assistance 2 — Trace one structure problem through the source

Start at the element that failed. Find its opening tag, its content, and its closing tag. Confirm that all nested elements close before the parent element closes. Then indent the repaired structure so each nesting level is visible.

For a link problem, compare one complete href and id pair character by character. Save, reload, and test the same link again.

Checkpoint: The required page passes the structure review

What now works
The saved page passes the structure and link reviews, the local working tree is clean, and GitHub contains the latest commit.
Files changed
html-profile/index.html, html-profile/.git/
What remains
Complete the final self-check, explain two semantic choices and the Git workflow, and show the project to your teacher.
Next action
Complete each self-check item against the saved source and browser page.
If it does not work
Start with the first failed check only. Repair it, save, reload, and repeat that check before moving to the next item.

Self-check

Complete these checks against the required result.

  1. Confirm that html-profile contains one required file named index.html and that the browser opens it as a page.
  2. Confirm that the document includes the doctype, html lang="en", head, UTF-8 charset, viewport setting, title, and body.
  3. Confirm that body contains page-level header, one visible main, and page-level footer in that order.
  4. Select About, Skills, Projects, and Contact in the navigation and confirm that each URL fragment exactly matches one section id.
  5. Confirm that the page has one h1, that the main content headings use h2, and that the two project headings use h3.
  6. Confirm that the Skills section contains at least four li elements inside a ul.
  7. Confirm that the Projects section contains at least two article elements and that the current-focus content uses aside.
  8. Read every link without its surrounding sentence and confirm that the link text still identifies its destination or purpose.
  9. Match every opening tag with its closing tag and confirm that nested elements close from the inside out.
  10. Explain why one project uses article and why the current-focus note uses aside.
  11. Run git log --oneline and confirm that it contains the three required checkpoint messages.
  12. Run git status and confirm that main has a clean working tree.
  13. Open the private GitHub repository and confirm that its newest commit matches the newest local commit.

Your teacher checks the required path against these criteria:

Criterion Evidence
Complete document index.html opens, saves, reloads, and contains the required document metadata and visible content.
Semantic structure The page regions and content groups use elements that match their purpose.
Navigation and links All four fragment links reach unique targets, and the contact or profile link has descriptive text and the intended destination.
Heading and content hierarchy One h1, the required h2 headings, and project h3 headings represent the page structure.
Source quality Tags are correctly nested and consistently indented, and the student can explain two element choices.
Version control The local history contains the required checkpoint commits, the final working tree is clean, and the private GitHub repository contains the latest commit.

An optional extension does not change whether the required assignment is complete.

The checkpoint sections contain support for their specific tasks and tests. The two options below provide a larger starting structure. You can open either option from any checkpoint.

Assistance 4 — Start from a partial document structure

This partial implementation supplies the document and page regions. Replace each TODO comment with your content. You must still add the skills list, project articles, current-focus aside, contact link, and footer content.

html-profile/index.html — partial implementation
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>TODO: profile name and role</title>
</head>
<body>
<header>
<p><a href="index.html">Profile</a></p>
<nav aria-label="Primary navigation">
<ul>
<li><a href="#about">About</a></li>
<li><a href="#skills">Skills</a></li>
<li><a href="#projects">Projects</a></li>
<li><a href="#contact">Contact</a></li>
</ul>
</nav>
</header>
<main>
<h1>TODO: profile name and role</h1>
<p>TODO: one-sentence introduction</p>
<section id="about">
<h2>About</h2>
<!-- TODO: Add the About paragraph. -->
</section>
<section id="skills">
<h2>Skills</h2>
<!-- TODO: Add the skills list. -->
</section>
<section id="projects">
<h2>Projects</h2>
<!-- TODO: Add two project articles. -->
</section>
<!-- TODO: Add the Current focus aside. -->
<section id="contact">
<h2>Contact</h2>
<!-- TODO: Add a paragraph and descriptive link. -->
</section>
</main>
<footer>
<!-- TODO: Add stable closing text. -->
</footer>
</body>
</html>
Assistance 5 — Compare with one complete reference solutionExample solution

This is one valid reference solution for a fictional profile. You can use it to compare structure, repair an error, or provide a starting state. The content can differ, but the required behaviors and semantic relationships remain the same.

html-profile/index.html — complete reference solution
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Sam Rivera — Web development student</title>
</head>
<body>
<header>
<p><a href="index.html">Sam Rivera profile</a></p>
<nav aria-label="Primary navigation">
<ul>
<li><a href="#about">About</a></li>
<li><a href="#skills">Skills</a></li>
<li><a href="#projects">Projects</a></li>
<li><a href="#contact">Contact</a></li>
</ul>
</nav>
</header>
<main>
<h1>Sam Rivera — Web development student</h1>
<p>I build clear web pages and study how their structure supports different users.</p>
<section id="about">
<h2>About</h2>
<p>I am developing a foundation in HTML before I add visual design and interaction. I inspect my source code, test links in the browser, and correct the structure when the result differs from my plan.</p>
</section>
<section id="skills">
<h2>Skills</h2>
<ul>
<li>Writing complete HTML documents</li>
<li>Choosing elements by content purpose</li>
<li>Building clear heading hierarchies</li>
<li>Testing local pages in the browser</li>
</ul>
</section>
<section id="projects">
<h2>Projects</h2>
<article>
<h3>HTML elements reference</h3>
<p>A local page that explains tags, attributes, nesting, headings, lists, and links through working examples.</p>
</article>
<article>
<h3>Web learning journal</h3>
<p>A semantic journal with page regions, fragment navigation, independent entries, and a related reference note.</p>
</article>
</section>
<aside>
<h2>Current focus</h2>
<p>I am checking that each HTML element describes the purpose of its content before I begin styling the page.</p>
</aside>
<section id="contact">
<h2>Contact</h2>
<p><a href="mailto:hello@example.com">Email Sam Rivera</a> about a web practice project.</p>
</section>
</main>
<footer>
<p>Built as an HTML practice project.</p>
</footer>
</body>
</html>

In this solution, the four primary topics use section, each project uses article, and the related learning note uses aside. The fragment links work because each href value matches one section id. The heading levels reflect the content hierarchy rather than the browser’s default text sizes.

Stop after any checkpoint if you need to split the project across sessions. Save index.html, reload the browser, and record this note before you close the project:

Resume note
What works:
[Name the last checkpoint that passed.]
What remains:
[Name the next incomplete requirement.]
Next action:
[Write one action in index.html.]
Required setup:
Open html-profile in VS Code, index.html in the browser, and the VS Code terminal. Run git status before you continue.

The required project is complete when the self-check passes and you have shown the saved page, source, and repository history to your teacher. Continue to Style a page with CSS when you are ready to control the page’s appearance.