Grid

With flexbox items are treated together in columns and rows. With grid instead it’s possible to position each item independently. While flexbox positions items on one axis (row or column), grid can position items on both axis. On one hand this gives control, on the other hand it takes time to define the item’s position, especially if the layout for small devices differs from the one for large devices. But grid offers more flexibility.

This is an example layout grid. You can access each cell in the grid independently and group cells together. They are addressed by their index, starting with 1. (See the numbers inside the [].)

grid_csstricks_grid

Source

The base for a grid is a parent container with display property grid.

.grid-container {
    display: grid;
}

The layout of the grid is defined in the .grid-container through

grid-template-columns and grid-template-rows. Depending on your layout it’s enough to define the columns.

Basic example

<!DOCTYPE html>
<html lang="de-DE">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta name="keywords" content="Comma-separated keywords">
    <meta name="description" content="Brief description">
    <meta name="author" content="You">
    <title>Grid Intro</title>
    <link rel="stylesheet" href="css/style.css">
</head>
<body>

    <div class="grid-container">

        <div class="item item-1">
            <div class="item-text">
                item 1
            </div>
        </div>

        <div class="item item-2">
            <div class="item-text">
                item 2
            </div>
        </div>

        <div class="item item-3">
            <div class="item-text">
                item 3
            </div>
        </div>

        <div class="item item-4">
            <div class="item-text">
                item-4
            </div>
        </div>

    </div>


</body>
</html>

style.css

* {
    box-sizing: border-box;
}

body {
    font-family: monospace;
    font-size: 14pt;
    margin: 0; /* to avoid white space around */
}

.grid-container {
    display: grid;
    grid-template-columns: auto;
    height: 100vh; /* for full size container */
}

@media (min-width: 768px) {
    .grid-container {
        grid-template-columns: repeat(2, auto);
    }
}

.item {
    /* justify text center */
    display: flex;
    align-items: center;
    justify-content: center;
    text-align: center;
}

.item-text {
    color: white;
}

.item-1 {
    background-color: rgb(9, 102, 72);
}

.item-2 {
    background-color: rgb(104, 121, 65);
}

.item-3 {
    background-color: rgb(251, 143, 241);
}

.item-4 {
    background-color: rgb(170, 166, 244);
}

See the line repeat(2, auto);: repeat can be used to define the layout of the grid with the syntax

repeat(number of columns/ number of rows, width of the column)

grid_basic_1


Different col width

index.html

<!DOCTYPE html>
<html lang="de-DE">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta name="keywords" content="Comma-separated keywords">
    <meta name="description" content="Brief description">
    <meta name="author" content="You">
    <title>Grid Intro</title>
    <link rel="stylesheet" href="css/style.css">
</head>
<body>

    <div class="grid-container">

        <div class="item item-1">
            <div class="item-text">
                item 1
            </div>
        </div>

        <div class="item item-2">
            <div class="item-text">
                item 2
            </div>
        </div>

        <div class="item item-3">
            <div class="item-text">
                item 3
            </div>
        </div>

        <div class="item item-4">
            <div class="item-text">
                item-4
            </div>
        </div>

        <div class="item item-5">
            <div class="item-text">
                item 5
            </div>
        </div>

        <div class="item item-6">
            <div class="item-text">
                item-6
            </div>
        </div>

        <div class="item item-7">
            <div class="item-text">
                item-7
            </div>
        </div>

        <div class="item item-8">
            <div class="item-text">
                item 8
            </div>
        </div>

        <div class="item item-9">
            <div class="item-text">
                item-9
            </div>
        </div>

    </div>


</body>
</html>

style.css

* {
    box-sizing: border-box;
}

body {
    font-family: monospace;
    font-size: 14pt;
    margin: 0; /* to avoid white space around */
}

.grid-container {
    display: grid;
    grid-template-columns: auto;
    height: 100vh; /* for full size container */
}

/* Grid for larger devices: */
@media (min-width: 768px) {
    .grid-container {
        grid-template-columns: auto 50% auto;
        grid-column-gap: 10px;
        grid-row-gap: 10px;
    }
}

.item {
    /* justify text center */
    display: flex;
    align-items: center;
    justify-content: center;
    text-align: center;
}

