Vanilla HTML/CSS Portfolio & ATS-Friendly CV
Summary
Building a professional, dual-language (EN/DE) DevOps portfolio and CV. Instead of over-engineering with heavy frameworks (React/Next.js) or maintaining separate Word/LaTeX documents, I used Vanilla HTML/CSS hosted on GitHub Pages. The core achievement is an ATS-friendly, auto-formatting CV that exports perfectly to PDF via the browser's native print function, while maintaining a Dark/Light theme toggle for the web version.
Details
The main goal was to have a single source of truth for the CV that looks great on the web (Dark Mode by default) but prints perfectly as a formal document (Light Mode, no UI elements).
Key Architectural Decisions:
1. Zero-Build Pipeline: Pure static files (index.html, cv.html, style.css) deployed directly via GitHub Pages. No Node.js vulnerabilities, zero maintenance.
2. CSS Custom Properties: Used CSS variables (:root) and a localStorage JavaScript toggle to switch themes without heavy state-management libraries.
3. Print Media Queries: Used @media print to strip away web UI elements (navigation, buttons) and force a white background with black text when saving to PDF.
4. Pragmatic i18n: Duplicated cv.html to cv-de.html for the German version. For a 2-page static site, file duplication is much simpler to maintain than a JSON translation layer.
Commands / Examples
1. Theme Toggling (CSS Variables)
This setup allows smooth switching between themes using a simple class on the <body> tag.
/* Default Dark Theme */
:root {
--bg-primary: #0d1117;
--text-primary: #c9d1d9;
--accent-primary: #58a6ff;
}
/* Light Theme Override */
body.light-theme {
--bg-primary: #ffffff;
--text-primary: #24292f;
--accent-primary: #0969da;
}
2. The Print Superpower (@media print)
This is the magic that makes the HTML CV export perfectly to an ATS-friendly PDF. It hides the UI and forces page breaks to respect job blocks.
@media print {
body {
/* Force high contrast for printing */
background-color: #ffffff !important;
color: #000000 !important;
}
/* Hide navigation and buttons */
.page-header, .btn {
display: none !important;
}
/* Prevent a job block from splitting across two pages */
.job-block {
page-break-inside: avoid;
}
/* Standard A4 margins */
@page {
margin: 1.5cm;
}
}
3. Minimal Vanilla JS Theme Persister
A tiny script to remember the user's theme choice across reloads.
const toggleBtn = document.getElementById('theme-toggle');
const body = document.body;
// Load saved preference
const currentTheme = localStorage.getItem('theme') || 'dark';
if (currentTheme === 'light') {
body.classList.add('light-theme');
}
// Toggle on click
toggleBtn.addEventListener('click', () => {
body.classList.toggle('light-theme');
const isLight = body.classList.contains('light-theme');
localStorage.setItem('theme', isLight ? 'light' : 'dark');
});