grid

revision:


Content

grid examples grid templates the repeat() function grid expansions simple asymmetric grid adaptive photo layout grid and background patterns pure CSS perspective portfolio


grid examples

top

example: colored grid

code:
            <div class="grid1">
                <div class="grid1-item"></div>
                <div class="grid1-item"></div>
                <div class="grid1-item"></div>
                <div class="grid1-item"></div>
                <div class="grid1-item"></div>
                <div class="grid1-item"></div>
                <div class="grid1-item"></div>
                <div class="grid1-item"></div>
                <div class="grid1-item"></div>
                <div class="grid1-item"></div>
                <div class="grid1-item"></div>
                <div class="grid1-item"></div>
                <div class="grid1-item"></div>
                <div class="grid1-item"></div>
                <div class="grid1-item"></div>
                <div class="grid1-item"></div>
                <div class="grid1-item"></div>
                <div class="grid1-item"></div>
                <div class="grid1-item"></div>
                <div class="grid1-item"></div>
                <div class="grid1-item"></div>
                <div class="grid1-item"></div>
                <div class="grid1-item"></div>
                <div class="grid1-item"></div>
                <div class="grid1-item"></div>
                <div class="grid1-item"></div>
                <div class="grid1-item"></div>
                <div class="grid1-item"></div>
                <div class="grid1-item"></div>
                <div class="grid1-item"></div>
                <div class="grid1-item"></div>
                <div class="grid1-item"></div>
                <div class="grid1-item"></div>
                <div class="grid1-item"></div>
                <div class="grid1-item"></div>
                <div class="grid1-item"></div>
            </div>
            <style>
                .grid1 {display: grid; grid-template-rows: repeat(9, 1fr); grid-auto-columns: calc((90vw - 2vw) / 4); grid-auto-flow: column; grid-gap: 1em; height: 100vh; width: 90vw; margin: 0 auto}
                .grid1-item:nth-child(3n) {background-color: black;}
                .grid1-item:nth-child(3n + 1){background-color:yellow;}
                .grid1-item:nth-child(3n + 2) {background-color: red;}
            </style>
        

example: masonry

code:
                <div class="masonry">
                    <div class="masonry-item cell cell-1"><img src="../images/1a.jpg"></div>
                    <div class="masonry-item cell cell-2"><img src="../images/2a.jpg"></div>
                    <div class="masonry-item cell cell-3"><img src="../images/3a.jpg"></div>
                    <div class="masonry-item cell cell-4"><img src="../images/4a.jpg"></div>
                    <div class="masonry-item cell cell-5"><img src="../images/5a.jpg"></div>
                    <div class="masonry-item cell cell-6"><img src="../images/6a.jpg"></div>
                    <div class="masonry-item cell cell-7"><img src="../images/7a.jpg"></div>
                    <div class="masonry-item cell cell-8"><img src="../images/8a.jpg"></div>
                    <div class="masonry-item cell cell-9"><img src="../images/9a.jpg"></div>
                    <div class="masonry-item cell cell-10"><img src="../images/10a.jpg"></div>
                    <div class="masonry-item cell cell-11"><img src="../images/11a.jpg"></div>
                    <div class="masonry-item cell cell-12"><img src="../images/12a.jpg"></div>
                    <div class="masonry-item cell cell-13"><img src="../images/13a.jpg"></div>
                    <div class="masonry-item cell cell-14"><img src="../images/14a.jpg"></div>
                </div>
                <style> 
                    .masonry {width: 95%; height: 100vh; padding: 1rem;  display: grid; grid-template-columns: repeat(16, 1fr); 
                        grid-template-rows: repeat(14, 1fr); row-gap: 1vw; column-gap: 1vw;}
                    .cell-1 {grid-column: 1 / 6; grid-row: 1 / 6;}
                    .cell-2 {grid-column: 6 / 9; grid-row: 1 / 11;}
                    .cell-3 {grid-column: 9 / 12; grid-row: 1 / 4;}
                    .cell-4 {grid-column: 12 /-1; grid-row: 1 / 4;}
                    .cell-5 {grid-column: 1 / 4; grid-row: 6 / 11;}
                    .cell-6 {grid-column: 4 / 6; grid-row: 6 / 7;}
                    .cell-7 {grid-column: 4 / 6; grid-row: 7 / 11;}
                    .cell-8 {grid-column: 1 / 6; grid-row: 11 / -1;}
                    .cell-9 {grid-column: 6 / 12; grid-row: 11 / -1;}
                    .cell-10 {grid-column: 9 / 12; grid-row: 4 / 11;}
                    .cell-11 {grid-column: 12 / 13; grid-row: 4 / 6;}
                    .cell-12 {grid-column: 13 / -1; grid-row: 4 / 6;}
                    .cell-13 {grid-column: 12 / -1; grid-row: 6 / 13;}
                    .cell-14 {grid-column: 12 / -1; grid-row: 13 / -1;}  
                    img {display: block; width: 100%; height: 100%; object-fit: cover; 
                        border-radius: 5px;pointer-events: none;}       
                </style>
            

example: masonry