.item-text {
    color: white;
}

.item-1 {
    background-color: rgb(9, 102, 72);
}

.item-2 {
    background-color: rgb(104, 121, 65);
}

.item-3 {
    background-color: rgb(251, 143, 241);
}

.item-4 {
    background-color: rgb(170, 166, 244);
}

.item-5 {
    background-color: rgb(115, 85, 40);
}

.item-6 {
    background-color: rgb(105, 22, 224);
}

.item-7 {
    background-color: rgb(182, 80, 191);
}

.item-8 {
    background-color: rgb(90, 138, 230);
}

.item-9 {
    background-color: rgb(235, 149, 21);
}

grid_basic_2

Different row height

Code as above except:

/* Grid for larger devices: */
@media (min-width: 768px) {
    .grid-container {
        grid-template-columns: auto 50% auto;
        grid-template-rows: 15% auto 10%;
        grid-column-gap: 10px;
        grid-row-gap: 10px;
    }
}

grid_basic_3

Items are independent

The real strength of CSS grid is that the items are independent from the grid! This means we can specify position and size of each item through CSS.

Example on a large device:

grid_basic_4

The same grid on a small device:

grid_basic_5

Corresponding code:

index.html

<!DOCTYPE html>
<html lang="de-DE">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta name="keywords" content="Comma-separated keywords">
    <meta name="description" content="Brief description">
    <meta name="author" content="You">
    <title>Grid Intro</title>
    <link rel="stylesheet" href="css/style.css">
</head>
<body>

    <div class="grid-container">

        <div class="item item-1">
            <div class="item-text">
                item 1
            </div>
        </div>

        <div class="item item-2">
            <div class="item-text">
                item 2
            </div>
        </div>

        <div class="item item-3">
            <div class="item-text">
                item 3
            </div>
        </div>

        <div class="item item-4">
            <div class="item-text">
                item-4
            </div>
        </div>

        <div class="item item-5">
            <div class="item-text">
                item 5
            </div>
        </div>

        <div class="item item-6">
            <div class="item-text">
                item-6
            </div>
        </div>

        <div class="item item-7">
            <div class="item-text">
                item-7
            </div>
        </div>


    </div>


</body>
</html>

style.css

* {
    box-sizing: border-box;
}

body {
    font-family: monospace;
    font-size: 14pt;
    margin: 0; /* to avoid white space around */
}

.grid-container {
    display: grid;
    grid-template-columns: auto auto;
    grid-column-gap: 10px;
    grid-row-gap: 10px;
    height: 100vh;
}

/* Grid for larger devices: */
@media (min-width: 768px) {
    .grid-container {
        grid-template-columns: auto 50% auto;
        grid-template-rows: 15% auto 10%;
    }
}

.item {
    /* justify text center */
    display: flex;
    align-items: center;
    justify-content: center;
    text-align: center;
}

.item-text {
    color: white;
}

.item-1 {
    background-color: rgb(9, 102, 72);
    grid-column: 1 / 3;
}

.item-2 {
    background-color: rgb(104, 121, 65);
}

.item-3 {
    background-color: rgb(251, 143, 241);
}

.item-4 {
    background-color: rgb(170, 166, 244);
    grid-column: 1 / 3;
}

.item-5 {
    background-color: rgb(115, 85, 40);
}

.item-6 {
    background-color: rgb(105, 22, 224);
}

.item-7 {
    background-color: rgb(182, 80, 191);
    grid-column: 1 / 3;
}

@media (min-width: 768px) {
    .item-1 {
        grid-column: 2 / 3;
        grid-row: 1/ 2;
    }

    .item-2 {
        grid-column: 1 / 2;
        grid-row: 1 / 2
    }

    .item-3 {
        grid-column: 3 / 4;
        grid-row: 1/ 2
    }

    .item-4 {
        grid-column: 2 / 3;
        grid-row: 2 / 3;
    }

    .item-5 {
        grid-column: 1 / 2;
        grid-row: 2 / 4;
    }

    .item-6 {
        grid-column: 3 / 4;
        grid-row: 2 / 4;
    }

    .item-7 {
        grid-column: 2 / 3;
        grid-row: 3/ 4;
    }
}

