Project: A Resume Page
A document with real structure: dated entries, an experience timeline, skills grouped by category, and a print stylesheet that produces a usable PDF.
-
HTML Basics
- What is HTML: The Structure Layer of Every Web Page
- HTML Document Structure: DOCTYPE, html, head and body
- Elements, Tags and Attributes: The Vocabulary of HTML
- HTML Comments: Notes That Ship With Your Code
- Block Level and Inline Elements
- Writing and Running Your First HTML Page
- How a Browser Turns Markup Into a Page
- Text and Formatting
- Links and Navigation
- Images and Media
- Lists
- Tables
-
Forms
- Form Structure: form, action and method
- Input Types: Text, Email, Number, Date and the Rest
- Labels: The Most Important Element in a Form
- Checkboxes, Radio Buttons and Grouping
- select, option, optgroup and datalist
- textarea, File Uploads and Hidden Fields
- Buttons: submit, reset and button
- Built In Form Validation
- GET or POST: What Happens When a Form Is Submitted
- Semantic HTML
- HTML5 Features
- Head and Metadata
- HTML with CSS
- HTML with JavaScript
- Accessibility
-
HTML SEO
- How Google Works: Crawling, Indexing and Ranking
- SEO Friendly HTML Structure
- Titles and Descriptions That Earn Clicks
- Headings and Content Structure for Search
- Internal Linking and Anchor Text
- robots.txt and XML Sitemaps
- Canonical URLs and Duplicate Content
- Structured Data and JSON-LD
- Image SEO
- Core Web Vitals and Mobile Friendliness
- DevTools and Debugging
- Editor Productivity
- HTML Best Practices
- HTML Projects
- Advanced Projects
- Practice and Exams
The brief
Build an online resume that reads well on screen, prints to a clean single file, and is understandable when read aloud.
Requirements
- Contact details in an
addresselement. - Experience entries as
articleelements with dates intime. - Education, skills and projects sections.
- Correct heading hierarchy throughout.
- A print stylesheet.
Personstructured data.- A download link to a PDF version.
The structure
<main id="main-content" tabindex="-1">
<header class="resume-header">
<h1>Meera Iyer</h1>
<p class="role">Front end developer</p>
<address>
<a href="mailto:meera@example.com">meera@example.com</a> ·
<a href="tel:+912026001234">+91 20 2600 1234</a> ·
Pune, Maharashtra
</address>
<p class="no-print">
<a href="/files/meera-iyer-resume.pdf" download>Download as PDF (180 KB)</a>
</p>
</header>
<section>
<h2>Summary</h2>
<p>Four years building accessible interfaces for public sector and education clients.</p>
</section>
<section>
<h2>Experience</h2>
<article class="entry">
<h3>Front end developer</h3>
<p class="entry-meta">
Riverside Digital ·
<time datetime="2024-06">June 2024</time> to present
</p>
<ul>
<li>Rebuilt the admissions portal, cutting page weight by sixty percent.</li>
<li>Brought the main site to WCAG 2.2 level AA.</li>
</ul>
</article>
<article class="entry">
<h3>Junior developer</h3>
<p class="entry-meta">
Kavya Studio ·
<time datetime="2022-08">August 2022</time> to
<time datetime="2024-05">May 2024</time>
</p>
<ul>
<li>Built template systems for six client sites.</li>
</ul>
</article>
</section>
<section>
<h2>Education</h2>
<article class="entry">
<h3>BSc Computer Science</h3>
<p class="entry-meta">
Riverside College ·
<time datetime="2019">2019</time> to <time datetime="2022">2022</time>
</p>
</article>
</section>
<section>
<h2>Skills</h2>
<dl class="skills">
<div>
<dt>Markup and styling</dt>
<dd>HTML, CSS, accessibility, responsive design</dd>
</div>
<div>
<dt>Scripting</dt>
<dd>JavaScript, the DOM, browser APIs</dd>
</div>
<div>
<dt>Tooling</dt>
<dd>Git, build pipelines, testing</dd>
</div>
</dl>
</section>
</main>Why an article per entry
Each job is self contained: it would make sense lifted out and shown on its own. That is the test for article. It also gives each entry a clean boundary for styling and for structured data.
Note the heading levels: h1 is the name, h2 for each section, h3 for each entry. Reading the headings alone gives a table of contents.
The print stylesheet
@media print {
/* remove anything that makes no sense on paper */
.no-print,
nav,
.skip-link { display: none; }
body {
max-width: none;
margin: 0;
padding: 0;
font-size: 11pt;
color: #000;
background: #fff;
}
/* print the destination of every link */
a[href^="http"]::after {
content: " (" attr(href) ")";
font-size: 9pt;
color: #444;
}
/* do not print mailto and tel URLs, the text already shows them */
a[href^="mailto"]::after,
a[href^="tel"]::after { content: ""; }
/* keep entries whole across page breaks */
.entry { break-inside: avoid; }
h2 { break-after: avoid; }
@page { margin: 1.5cm; }
}Printing link destinations is the detail that makes a printed page useful. On paper a link is invisible; the generated content brings it back.
Structured data
<script type="application/ld+json">
{
"@context": "https://schema.org",
"@type": "Person",
"name": "Meera Iyer",
"jobTitle": "Front end developer",
"email": "mailto:meera@example.com",
"telephone": "+91-20-2600-1234",
"address": {
"@type": "PostalAddress",
"addressLocality": "Pune",
"addressRegion": "Maharashtra",
"addressCountry": "IN"
},
"alumniOf": {
"@type": "CollegeOrUniversity",
"name": "Riverside College"
},
"knowsAbout": ["HTML", "CSS", "Accessibility", "JavaScript"],
"sameAs": ["https://example.org/journal"]
}
</script>Layout with a grid
.entry {
display: grid;
grid-template-columns: 1fr;
gap: 0.25rem;
padding-bottom: 1.5rem;
border-bottom: 1px solid #e2e8f0;
margin-bottom: 1.5rem;
}
@media (min-width: 45rem) {
.entry {
grid-template-columns: 12rem 1fr;
column-gap: 2rem;
}
.entry h3 { grid-column: 2; }
.entry-meta { grid-column: 1; grid-row: 1 / span 2; }
.entry ul { grid-column: 2; }
}The dates move into a left column on wider screens while staying in reading order in the markup - the job title is announced before its dates either way.
Checking your work
- Validate.
- Print to PDF. Are entries split across pages? Are link URLs printed?
- Tab through it.
- Read the headings alone. Do they describe the document?
- Test the structured data in the Rich Results Test.
- Check at 320 pixels and at 200 percent zoom.
Extensions
- Add a
detailselement per entry holding the longer description. - Add a skills bar using
meter, with the level also in text. - Add a dark mode.
- Add a language switch with
hreflangalternates.
Practice
- Build your own resume with this structure.
- Write the print stylesheet and check the PDF on paper sized pages.
- Add
Personstructured data and validate it. - Read it with a screen reader and note anything announced oddly.