code:
                <div class="container">
                    <div class="gallery">
                        <figure class="gallery__item gallery__item--1">
                            <img src="../images/1a.jpg" class="gallery__img" alt="Image 1">
                        </figure>
                        <figure class="gallery__item gallery__item--2">
                            <img src="../images/2a.jpg" class="gallery__img" alt="Image 2">
                        </figure>
                        <figure class="gallery__item gallery__item--3">
                            <img src="../images/3a.jpg" class="gallery__img" alt="Image 3">
                        </figure>
                        <figure class="gallery__item gallery__item--4">
                            <img src="../images/4a.jpg" class="gallery__img" alt="Image 4">
                        </figure>
                        <figure class="gallery__item gallery__item--5">
                            <img src="../images/5a.jpg" class="gallery__img" alt="Image 5">
                        </figure>
                        <figure class="gallery__item gallery__item--6">
                            <img src="../images/6a.jpg" class="gallery__img" alt="Image 6">
                        </figure>
                    </div>
                </div>
                <style>
                    .container {width: 90%; margin: 2vw auto; }
                    .gallery {display: grid; grid-template-columns: repeat(8, 1fr);grid-template-rows: repeat(8, 5vw);}
                    .gallery__img {width: 100%; height: 100%; object-fit: cover;}
                    .gallery__item--1 { grid-column-start: 1; grid-column-end: 3; grid-row-start: 1; grid-row-end: 3;}
                    .gallery__item--2 {grid-column-start: 3; grid-column-end: 5; grid-row-start: 1; grid-row-end: 3;}
                    .gallery__item--3 {grid-column-start: 5; grid-column-end: 9; grid-row-start: 1; grid-row-end: 6;}
                    .gallery__item--4 {grid-column-start: 1; grid-column-end: 5;grid-row-start: 3; grid-row-end: 6;}
                    .gallery__item--5 {grid-column-start: 1; grid-column-end: 5; grid-row-start: 6; grid-row-end: 9;}
                    .gallery__item--6 {grid-column-start: 5; grid-column-end: 9; grid-row-start: 6; grid-row-end: 9;}
                </style>
            


grid templates

top

grid template 1

header
Main
Section
code:
           
                <div class="spec" id="content">
                    <header> header</header>
                    <main>Main </main>
                    <section>Section</section>
                    <aside>Aside</aside>
                    <nav>Nav</nav>
                    <footer>Footer</footer>
                </div>
                <style>
                    #content{display: grid; width:100%; margin: 0 auto; grid-template-columns: repeat(12, 1fr); grid-auto-rows: minmax(4vw, auto); grid-gap: 5px; position:relative;}
                    #content > *{background: red; padding: 10px}
                    header{grid-column:1/13;}
                    main{grid-column:4/13; grid-row:2/4;}
                    section{grid-column:1/9;grid-row:4/6;}
                    aside{grid-column:9/13;grid-row:4/6;}
                    nav{grid-column:1/4; grid-row: 2/4;}
                    footer{grid-column:1/13;}
                </style>
            

grid template 2

header
Main
Section
code:
                <div id="contentA">
                    <div class="logo">logo</div>
                    <header class="header"> header</header>
                    <main class="main">Main </main>
                    <section class="section">Section</section>
                    <aside class="aside">Aside</aside>
                    <nav class="nav">Nav</nav>
                    <footer class="footer">Footer</footer>
                </div>	
                <style>
                    #contentA{display: grid; max-width: 96vw; margin: 0 auto; grid-template-columns: repeat(12, 1fr); grid-auto-rows: minmax(4vw, auto); grid-gap: 0.5vw; position:relative;}
                    #contentA > *{background: black; padding: 1vw; color:white;}
                    .logo{grid-column:1/1}
                    .header{grid-column:2/13;}
                    .main{grid-column:4/13; grid-row:2/4;}
                    .section{grid-column:1/9;grid-row:4/6;}
                    .aside{grid-column:9/13;grid-row:4/6;}
                    .nav{grid-column:1/4; grid-row: 2/4;}
                    .footer{grid-column:1/13;}
                </style>
            

grid template 3

logo
header
Main
Section-1 Section-2
code:
                <div id="contentB">
                    <div class="logo1">logo</div>
                    <header class="header1"> header</header>
                    <main class="main1">Main </main>
                    <section-1 class="section1">Section-1</section-1>
                    <section-2 class="section1a">Section-2</section-2>
                    <aside class="aside1">Aside</aside>
                    <nav class="nav1">Nav</nav>
                    <footer class="footer1">Footer</footer>
                </div>	
                <style>
                    #contentB{display: grid; max-width: 96vw; margin: 0 auto; grid-template-columns: repeat(12, 1fr); grid-auto-rows: minmax(4vw, auto); grid-gap: 5px; position:relative;}
                    #contentB > *{background: yellow; padding: 10px}
                    .logo1{grid-column:1/1;}
                    .header1{grid-column:2/13;}
                    .main1{grid-column:4/13; grid-row:2/4;}
                    .section1{grid-column:1/13;grid-row:4/6;}
                    .section1a{grid-column:1/13;grid-row:6/8;}
                    .aside1{grid-column:1/13;grid-row:8/9;}
                    .nav1{grid-column:1/4; grid-row: 2/4;}
                    .footer1{grid-column:1/13;grid-row:9/10;}
                </style>
            

grid template 4