Example of responsive reordering

Layout on large devices:

grid_lg


Layout on small devices. While both layouts are possible with rows and columns, the transition of the red image between large and small layout is not possible that way, because the item would belong to different rows in the upper and lower layouts.

grid_sm


index.html

<!DOCTYPE html>
<html>
    <head>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <title>Writing an own website</title>
        <link rel="stylesheet" href="css/fonts.css">
        <link rel="stylesheet" href="css/style.css">
    </head>
    <body>

        <div class="grid-container">

            <div class="item-1">
                <h1 class="display_lg">writing<br>an own<br>website</h1>
                <h1 class="display_sm">writing an own website</h1>
            </div>

            <div>
                <h2>A flower needs some water</h2>
                <p>Lorem ipsum dolor sit amet, consectetur adipisicing 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.</p>
            </div>

            <div>
                <span class="img-center-helper"></span><img src="img/radematic_com.jpg" alt="screenshot of radematic.com" width="600" height="auto">
            </div>

            <div class="item-2">
                <h2>A computer <i>needs</i> some code</h2>
                <p>Lorem ipsum dolor sit amet, consectetur adipisicing 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. Lorem ipsum dolor sit amet, consectetur adipisicing 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. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</p>
                <p>Lorem ipsum dolor sit amet, consectetur adipisicing 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. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</p>
            </div>

            <div>
                <span class="img-center-helper"></span><img src="img/mschf_xyz.jpg">
            </div>

            <div class="item-3">
                <span class="img-center-helper"></span><img src="img/designsystems_international.jpg">
            </div>

            <div class="item-4">
                <a href="https://terra0.org" target="_blank" style="background-color: unset;">
                    <span class="img-center-helper"></span><img src="img/terra0_org.jpg">
                </a>
            </div>

        </div>
    </body>
</html>

style.css

* {
    box-sizing: border-box;
}

body {
    font-family: 'Vollkorn';
    font-size: 1.5em;
    background-color: rgb(33, 34, 32);
    color: rgb(33, 34, 32);
    margin: 0;
}

/* --- GRID --- */

.grid-container {
    display: grid;
    grid-template-columns: auto auto auto; /* 3 columns */
    grid-column-gap: 10px;
    grid-row-gap: 20px;
    margin: 20px 10px 20px 10px;
}

.grid-container > div {
    background-color: rgb(249, 243, 228);
    padding: 50px;
}

.item-1 {
    grid-column-start: 1;
    grid-column-end: 3;
}

.item-2 {
    grid-row-start: 2;
    grid-row-end: 4;
}

.item-3 {
    grid-column-start: 2;
    grid-column-end: 4;
}

.item-4 {
    grid-row-start: 4;
    grid-column-start: 1;
    grid-column-end: 4;
}

@media (max-width: 992px) {
    .grid-container {
        grid-template-columns: auto auto;
    }
    /* writing an own website */
    .item-1 {
        grid-column-start: 1;
        grid-column-end: 3;
    }
    /* a computer needs some code */
    .item-2 {
        grid-row-start: 3;
        grid-column-start: 1;
        grid-column-end: 3

    }
    /* designsystems_international */
    .item-3 {
        grid-row-start: 4;
        grid-column-start: 2;
        grid-column-end: 3;
    }
    /* terra0 */
    .item-4 {
        grid-row-start: 5;
        grid-column-start: 1;
        grid-column-end: 3;
    }
}

/* --- ITEMS --- */

h1, h2 {
    font-family: 'Montserrat';
    color: salmon;
    text-align: center;
}

h1 {
    font-size: 3.5vw;
}

h2 {
    font-size: 32pt;
}

p {
    padding: 10px;
    text-align: justify;
    text-indent: 16pt;
}

a {
    text-decoration: none;
}

.img-center-helper {
    display: inline-block;
    height: 100%;
    vertical-align: middle;
}

img {
    width: 100%;
    vertical-align: middle;
}

/* --- DISPLAY --- */

.display_lg {
    display: block;
}

.display_sm {
    display: none;
}

@media (max-width: 992px) {
    .display_lg {
        display: none;
    }

    .display_sm {
        display: block;
    }
}