Monday, 5 February 2024 - Amsterdam

CSS grid

CSS grid makes it a pleasure to create layouts. Here we’ll create a resume using CSS grid. Only HTML and CSS will be used. No JavaScript required. Another goal is to keep it all in one file to make it easy to distribute and fast.

Intro

Lets start by creating a simple index.html page in a newly created project folder.

mkdir resume-css-grid
cd resume-css-grid
touch `index.html`

Setting up index.html

Enter the following template in index.html to setup a basic HTML document.

<!-- index.html -->
<!DOCTYPE html>
<html>
    <head>
        <meta charset="utf-8" />
        <meta content="giwan, persaud, resume, not" name="keywords" />
        <meta
            content="The online resume of Giwan Persaud."
            name="description"
        />
        <meta content="Resume / CV Giwan Persaud" name="title" />
        <title>Resume / CV Giwan Persaud</title>
    </head>

    <body></body>
</html>

Styling

To keep things simple, styling will be added directly in the HTML document in a <style></style> tag. There we’ll also setup some default CSS Properties to be used throughout the document.

<style>
    :root {
        --unit: 16px;
        --color-primary: #1a1a1a;
        --color-secondary: #797979;
        --color-gray: #e5e5e5;
    }
</style>

Resume header

Let’s create the header first with the relevant information. The phone number sections will be hidden but for now fake information is added. Replace the body tag with the following:

<body>
    <div class="page">
        <header>
            <h1>Sr. Front-end Developer</h1>
            <h2>Giwan Persaud</h2>
            <address>
                <a href="mailto:giwan.persaud@gmail.com"
                    >giwan.persaud@gmail.com</a
                >
                <a
                    href="tel:+3100000000"
                    alt="duplicate even # to get correct telephone number"
                    >+31 6<span class="marker">00000000</span></a
                >
                <p>
                    <span class="marker">Xxxxxstraat 1, 1111 XX</span>
                    Amsterdam, The Netherlands
                </p>
            </address>
            <p>
                Dutch national born October 10th 1980, <br />Living in Amsterdam
            </p>
        </header>
        <aside>
            <img
                src="https://res.cloudinary.com/mytoori/image/upload/c_scale,w_200/v1554037030/42a2d7fd327e612d11d085837069adfc_400x400.jpg"
                alt="giwan profile image"
            />
        </aside>
    </div>
</body>

In the normal HTMl flow the header and aside elements are placed below each other. We address that by changing display property of container page to grid. 12 columns are created with grid-template-columns: repeat(12, 1fr) The header content will be split over these in 8 by 4 columns. By setting the max-width and the margin we ensure the page does not get too wide on large screens and remains centered.

<!-- page class styling -->
<style>
    .page {
        display: grid;
        max-width: calc(var(--unit) * 50);
        margin: 0 auto;
        grid-template-columns: repeat(12, 1fr);
        grid-template-rows: 300px 1fr 300px;
    }
</style>

Add the following styles to complete the header.

<style>
    :root {
        --unit: 16px;
        --color-primary: #1a1a1a;
        --color-secondary: #797979;
        --color-gray: #e5e5e5;
    }

    h1,
    h2,
    h3,
    h4 {
        font-family: "Roboto Condensed", "Roboto", "sans-serif";
        margin: 0;
        padding: 0;
    }

    .page {
        border: var(--unit) solid transparent;
        border-top: 0;
        max-width: calc(var(--unit) * 50);
        margin: 0 auto;
        display: grid;
        grid-template-columns: repeat(12, 1fr);
        grid-template-rows: 300px 1fr 300px;
    }

    .page > header {
        grid-column: 1 / span 8;
        padding-top: var(--unit);
    }

    .page > header + aside {
        grid-column: span 4 / -1;
        display: flex;
        justify-content: center;
        align-items: flex-start;
    }

    address,
    a {
        text-decoration: none;
        color: var(--color-primary);
        font-style: normal;
    }

    address p {
        line-height: 1.75em;
    }

    .marker {
        background-color: var(--color-gray);
        color: var(--color-gray);
    }

    h2 + address {
        margin-top: var(--unit);
    }

    h2 + address + p {
        color: var(--color-secondary);
    }
