Recommand · June 12, 2021 0

resize column across multiple rows using html grid layout

I’ve got a grid layout with 2 columns and 3 rows.

I want to be able to resize the column widths. I know I can use resize: horizontal but that only changes width for one row.

I’m thinking I can’t do what I want and I’ll need to use nested grids but I’m not sure so I wanted to check.

<!DOCTYPE html>
<html>

    <head>
        <style>
            .container {
                display: grid;
                grid-template-columns: 1fr 1fr;
                grid-template-rows: 1fr 1fr 1fr;
                gap: 0px 0px;
                grid-auto-flow: row;
                grid-template-areas:
                    "logo search"
                    "nav main"
                    "log main";
            }

            .logo {
                grid-area: logo;
            }

            .search {
                grid-area: search;
            }

            .nav {
                grid-area: nav;
                overflow: auto;
                resize: horizontal;
            }

            .log {
                grid-area: log;
                overflow: auto;
                resize: horizontal;
            }

            .main {
                grid-area: main;
            }


            html,
            body,
            .container {
                height: 100%;
                margin: 0;
            }

            /* For presentation only, no need to copy the code below */

            .container * {
                border: 1px solid red;
                position: relative;
            }

            .container *:after {
                content: attr(class);
                position: absolute;
                top: 0;
                left: 0;
                width: 100%;
                height: 100%;
                display: grid;
                align-items: center;
                justify-content: center;
            }
        </style>
    </head>

    <body>
        <div class="container">
            <div class="logo"></div>
            <div class="search"></div>
            <div class="nav">

            </div>
            <div class="log"></div>
            <div class="main"></div>
        </div>
    </body>

</html>

You can do it with your structure. The trick is to use auto 1fr on the template columns and set the initial width of the resizable element to be equal to 50vw to simulate the 1fr 1fr initially:

PS: I simplified the code by removing the areas but that’s not part of the trick, you can keep it

.container {
  display: grid;
  height: 100vh;
  grid-template-columns: auto 1fr;
  grid-template-rows: 1fr 1fr 1fr;
}

.log {
  overflow: auto;
  resize: horizontal;
  width:50vw;
}

.main {
  grid-row:2/span 2;
  grid-column:2;
}

body{
  margin: 0;
}


/* For presentation only, no need to copy the code below */

.container * {
  border: 1px solid red;
  position: relative;
}

.container *:after {
  content: attr(class);
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  display: grid;
  align-items: center;
  justify-content: center;
}
<div class="container">
  <div class="logo"></div>
  <div class="search"></div>
  <div class="nav">

  </div>
  <div class="log"></div>
  <div class="main"></div>
</div>

If you will have content, you can do it like below:

.container {
  display: grid;
  height: 100vh;
  grid-template-columns: auto 1fr;
  grid-template-rows: 1fr 1fr 1fr;
}

.log {
  overflow: auto;
  resize: horizontal;
  width:50vw;
}
/* disable the width contribution so only the log will define the width */
.logo,
.nav {
  width:0;
  min-width:100%;
}
/**/
.main {
  grid-row:2/span 2;
  grid-column:2;
}

body{
  margin: 0;
}


/* For presentation only, no need to copy the code below */

.container * {
  border: 1px solid red;
  position: relative;
}
<div class="container">
  <div class="logo"> Lorem ipsum dolor sit amet, consectetur .</div>
  <div class="search"> </div>
  <div class="nav">Lorem ipsum dolor sit amet, consectetur adipiscing elit. 
  </div>
  <div class="log"> </div>
  <div class="main"></div>
</div>