link

PrintCSS

A basic CV example

PDF CV example, Skills section
PDF CV example, Skills section

In this article, you will learn how to create your own CV PDF with HTML, CSS. To render the actual PDF we will use PagedJS an open-source tool to create PDF documents from HTML.

Before we start with the CV, let us think about the structure we want. So in this example we will create a multi-page CV and on each of the pages we will have our main details in a header section.

After the header there will be a short section for a introduction text. Then following a section for the employment history, the education and further skills.

For all sections there will be sub-sections for the different jobs or achievements. On the left side we will put the dates and right the content so what we actually did in that time period.

#The header section

Header Section Sample
Header Section Sample

For the header let us first define the HTML structure. Our heading will be the first and last name in an H1 element. Next, we want to put some links to important websites, like our LinkedIn or GitHub profile. That these links look nice you can include FontAwesome and add a small icon in front of every link. Last we should put more information about ourselves, like the birthdate, phone number and address.

#CSS

@import url('https://fonts.googleapis.com/css2?family=Asul:wght@700&family=Open+Sans&display=swap');
@import url('https://stackpath.bootstrapcdn.com/font-awesome/4.7.0/css/font-awesome.min.css');

@page {
    size: A4;
    margin: 5cm 2cm 2cm 2cm;

    @top-center {
        content: element(MyHeader);
    }

    @bottom-center {
        content: "- " counter(page) " -";
    }
}

header {
    position: running(MyHeader);
    text-align: center;
}

header p i:first-of-type {
    margin-left: 0;
}

header i {
    margin-left: 5mm;
}

#HTML

<header>
    <h1>Firstname Lastname</h1>
    <p>
        <i class="fa fa-envelope" aria-hidden="true"></i> <a href="mailto:info@azettl.net">info@azettl.net</a> 
        <i class="fa fa-home" aria-hidden="true"></i> <a href="https://printcss.live">printcss.live</a>
        <i class="fa fa-github" aria-hidden="true"></i> <a href="https://github.com/">github.com/USER</a>
        <i class="fa fa-linkedin" aria-hidden="true"></i> <a href="https://linkedin.com/">linkedin.com/in/USER</a>
    </p>
    <p>
        <i class="fa fa-birthday-cake" aria-hidden="true"></i> 01. January 1970 
        <i class="fa fa-phone" aria-hidden="true"></i> +49 123 456 789 
        <i class="fa fa-map-marker" aria-hidden="true"></i> Streetname 1, 12345 City
    </p>
</header>

#The profile section

The profile section or introduction text will be our first section. Here we already define the split of left and right content in the sub-sections. We will use the same code in all the following sections. Let’s put the section's title in an H2 element and for the left/right sub-sections we will use a flex layout. To do so you need to set the display property of the element to flex. The left element should have a minimum width and the right element will take the rest of the space.

As the right element has paragraphs or further headlines (H3 elements) inside you should set their margin top to 0. This way they start at the same level as the left sides content.

#CSS

section:first-of-type {
    position: absolute;
    bottom: 0;
}

section:nth-of-type(2){
    break-before: always;
}

section {
    break-inside: avoid;
}

h1, 
h2, 
h3 {
    font-family: "Asul", sans-serif;
}

h2 {
    background-color: black;
    color: white;
    display: inline-block;
    padding: 1mm;
    text-transform: uppercase;
}

body {
    font-family: 'Open Sans', sans-serif;
}

.flex {
    display: flex;
}

.left {
    min-width: 4cm;
}

.right p:first-of-type,
.right h3:first-of-type {
    margin-top: 0;
}

.right p:first-of-type {
    margin-bottom: 0;
}

#HTML

<section>
    <h2>Profile</h2>
    <div class="flex">
        <div class="left"></div>
        <div class="right">
            <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. A erat nam at lectus urna duis. Urna nec tincidunt praesent semper feugiat nibh sed pulvinar. Risus ultricies tristique nulla aliquet enim tortor at auctor urna. Justo donec enim diam vulputate ut pharetra sit amet aliquam. Eros donec ac odio tempor orci dapibus ultrices in. Libero enim sed faucibus turpis in eu mi bibendum.</p>
            <p>Imperdiet nulla malesuada pellentesque elit eget gravida cum sociis. Pellentesque habitant morbi tristique senectus et netus et. Gravida in fermentum et sollicitudin ac. Ac odio tempor orci dapibus ultrices.</p>
            <p>Nunc mattis enim ut tellus elementum. Diam quam nulla porttitor massa id neque aliquam. Auctor urna nunc id cursus metus aliquam. Nunc congue nisi vitae suscipit. Ut eu sem integer vitae justo eget. </p>
        </div>
    </div>
</section>

#The other sections

All other sections in your CV document will have the same HTML structure and CSS styling. Have a look at the complete sample below to see how these sections are added.