Logo
Header
Main
Sidebar
Album
Content
Footer
code:
                <div class="wrapper">
                    <div class="boxes logo2">Logo</div>
                    <div class="boxes header2">Header</div>
                    <div class="boxes main2">Main</div>
                    <div class="boxes sidebar2">Sidebar</div>
                    <div class="boxes album2">Album</div>
                    <div class="boxes content2">Content</div>
                    <div class="boxes footer2">Footer</div>
                </div>
                <style>
                    .logo2 {grid-area: logo;}
                    .header2 {grid-area: header;}
                    .main2 {grid-area: main;}
                    .sidebar2 {grid-area: sidebar;}
                    .album2{grid-area: album;}
                    .content2 {grid-area: content;}
                    .footer2 {grid-area: footer;}
                    .wrapper {display: grid; grid-gap: .5vw;
                            grid-template-columns: 5, minmax(5vw, auto);
                            grid-auto-rows: 6vw;
                            grid-template-areas:
                            "logo header header header header "
                            "sidebar content content . ."
                            "sidebar main main . ."
                            "album album album . ."
                            "footer footer footer footer footer";
                            background-color: red; color: black;}
                    .boxes { background-color: yellow; color: black; border-radius: .5vw; padding: 2vw; font-size: 100%;}
                    .header {background-color: #999;}
                </style>
            

grid template 5

A
B
C
D
E
code:
                <div class="wrapperB">
                    <div class="boxB a">A</div>
                    <div class="boxB b">B</div>
                    <div class="boxB c">C</div>
                    <div class="boxB d">D</div>
                    <div class="boxB e">E</div>
                </div>
                <style>
                    .wrapperB {display: grid; grid-gap: 5px;
                            grid-template-columns: repeat(24, 1fr);
                            grid-auto-rows: 9vw;
                            background-color: black; color: yellow;}
                    .boxB {background-color: yellow; color: red; border-radius: 5px; padding: 10px; font-size: 150%;}
                    .a {grid-column: 1/ span 12; grid-row: 1;}
                    .b {grid-column: 13 / span 12 ; grid-row: 1 ;}
                    .c {grid-column: 1/ span 6; grid-row: 2 ;}
                    .d {grid-column: 7 / span 18; grid-row: 2 ;}
                    .e {grid-column: 1/ span 24; grid-row: 3;}
                </style>
            

grid template 6

code:
                <div class="grid_a">
                    <div class="cell cell__1"></div>
                    <div class="cell cell__2"></div>
                    <div class="cell cell__3"></div>
                    <div class="cell cell__4"></div>
                    <div class="cell cell__5"></div>
                    <div class="cell cell__6"></div>
                    <div class="cell cell__7"></div>
                    <div class="cell cell__8"></div>
                    <div class="cell cell__9"></div>
                    <div class="cell cell__10"></div>
                    <div class="cell cell__11"></div>
                    <div class="cell cell__12"></div>
                    <div class="cell cell__13"></div>
                    <div class="cell cell__14"></div>
                    <div class="cell cell__15"></div>
                    <div class="cell cell__16"></div>
                </div>
                </div>
                <style>
                        .grid_a {display: grid; grid-auto-rows: 10vw;  grid-template-columns: 1fr 1fr 1fr; border: 1px solid black;}
                        .cell__1 { background-image: url('../images/1.jpg'); grid-column: 1 / 3; grid-row: 1 / 3; border: 2px solid black;}
                        .cell__2 { background-image: url('../images/2.jpg');}
                        .cell__3 { background-image: url('../images/3.jpg');}
                        .cell__4 { background-image: url('../images/4.jpg');}
                        .cell__5 { background-image: url('../images/5.jpg');}
                        .cell__6 { background-image: url('../images/6.jpg'); grid-column: 3 / 4; grid-row: 3 / 5; border: 2px solid black;}
                        .cell__7 { background-image: url('../images/7.jpg'); grid-column: 1 / 2; grid-row: 4 / 6;}
                        .cell__8 { background-image: url('../images/8.jpg');}
                        .cell__9 { background-image: url('../images/9.jpg'); grid-column: 2 / 4; grid-row: 5 / 6;}
                        .cell__10 { background-image: url('../images/10.jpg'); grid-column: 1 / 3; grid-row: 6 / 8;}
                        .cell__11 { background-image: url('../images/11.jpg');}
                        .cell__12 { background-image: url('../images/12.jpg');}
                        .cell__13 { background-image: url('../images/British.jpg'); grid-column: 1 / 2; grid-row: 8 / 10;}
                        .cell__14 { background-image: url('../images/cartoon.jpg');}
                        .cell__15 { background-image: url('../images/french.png');}
                        .cell__16 { background-image: url('../images/insta.png');  grid-column: 3 / 4;  grid-row: 8 / 10;}
                </style>
            

grid template 7

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
code:
                <div class="grid_b">
                    <div class="boxC">1</div>
                    <div class="boxC">2</div>
                    <div class="boxC">3</div>
                    <div class="boxC">4</div>
                    <div class="boxC">5</div>
                    <div class="boxC">6</div>
                    <div class="boxC">7</div>
                    <div class="boxC">8</div>
                    <div class="boxC">9</div>
                    <div class="boxC">10</div>
                    <div class="boxC">11</div>
                    <div class="boxC">12</div>
                    <div class="boxC">13</div>
                    <div class="boxC">14</div>
                    <div class="boxC">15</div>
                    <div class="boxC">16</div>
                    <div class="boxC">17</div>
                    <div class="boxC">18</div>
                    <div class="boxC">19</div>
                    <div class="boxC">20</div>
                    <div class="boxC">21</div>
                    <div class="boxC">22</div>
                    <div class="boxC">23</div>
                    <div class="boxC">24</div>
                    <div class="boxC">25</div>
                    <div class="boxC">26</div>
                    <div class="boxC">27</div>
                    <div class="boxC">28</div>
                </div>
                <style>
                    .grid_b {display: grid; grid-template-rows: repeat(6, 1fr); grid-template-columns: repeat(12, 1fr); grid-gap: 0.25vw; background-color: black; max-width:100%;}
                    .boxC {color: red;font-size: 2vw;padding: 1px;background: yellow;text-align: center;}
                    .boxC:nth-child(1) {grid-column: span 12;}
                    .boxC:nth-child(2), .boxC:nth-child(3) {grid-column: span 6;}
                    .boxC:nth-child(4),.boxC:nth-child(5),.boxC:nth-child(6) {grid-column: span 4;}
                    .boxC:nth-child(7),.boxC:nth-child(8),.boxC:nth-child(9),.boxC:nth-child(10){grid-column: span 3;}
                    .boxC:nth-child(11),.boxC:nth-child(12),.boxC:nth-child(13),.boxC:nth-child(14), .boxC:nth-child(15),.boxC:nth-child(16) {grid-column: span 2;}
                    @media screen and (max-width: 575px) {
                        .grid { display: block; }
                        .box { margin: 10px 0; }
                    }
                </style>	
            

grid template 8

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
code:
                <div class="grid_c">
                    <div class="boxD">1</div>
                    <div class="boxD">2</div>
                    <div class="boxD">3</div>
                    <div class="boxD">4</div>
                    <div class="boxD">5</div>
                    <div class="boxD">6</div>
                    <div class="boxD">7</div>
                    <div class="boxD">8</div>
                    <div class="boxD">9</div>
                    <div class="boxD">10</div>
                    <div class="boxD">11</div>
                    <div class="boxD">12</div>
                    <div class="boxD">13</div>
                    <div class="boxD">14</div>
                    <div class="boxD">15</div>
                    <div class="boxD">16</div>
                    <div class="boxD">17</div>
                    <div class="boxD">18</div>
                    <div class="boxD">19</div>
                    <div class="boxD">20</div>
                    <div class="boxD">21</div>
                    <div class="boxD">22</div>
                    <div class="boxD">23</div>
                    <div class="boxD">24</div>
                    <div class="boxD">25</div>
                    <div class="boxD">26</div>
                    <div class="boxD">27</div>
                    <div class="boxD">28</div>
                </div>
                <style>
                    .grid_c {display: grid; grid-template-rows: repeat(12, 1fr); grid-template-columns: repeat(6, 1fr); grid-auto-flow: column; grid-gap: 0.25vw; background-color: red; max-width:100%;}
                    .boxD {color: black;font-size: 2vw; padding: 1px;background: yellow;margin: 0; text-align: center;}
                    .boxD:nth-child(1) {grid-row: span 12;}
                    .boxD:nth-child(2), .boxD:nth-child(3) {grid-row: span 6;}
                    .boxD:nth-child(4),.boxD:nth-child(5),.boxD:nth-child(6) {grid-row: span 4;}
                    .boxD:nth-child(7),.boxD:nth-child(8),.boxD:nth-child(9),.boxD:nth-child(10) {grid-row: span 3;}
                    .boxD:nth-child(11),.boxD:nth-child(12),.boxD:nth-child(13),.boxD:nth-child(14),.boxD:nth-child(15), .boxD:nth-child(16) {grid-row: span 2;}
                </style>
            

grid template 9

1
2
3
4
5
6
7
8
9
10
11
12
13
code:
                <div class="grid_d">
                    <div class="grid-container">
                        <div class="item1">1</div>
                        <div class="item2">2</div>
                        <div class="item3">3</div>  
                        <div class="item4">4</div>
                        <div class="item5">5</div>
                        <div class="item6">6</div>
                        <div class="item7">7</div>
                        <div class="item8">8</div>  
                        <div class="item9">9</div>
                        <div class="item10">10</div>
                        <div class="item11">11</div>
                        <div class="item12">12</div>
                        <div class="item13">13</div>
                    </div>
                </div>
                <style>
                    .grid-container {display: grid;grid-template-columns: auto auto auto auto auto auto; grid-gap: 0.5vw; background-color: red;padding: 10px;}
                    .grid-container > div {background-color: yellow;text-align: center;padding: 20px 0; font-size: 30px;}
                    .item8 {/*grid-area: 1 / 2 / 5 / 6;*/grid-area: 2 / 1 / span 2 / span 3;}
                </style>  
            


the repeat() function

The repeat() function allows to repeat columns as many times as needed. When creating a 12-columns grid, you could write the following one-liner:

       <style>
            .grid {display: grid;/* define the number of grid columns */ grid-template-columns: repeat(12, 1fr);}
        </style>
    

The "1fr" tells the browser to distribute the space between the columns so that each column equally gets one fraction of that space. They are all fluid, equal-width columns, and the grid will always have 12 columns regardless of how wide it is. However, the content will be too squished on smaller viewports. By using "the minmax() function", a minimum width for the columns can be specified, making sure they don't get too narrow.

        <style>
            grid-template-columns: repeat( 12, minmax(250px, 1fr) );
        </style>
    

But due to the way CSS grid works, this will cause overflow in the row. The columns will not wrap into new rows if the viewport width is too narrow to fit them all with the new minimum width requirement, because the browser is explicitly told to repeat the columns 12 times per row. To achieve wrapping, the "auto-fit" or "auto-fill" keywords can be used.

 
        <style>
            grid-template-columns: repeat( auto-fit, minmax(250px, 1fr) );
        </style>
    

These keywords tell the browser to handle the column sizing and element wrapping for us so that the elements will wrap into rows when the width is not large enough to fit them in without any overflow. The "fraction unit" (i.e. fr) also ensures that in case the width allows for a fraction of a column to fit but not a full column, that space will instead be distributed over the column or columns that already fit, making sure any empty space is left at the end of the row.

auto-fill vs. auto-fit

auto-fill FILLS the row with as many columns as it can fit : it creates implicit columns whenever a new column can fit, because it's trying to FILL the row with as many columns as it can. The newly added columns can and may be empty, but they will still occupy a designated space in the row.

auto-fit FITS the currentyl available columns into the space by expanding them so that they take up any available space. The browser does that after FILLING that extra space with extra columns (as with auto-fill ) and then collapsing the empty ones.

example: auto-fill vs. auto-fit

auto-fill

1
2
3
4
5
6
7

auto-fit

1
2
3
4
5
6
7
code
                <div class="grid-container grid-container--fill" style="margin-left:4vw;">
                    <div class="grid-element">1</div>
                    <div class="grid-element">2</div>
                    <div class="grid-element">3</div>
                    <div class="grid-element">4</div>
                    <div class="grid-element">5</div>
                    <div class="grid-element">6</div>
                    <div class="grid-element">7</div>
                </div>

                <p class="spec">auto-fit</p>
                    <div class="grid-container grid-container--fit" style="margin-left:4vw;">
                        <div class="grid-element">1</div>
                        <div class="grid-element">2</div>
                        <div class="grid-element">3</div>
                        <div class="grid-element">4</div>
                        <div class="grid-element">5</div>
                        <div class="grid-element">6</div>
                        <div class="grid-element">7</div>
                    </div>
                <style>
                    .grid-container {display: grid;}
                    .grid-container--fill {grid-template-columns: repeat(auto-fill, minmax(100px, 1fr));}
                    .grid-container--fit {grid-template-columns: repeat(auto-fit, minmax(80px, 1fr));}
                    .grid-element {background-color: deepPink; padding: 20px; color: #fff; border: 1px solid #fff; }
                </style>
            

"auto-fill" and "auto-fit" don't have identical behavior under the hood. They will give the same result up to a certain viewport width. The point at which these two keywords start exhibiting different behaviors depends on the "number" and "size" of columns defined in grid-template-columns, so it will differ from one example to another.

The difference between these two keywords is made apparent when the viewport gets wide enough to fit one (or more) extra column(s) into the row. At that point, the browser is presented with two ways to handle the situation, and how it handles it largely depends on whether or not there is content to be placed into that extra column. The difference between "auto-fill" and "auto-fit" for sizing columns is only noticeable when the row is wide enough to fit more columns in it.

When using "auto-fit", the content will stretch to fill the entire row width. When using "auto-fill", the browser will allow empty columns to occupy space in the row like their non-empty neighbors — they will be allocated a fraction of the space even if they have no grid items in them, thus affecting the size/width of the latter.

example: auto-fill vs. auto-fit

1
2
3
4
5
1
2
3
4
5
code
                <div>
                    <div class="wrapper-1">
                        <div class="box">1</div>
                        <div class="box">2</div>
                        <div class="box">3</div>
                        <div class="box">4</div>
                        <div class="box">5</div>
                    </div>
                    <div class="wrapper-2">
                        <div class="box">1</div>
                        <div class="box">2</div>
                        <div class="box">3</div>  
                        <div class="box">4</div>  
                        <div class="box">5</div>  
                    </div>
                </div>
                <style>
                    .box {background-color: #444; color: #fff; border-radius: .5vw; padding: 2vw; font-size: 150%;}
                    .box:nth-child(even) {background-color: #ccc; color: #000;}
                    .wrapper-1 {display: grid; border:0.1vw solid #000; grid-gap: 1vw; grid-template-columns: repeat(auto-fill, minmax(10vw,1fr)); margin-bottom: 2vw;}
                    .wrapper-2 {display: grid; border:0.1vw solid #000; grid-gap: 1vw; grid-template-columns: repeat(auto-fit, minmax(10vw,1fr));}
                </style> 
            

auto-fill

1
2
3
4
5
6
7
8

auto-fit

1
2
3
4
5
6
7
8
code
                <div class="spec">
                    <p class="spec">auto-fill</p>
                    <div class="container-1">
                        <div class="item item1">1</div>
                        <div class="item item2">2</div>       
                        <div class="item item3">3</div>       
                        <div class="item item4">4</div>       
                        <div class="item item5">5</div>       
                        <div class="item item6">6</div>       
                        <div class="item item7">7</div>       
                        <div class="item item8">8</div>   
                    </div>
                    <p class="spec">auto-fit</p>
                    <div class="container-2">
                        <div class="item item10">1</div>
                        <div class="item item11">2</div>       
                        <div class="item item12">3</div>       
                        <div class="item item13">4</div>       
                        <div class="item item14">5</div>       
                        <div class="item item15">6</div>       
                        <div class="item item16">7</div>       
                        <div class="item item17">8</div>   
                    </div>
                </div>
                <style>
                    .item { display: flex; justify-content: center; align-items: center; border: 0.5vw solid #87b5ff; border-radius: 0.3vw;  font-size: 2vw; 
                        font-family: sans-serif; font-weight: bold; background-color: #1c57b5; }
                    /* CSS Grid styles */
                    .container-1 {display: grid; grid-template-columns: repeat(auto-fill, minmax(8vw, 1fr)); grid-gap: 1.5vw;}
                    .container-2 {display: grid; grid-template-columns: repeat(auto-fit, minmax(8vw, 1fr)); grid-gap: 1.5vw;}
                </style> 
            


grid expansions

top

Essentially, any given grid cell could have a button that would open up another, larger area that is also part of the grid. But this new larger grid cell needed to be: right below the cell that opened it, and full width. There is a nice solution to it, and in the spirit of "CSS Grid" itself. It only involves a couple of lines of code.

trick #1

the grid-template-columns: repeat(autofit, 20vw);

        <style>
            .grid {display: grid; gap: 1vw; grid-template-columns: repeat(auto-fit, 20vw);}     
        </style>
    

The "secret sauce" in this code is the "grid-template-columns: repeat(auto-fit, 20vw);", which gives us a grid with columns (20vw wide in this example) that are arranged automatically in the available space, wrapping to the next row when there's not enough room.

trick #2

Next, a new full-width card has to be accomodated into the grid:

        <style>
            .fullwidth {grid-column: 1 / -1;}
        </style>
    

This code works because grid-template-columns in trick #1 creates an "explicit" grid, so it's possible to define start and end columns for the ".fullwidth card", where 1 / -1 means "start in column 1, and span every column up to the very last one".

trick #3

Filling the gaps has been done with a faux-masonry approach.

        <style>
            .grid {grid-auto-flow: dense;}
        </style>
    

The "grid-auto-flow property" controls how the CSS Grid auto-placement algorithm works. In this case, the dense packing algorithm tries to fill in holes earlier in the grid. All our grid columns are the same width. Dense packing also works if the column widths are flexible, for example, by using minmax(20vw, 1fr). All our grid “cells” are the same height in each row. This is the default CSS Grid behavior. The grid container implicitly has "align-items: stretch" causing cells to occupy 100% of the available row height.

The result of all this is that the holes in our grid are filled — and the beautiful part is that the original source order is preserved in the rendered output. This is important from an accessibility perspective.

the complete solution

the complete solution

code:
                <style>
                    ul[class] {margin: 0;padding: 0;}
                    ul[class] li {list-style: none;}
                    ul[class] li > * {margin: 1vw;}
                    :focus:not(details summary) { box-shadow: 0 0 0 0.25vw rebeccapurple; outline: 0;}
                    /* [1] 'auto-fit' grid columns, so no media queries required. */
                    /* [2] 'dense' packing fills in holes earlier in the grid. */
                    .grid-A {display: grid; gap: 1vw; grid-auto-flow: dense; /* [2] */ 
                        grid-template-columns: repeat(auto-fit, 20vw); /* [1] */ 
                        justify-content: center;}
                    .grid-A > * {align-items: flex-start; background: grey; display: flex; 
                        flex-direction: column; height: 100%;}
                    /* [3] Make fullwidth card span all grid columns. */
                    .fullwidth {grid-column: 1 / -1;}
                    .is-hidden {display: none;}
                    .fullwidth,.is-selected {background: wheat; }
                </style>
                <div>
                    <ul class="grid-A">
                        <li>
                            <p class="spec">1</p>
                        </li>
                        <li>
                            <p class="spec">2</p>
                            <button type="button" data-quick-view>Quick view</button>
                        </li>
                        <li class="fullwidth is-hidden" id="quickview-01">
                            <button type="button" data-close>close 2</button>
                            <p class="spec">fullwidth 2</p>
                            <p class="spec">This grid item needs to stretch the full width of the page, and force other grid items to reflow around it, whilst remaining "visually connected" to the preceeding grid item.</p>
                            <p class="spec">Test <a href="#">inline link</a>.</p>
                        </li>
                        <li>
                            <p class="spec">3</p>
                        </li>
                        <li>
                            <p class="spec">4</p>
                            <button type="button" data-quick-view>Quick view</button>
                        </li>
                        <li class="fullwidth is-hidden" id="quickview-04">
                            <button type="button" data-close>Close 4</button>
                            <p class="spec">fullwidth 4</p>
                            <p class="spec">This grid item needs to stretch the full width of the page, and force other grid items to reflow around it, whilst remaining "visually connected" to the preceeding grid item.</p>
                            <p class="spec">Test <a href="#">inline link</a>.</p>
                        </li>
                        <li>
                            <p class="spec">5</p>
                            <button type="button" data-quick-view>Quick view</button>
                        </li>
                        <li class="fullwidth is-hidden" id="quickview-05">
                            <button type="button" data-close>Close 5</button>
                            <p class="spec">fullwidth 5</p>
                            <p class="spec">This grid item needs to stretch the full width of the page, and force other grid items to reflow around it, whilst remaining "visually connected" to the preceeding grid item.</p>
                            <p class="spec">Test <a href="#">inline link</a>.</p>
                        </li>
                        <li>
                            <p class="spec">6</p>
                        </li>
                        <li>
                            <p class="spec">7</p>
                        </li>
                        <li>
                            <p class="spec">8</p>
                        </li>
                    </ul>
                </div>
                <script>
                    const quickViewButtons = document.querySelectorAll('[data-quick-view]');
                    const closeButtons = document.querySelectorAll('[data-close');
                    const fullwidthCards = document.querySelectorAll('.fullwidth');
                    let toggle; // Quick view <button>.
                    let toggleParent; // <li>.
                    let fullwidth; // Fullwidth card to be "injected".
        
                    const openQuickView = (toggle, toggleParent, fullwidth) => {
                        toggle.setAttribute('aria-expanded', 'true');
                        toggleParent.classList.toggle('is-selected');
                        fullwidth.classList.toggle('is-hidden');
                        // Make fullwidth card keyboard focusable.
                        fullwidth.setAttribute('tabIndex', '0');
                    };
        
                    const closeQuickView = (toggle, toggleParent, fullwidth) => {
                        toggle.setAttribute('aria-expanded', 'false');
                        toggleParent.classList.toggle('is-selected');
                        fullwidth.classList.toggle('is-hidden');
                        fullwidth.removeAttribute('tabIndex');
                    };
        
                    quickViewButtons.forEach(quickView => {
                        // Add appropriate ARIA attributes for "toggle" behaviour.
                        fullwidth = quickView.parentElement.nextElementSibling;
                        quickView.setAttribute('aria-expanded', 'false');
                        quickView.setAttribute('aria-controls', fullwidth.id);
                        quickView.addEventListener('click', (e) => {
                            toggle = e.target;
                            toggleParent = toggle.parentElement;
                            fullwidth = toggleParent.nextElementSibling;
                            // Open (or close) fullwidth card.
                        if (toggle.getAttribute('aria-expanded') === 'false') {
                            // Do we have another fullwidth card already open? If so, close it.
                                fullwidthCards.forEach(fullwidthOpen => {
                                    if (!fullwidthOpen.classList.contains('is-hidden')) {
                                        toggleParentOpen =
                                            fullwidthOpen.previousElementSibling;
                                        toggleOpen = toggleParentOpen.querySelector(
                                            '[data-quick-view'
                                        );
                                        closeQuickView(toggleOpen, toggleParentOpen, fullwidthOpen);
                                    }
                                });
                                openQuickView(toggle, toggleParent, fullwidth);
                            } else {
                                closeQuickView(toggle, toggleParent, fullwidth);
                            }
                        });
                    });
        
                    closeButtons.forEach(close => {
                        close.addEventListener('click', (e) => {
                            fullwidth = e.target.parentElement;
                            toggleParent = e.target.parentElement.previousElementSibling;
                            toggle = toggleParent.querySelector('[data-quick-view');
                            closeQuickView(toggle, toggleParent, fullwidth);
                            toggle.focus(); // Return keyboard focus to "toggle" button.
                        });
                    });
                </script>      
            


simple asymmetric grid

top
1
2
3
4
5
6
7
8
9
10
11
code
                <div class="container">
                <div class="normal"> 1 </div>
                <div class="vertical"> 2 </div>
                <div class="horizontal"> 3 </div>
                <div class="normal"> 4 </div>
                <div class="normal"> 5 </div>
                <div class="big"> 6 </div>
                <div class="normal"> 7 </div>
                <div class="vertical"> 8 </div>
                <div class="horizontal"> 9 </div>
                <div class="normal"> 10 </div>
                <div class="normal"> 11 </div>
                </div>
                <style>
                .container { display: grid; grid-gap: 0.2vw; grid-template-columns: repeat(auto-fit, minmax(40vw, 1fr)); grid-auto-rows: 5vw;   grid-auto-flow: dense; width: 40vw;}
                .horizontal {background: darkblue; grid-column: span 2;}
                .vertical {background: blue; grid-row: span 2; }
                .big {background: lightblue; grid-column: span 2; grid-row: span 2; }
                .normal { background: teal; }
                .container > div{ display: flex; justify-content: center; align-items: center; font-size: 2vw; color: lightgreen; font-family: helvetica;}
                </style>
            


adaptive photo layout

top

example: adaptive photo layout

code:
                <ul>
                    <li><img src="../images/1.jpg" alt="holiday" loading="lazy"></li>
                    <li><img src="../images/1a.jpg" alt="beach" loading="lazy"></li>
                    <li><img src="../images/2.jpg" alt="beach" loading="lazy"></li>
                    <li><img src="../images/3.jpg" alt="bath" loading="lazy"></li>
                    <li><img src="../images/4.jpg" alt="sailing" loading="lazy"></li>
                    <li><img src="../images/4a.jpg" alt="portrait" loading="lazy"></li>
                    <li><img src="../images/5.jpg" alt="palmtrees" loading="lazy"></li>
                    <li><img src="../images/5a.jpg" alt="traffic" loading="lazy"></li>
                    <li><img src="../images/6.jpg" alt="sailing" loading="lazy"></li>
                    <li><img src="../images/6a.jpg" alt="butterfly" loading="lazy"></li>
                    <li><img src="../images/7.jpg" alt="interior" loading="lazy"></li>
                    <li><img src="../images/8.jpg" alt="beach" loading="lazy"></li>
                    <!--  Adding an empty <li> here so the final photo doesn't stretch like crazy.  Try removing it and see what happens!  -->
                    <li></li>
                </ul>
                <style>
                    ul {display: grid; grid-template-columns: 1fr 1fr 1fr; gap: 0.2vw 0.2vw; width: auto; text-decoration-style: none;}
                    li {height: 15vh; max-width:15vw; list-style: none;}
                    img {height: 100%; width: 100%; object-fit: cover; vertical-align: bottom;}
                    @media only screen and (max-width: 750px){
                        ul{grid-template-columns: 1fr 1fr; gap: 0.1vw 0.1vw;}
                    }
                    @media only screen and (max-width: 660px){
                    ul{grid-template-columns: 1fr; gap: 0.1vw;}
                    }
                </style>
            


grid and background patterns

top
A N T W E R P E N
P R O V I N C I E
G R A P H I C   D E S I G N
code:
                <div class="wrap">
                <div class="block-title">
                    <div class="title-1">
                    <span>A</span>
                    <span>N</span>
                    <span>T</span>
                    <span>W</span>
                    <span>E</span>
                    <span>R</span>
                    <span>P</span>
                    <span>E</span>
                    <span>N</span>
                    </div>
                    <div class="title-2">
                    <span>P</span>
                    <span>R</span>
                    <span>O</span>
                    <span>V</span>
                    <span>I</span>
                    <span>N</span>
                    <span>C</span>
                    <span>I</span>
                    <span>E</span>
                    </div>
                    <div class="title-3">
                    <span>G</span>
                    <span>R</span>
                    <span>A</span>
                    <span>P</span>
                    <span>H</span>
                    <span>I</span>
                    <span>C</span>
                    <span> </span>
                    <span>D</span>
                    <span>E</span>
                    <span>S</span>
                    <span>I</span>
                    <span>G</span>
                    <span>N</span>
                    </div>
                </div>
                <div class="block style-1"></div>
                <div class="block style-2"></div>
                <div class="block style-3"></div>
                <div class="block style-4"></div>
                <div class="block style-5"></div>
                <div class="block style-6"></div>
                <div class="block style-7"></div>
                <div class="block style-8"></div>
                <div class="block style-9"></div>
                <div class="block style-10"></div>
                <div class="block style-6"></div>
                <div class="block style-3"></div>
                <div class="block style-12"></div>
                <div class="block style-1"></div>
                <div class="block style-11"></div>
                <div class="block style-7"></div>
                <div class="block style-2"></div>
                <div class="block-13"></div>
                </div>

                <style>
                .wrap { background: #f7f7f7; margin-top: 2vw; margin-bottom: 2vw; width: 50vw;  height: 120vw; border-radius: 5vw; overflow: hidden; display: grid; grid-template-columns: repeat(4, 1fr);}
                .block {width: 12vw; height: 12vw;}
                .block-title { background: gray; grid-column-start: 2; grid-column-end: -1; grid-row-start: 3; grid-row-end: 5; display: flex; padding: 3vw 3.5vw; transition: padding .3s linear; align-items: stretch; justify-content: 
                    space-between; flex-direction: column;}
                .block-title > div { display: flex; justify-content: space-between;}
                .block-title:hover {padding: 3vw;}
                .block-title:hover .title-1 {order: 0;}
                .block-title:hover .title-2 {order: 2;}
                .block-title:hover .title-3 {order: 1;}
                .title-1, .title-3 {font-weight: 800; font-size: 3vw;}
                .title-2 {font-weight: 600; font-size: 1.1vw;}
                .title-3 {order: 1;}
                .style-1 {background: #454547;}
                .style-2 {width: 0; height: 0; border: 6vw solid #f7f7f7; border-top-color: #aeafb3; border-bottom-color: #aeafb3; background: #aeafb3; padding-top: 0.1vw;}
                .style-3 {background-image: linear-gradient(135deg, #e89d93 50%, #dbdbdd 50%);}
                .style-4 {background-image: linear-gradient(#f7f7f7, #f7f7f7 0.4vw, #454547 0.4vw, #454547); background-size: 100% 1.4vw;}
                .style-5 {background-image: linear-gradient(45deg, #eec71a 50%, #f7f7f7 50%);}
                .style-6 {background-image: linear-gradient(135deg, #454547 50%, transparent 50%), linear-gradient(#f7f7f7, #f7f7f7 7px, #454547 7px, #454547); background-size: 100%, 100% 14px;}
                .style-7 {background: linear-gradient(45deg, #dbdbdd 50%, transparent 50%), radial-gradient(#454547 4px, transparent 4px), radial-gradient(#454547 4px, transparent 4px), transparent; 
                    background-size: 100%, 24px 24px, 24px 24px, 100%; background-position: 0 0, -2px 6px, 10px 18px, 0 0;}
                .style-8 {background-image: linear-gradient(315deg, #eec71a 50%, #f7f7f7 50%);}
                .style-9 {background-image: linear-gradient(225deg, #e89d93 50%, #f7f7f7 50%);}
                .style-10 {background: #dbdbdd;}
                .style-11 {background-image: linear-gradient(45deg, #e89d93 50%, #f7f7f7 50%);}
                .style-12 {background-image: linear-gradient(225deg, #eec71a 50%, #f7f7f7 50%);}
                .block-13 {  background-image: linear-gradient(to right, #e89d93, #e89d93 4px, #f7f7f7 4px, #f7f7f7);background-size: 8px 100%;}
                </style>
            


pure CSS perspective portfolio

top
Portfolio Item

Title

Description.

Portfolio Item

Title

Description.

Portfolio Item

Title

Description.

Portfolio Item

Title

Description.

Portfolio Item

Title

Description.

Portfolio Item

Title

Description.

Portfolio Item

Title

Description.

Portfolio Item

Title

Description.

Portfolio Item

Title

Description.

code:
            <div id="container-1"> 
            <figure>
                <img src="../images/Argonath1.jpg" alt="Portfolio Item">
                <figcaption>
                    <h4>Title</h4>
                    <p>Description.</p>
                </figcaption>
            </figure>
        
            <figure>
                <img src="../images/car2.jpg" alt="Portfolio Item">
                <figcaption>
                    <h4>Title</h4>
                    <p>Description.</p>
                </figcaption>
            </figure>
        
            <figure>
                <img src="../images/einstein.jpg" alt="Portfolio Item">
                <figcaption>
                    <h4>Title</h4>
                    <p>Description.</p>
                </figcaption>
            </figure>
        
            <figure>
                <img src="../images/g-orwell.jpg" alt="Portfolio Item">
                <figcaption>
                    <h4>Title</h4>
                    <p>Description.</p>
                </figcaption>
            </figure>
        
            <figure>
                <img src="../images/hemingway.jpg" alt="Portfolio Item">
                <figcaption>
                    <h4>Title</h4>
                    <p>Description.</p>
                </figcaption>
            </figure>
        
            <figure>
                <img src="../images/malcom-x.jpg" alt="Portfolio Item">
                <figcaption>
                    <h4>Title</h4>
                    <p>Description.</p>
                </figcaption>
            </figure>
        
            <figure>
                <img src="../images/poum.jpg" alt="Portfolio Item">
                <figcaption>
                    <h4>Title</h4>
                    <p>Description.</p>
                </figcaption>
            </figure>
        
            <figure>
                <img src="../images/tesla.jpg" alt="Portfolio Item">
                <figcaption>
                    <h4>Title</h3>
                    <p>Description.</p>
                </figcaption>
            </figure>
        
            <figure>
                <img src="../images/tolkien.jpg" alt="Portfolio Item">
                <figcaption>
                    <h4>Title</h4>
                    <p>Description.</p>
                </figcaption>
            </figure>​ 
            </div>
            <style>
                #container-1{display: grid; grid-template-columns: repeat(3,1fr); gap: 1vw; width: 96vw; height: auto; } 
                figure {float: left; height: 6vw; margin: 1vw; width: 12vw; -webkit-transform: perspective(500);transform: perspective(500);     -webkit-transform-style: preserve-3d;transform-style: preserve-3d; 
                    -webkit-transition: .5s; transition: .5s;}
                figure:hover {-webkit-transform: perspective(500) rotateX(90deg) translateY(-3em) translateZ(3em); transform: perspective(500) rotateX(90deg) translateY(-3em) translateZ(3em);}
                img {background-color: #333; box-shadow: 0 2vw 1.5vw -1vw hsla(0,0%,0%,.25); display: block; height: 100%;-webkit-transition: .5s;transition: .5s; }
                figure:hover img {box-shadow: none;}
                figcaption {background-color: #222; color: #fff;padding: 1.5vw; -webkit-transform: rotateX(-90deg); -webkit-transform-origin: 100% 0;
                -webkit-transition: .5s;; transform: rotateX(-90deg); transform-origin: 100% 0; transition: .5s;}
                figure:hover figcaption {box-shadow: 0 2vw 1.5vw -1vw hsla(0,0%,0%,.25);}
                h4 {font-weight: bold;}
            </style>