</style>

The Main content

The main content consists of a column for experience and a column for skills.

<main class="experience">
    <h4>Experience</h4>
    <section>
        <header>
            <h2>Senior Front-end developer</h2>
            <h3>
                <a
                    target="_blank"
                    href="https://weeronline.nl"
                    alt="weeronline weather site"
                >
                    Weeronline.nl
                </a>
                | Amsterdam, The Netherlands Oct 2019 - present
            </h3>
        </header>
        <article>
            Support main site, A/B test new features to improve ad revenue.
            Investigate loading performance & suggest optimizations
        </article>
        <aside>
            <ul>
                <li>ReactJS & NodeJS</li>
                <li>Page speed investigation</li>
                <li>Server Side Rendering</li>
            </ul>
        </aside>
    </section>
    <section>
        <header>
            <h2>Lead Front-end developer</h2>
            <h3>
                <a
                    target="_blank"
                    href="https://edia.nl"
                    alt="bilingual books app"
                >
                    EDIA.nl</a
                >
                | Amsterdam, The Netherlands Sep 2015 - Jul 2019
            </h3>
        </header>
        <article>
            Architect & develop newsreader for language learners. Coach juniors.
            Liase with backend, AI and DevOps teams. Proud achievement:
            papyrus.edia.nl (It also shows off my landing page design)
        </article>
        <aside>
            <ul>
                <li>ReactJS & NodeJS</li>
                <li>Chrome extension (react)</li>
                <li>Docker & Kubernetes</li>
                <li>Scrum, Jira & Coaching</li>
                <li>Progressive Web App</li>
            </ul>
        </aside>
    </section>
    <section>
        <header>
            <h2>Founder - Fullstack developer</h2>
            <h3>
                <a
                    target="_blank"
                    href="https://mytoori.com"
                    alt="bilingual books app"
                    >Mytoori.com</a
                >
                | Amsterdam, The Netherlands Sep 2014 - present
            </h3>
        </header>
        <article>
            Develop iOS app (Objective-C), Build book management system using
            React, NodeJS & MongoDB. Coordinate Product marketing. Liase with
            investors. Explore marketing and advertising opportunities.
        </article>
        <aside>
            <ul>
                <li>ReactJS & NodeJS</li>
                <li>MongoDB & Mongoose</li>
                <li>Progressive Web App</li>
                <li>Trello Product Management</li>
                <li>Hosting, Email & DNS</li>
            </ul>
        </aside>
    </section>
    <hr />
    <section>
        <header>
            <h2>Developer</h2>
            <h3>Bureau BlauwGeel | Utrecht, Feb 2014 - Aug 2014</h3>
        </header>
    </section>
    <section>
        <header>
            <h2>CoFounder - Developer</h2>
            <h3>Questionise | Amsterdam, 2012 - 2014</h3>
        </header>
    </section>
    <section>
        <header>
            <h2>SAP Technical Consultant</h2>
            <h3>Accenture | Various Euro countries 2004 - 2012</h3>
        </header>
    </section>
</main>

By simply adding the following style, the content is spread over 8 columns. This shorthand for: start at column 1 and spread over 8 columns. Many other options are possible which I won’t go into detail here. The links at the bottom of the article offer more details.

<style>
    .experience {
        grid-column: 1 / span 8;
    }
</style>

The sidebar to the main content

The right column shows the list of skills. Add this below the <main></main> tag.