<!DOCTYPE html>
<html lang="en">
    <head>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <title>Firstname Lastname - CV</title>
        <style>
            @import url('https://fonts.googleapis.com/css2?family=Asul:wght@700&family=Open+Sans&display=swap');
            @import url('https://stackpath.bootstrapcdn.com/font-awesome/4.7.0/css/font-awesome.min.css');

            @page {
                size: A4;
                margin: 5cm 2cm 2cm 2cm;

                @top-center {
                    content: element(MyHeader);
                }

                @bottom-center {
                    content: "- " counter(page) " -";
                }
            }

            header {
                position: running(MyHeader);
                text-align: center;
            }

            header p i:first-of-type {
                margin-left: 0;
            }

            header i {
                margin-left: 5mm;
            }

            section:first-of-type {
                position: absolute;
                bottom: 0;
            }

            section:nth-of-type(2){
                break-before: always;
            }

            section {
                break-inside: avoid;
            }

            h1, 
            h2, 
            h3 {
                font-family: "Asul", sans-serif;
            }

            h2 {
                background-color: black;
                color: white;
                display: inline-block;
                padding: 1mm;
                text-transform: uppercase;
            }

            body {
                font-family: 'Open Sans', sans-serif;
            }

            .flex {
                display: flex;
            }

            .left {
                min-width: 4cm;
            }

            .right p:first-of-type,
            .right h3:first-of-type {
                margin-top: 0;
            }

            .right p:first-of-type {
                margin-bottom: 0;
            }
        </style>
    </head>
    <body>
        <header>
            <h1>Firstname Lastname</h1>
            <p>
                <i class="fa fa-envelope" aria-hidden="true"></i> <a href="mailto:info@azettl.net">info@azettl.net</a> 
                <i class="fa fa-home" aria-hidden="true"></i> <a href="https://printcss.live">printcss.live</a>
                <i class="fa fa-github" aria-hidden="true"></i> <a href="https://github.com/">github.com/USER</a>
                <i class="fa fa-linkedin" aria-hidden="true"></i> <a href="https://linkedin.com/">linkedin.com/in/USER</a>
            </p>
            <p>
                <i class="fa fa-birthday-cake" aria-hidden="true"></i> 01. January 1970 
                <i class="fa fa-phone" aria-hidden="true"></i> +49 123 456 789 
                <i class="fa fa-map-marker" aria-hidden="true"></i> Streetname 1, 12345 City
            </p>
        </header>
        <section>
            <h2>Profile</h2>
            <div class="flex">
                <div class="left"></div>
                <div class="right">
                    <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. A erat nam at lectus urna duis. Urna nec tincidunt praesent semper feugiat nibh sed pulvinar. Risus ultricies tristique nulla aliquet enim tortor at auctor urna. Justo donec enim diam vulputate ut pharetra sit amet aliquam. Eros donec ac odio tempor orci dapibus ultrices in. Libero enim sed faucibus turpis in eu mi bibendum.</p>
                    <p>Imperdiet nulla malesuada pellentesque elit eget gravida cum sociis. Pellentesque habitant morbi tristique senectus et netus et. Gravida in fermentum et sollicitudin ac. Ac odio tempor orci dapibus ultrices.</p>
                    <p>Nunc mattis enim ut tellus elementum. Diam quam nulla porttitor massa id neque aliquam. Auctor urna nunc id cursus metus aliquam. Nunc congue nisi vitae suscipit. Ut eu sem integer vitae justo eget. </p>
                </div>
            </div>
        </section>
        <section>
            <h2>Employment History</h2>
            <div class="flex">
                <div class="left">2020 January &ndash; today</div>
                <div class="right">
                <p>Excepteur</p>
                <h3>Duis aute irure dolor in reprehenderit in voluptate</h3>
                <ul>
                    <li>Lorem ipsum dolor sit amet</li>
                    <li>Lorem ipsum dolor sit amet</li>
                    <li>Lorem ipsum dolor sit amet</li>
                    <li>Lorem ipsum dolor sit amet</li>
                </ul>
                </div>
            </div>
            <div class="flex">
                <div class="left">2007 &ndash; today</div>
                <div class="right">
                <p>Lorem ipsum dolor</p>
                <h3>Lorem ipsum</h3>
                <p>
                    Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur.
                </p>
                </div>
            </div>
        </section>
        <section>
            <h2>Education</h2>
            <div class="flex">
                <div class="left">2004 &ndash; 2007</div>
                <div class="right">
                    <h3>Lorem ipsum dolor sit amet, consectetur adipiscing elit</h3>
                    <p>sed do eiusmod tempor incididunt ut labore et dolore magna aliqua</p>
                    <ul>
                        <li>Lorem ipsum dolor sit amet</li>
                        <li>Lorem ipsum dolor sit amet</li>
                        <li>Lorem ipsum dolor sit amet</li>
                        <li>Lorem ipsum dolor sit amet</li>
                        <li>Lorem ipsum dolor sit amet</li>
                    </ul>
                </div>
            </div>
        </section>
        <section>
            <h2>Skills</h2>
            <div class="flex">
                <div class="left">Languages</div>
                <div class="right">German: mother tongue,English: fluent</div>
            </div>
            <div class="flex">
                <div class="left">Certificates</div>
                <div class="right">Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.</div>
            </div>
        </section>
    </body>
</html>

You can see the complete sample including the resulting PDF document on my GitHub repository for print CSS samples.

If you want to try recreating this CV or create your own one you can use printcss.live to render your PDF. This will save you the time of installing one of the rendering tools on your own dev environment.

If you want a more detailed explanation of the above sample check the Video about the same on YouTube.