<aside class="page-aside">
    <section>
        <h4>Tech skills</h4>
        <ul class="skills">
            <li>ReactJS</li>
            <li>Redux</li>
            <li>NodeJS</li>
            <li>PWA</li>
            <li>Jest</li>
            <li>Sass</li>
            <li>HTML5</li>
            <li>CSS</li>
            <li>ExpressJS</li>
            <li>Docker</li>
            <li>MongoDB</li>
            <li>git</li>
            <li>GatsbyJS</li>
        </ul>

        <ul class="skills-2">
            <li>Objective-c</li>
            <li>Google apps for business</li>
            <li>Hosting (Heroku, Zeit, Netlify)</li>
            <li>DNS Management</li>
            <li>git (Bitbuket, Github, Gitlab)</li>
        </ul>
    </section>

    <section class="language">
        <h4>Language skills</h4>
        <ul>
            <li>English & Dutch, fluent.</li>
            <li>French, intermediate.</li>
        </ul>
    </section>
    <section class="education">
        <h4>Education</h4>
        <section>
            <h1>MSc. Web Marketing and Project management 2011</h1>
            <h2>SKEMA Business school - Sophia Antipolis, France</h2>
            <ul>
                <li>Project management</li>
                <li>Planning</li>
                <li>Stakeholder management</li>
                <li>PMI Certification</li>
                <li>Search engine marketing</li>
                <li>Social media</li>
            </ul>
        </section>
        <section>
            <h1>Bachelor Information Engineering 2004</h1>
            <h2>Hogeschool van Amsterdam - Amsterdam, The Netherlands</h2>
            <ul>
                <li>Project management</li>
                <li>Java</li>
                <li>UML</li>
                <li>Communication</li>
                <li>Object Oriented Design</li>
                <li>Relational Databases</li>
            </ul>
        </section>
    </section>
</aside>

By spanning the 4 columns from the end we ensure that the aside element is now placed in the last 4 columns.

<style>
    .experience + aside {
        grid-column: span 4 / -1;
    }
</style>

Next each <section> in the experience class is turned into another grid.

<style>
    .experience > section {
        margin-bottom: calc(var(--unit) * 3);
        padding: 0;
        display: grid;
        grid-template-columns: 1fr 1fr;
        grid-template-rows: calc(var(--unit) * 4) 1fr;
    }
</style>

With that in place we can add some basic CSS to clean up the rest of the styling.

<style>
    <style > :root {
        --unit: 16px;
        --color-primary: #1a1a1a;
        --color-secondary: #797979;
        --color-gray: #e5e5e5;
    }

    h1,
    h2,
    h3,
    h4 {
        font-family: "Roboto Condensed", "Roboto", "sans-serif";
        margin: 0;
        padding: 0;
    }

    h1 {
        font-size: 2rem;
        font-weight: 800;
    }

    h2 {
        font-size: 1.75rem;
    }

    h3 {
        color: var(--color-secondary);
    }

    h4 {
        text-transform: uppercase;
        margin-bottom: calc(var(--unit) / 2);
        color: var(--color-secondary);
        font-weight: 300;
        display: inline-block;
        border-bottom: 1px solid var(--color-secondary);
    }

    .page {
        border: var(--unit) solid transparent;
        border-top: 0;
        max-width: calc(var(--unit) * 50);
        margin: 0 auto;
        display: grid;
        grid-template-columns: repeat(12, 1fr);
        grid-template-rows: 300px 1fr 300px;
    }

    .experience {
        grid-column: 1 / span 8;
    }

    main.experience + aside {
        grid-column: span 4 / -1;
    }

    .experience header h3 {
        font-size: 1rem;
        font-weight: 300;
    }

    .experience > section {
        margin-bottom: calc(var(--unit) * 3);
        padding: 0;
        display: grid;
        grid-template-columns: 1fr 1fr;
        grid-template-rows: calc(var(--unit) * 4) 1fr;
    }

    .experience > section header {
        grid-column: span 2;
    }

    section ul {
        list-style: none;
        margin: 0;
        padding: 0;
    }
    .experience section ul li {
        margin: 0;
        padding: 0;
    }

    .experience section aside {
        color: var(--color-secondary);
        font-family: "Roboto Condensed";
        margin-left: var(--unit);
    }
</style>

The final result can be seen at https://giwan.mytoori.com. Open the dev tools of your browser to see the full style.

Links