Dwij Bavisi
Dwij Bavisi

Reputation: 3

Flex item fill height but without flex-direction: column

What I have so far

This is the flex layout I have. It is based on the idea of holy-grail. This is what current layout look

What I'm trying to do

I need main to stretch to fill remaining height This is what I'm trying to make

Most solutions I found on the internet won't work for me.
So far my attempts with %based heights have nothing fruitful.
Setting main height to 100% will make it overflow parent container.
Headers and footer don't have fixed height, hence, calc based solutions also won't work.


External Links:

current_layout: https://i.sstatic.net/GooN5.png
trying layout: https://i.sstatic.net/3Ovic.png

Code snippet

.ctm .grail {
    display: flex;
    flex-direction: column;
    flex-wrap: wrap;

    justify-content: flex-start;
    align-content: space-between;

    gap: var(--ctm-gap, 1em) var(--ctm-gap, 1em);
}

.ctm .grail>details,
.ctm .grail>header,
.ctm .grail>nav,
.ctm .grail>footer {
    flex-basis: 100%;
}

.ctm .grail>header {
    min-height: 4em;
}

.ctm .grail>main {
    flex-grow: 3;
}

.ctm .grail>aside {
    flex-grow: 1;
    min-width: min(6em, 100%);
}

<!DOCTYPE html>
<html lang="en" class="ctm">

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Consortium Test</title>

    <link rel="stylesheet" href="../../assets/output/web/styles.css">

    <style>
        body {
            margin: 0;
            min-height: 100vh;
            background-color: #122334;
        }

        details {
            background-color: #f00;
            color: #fff;
        }

        header {
            background-color: #f44;
            color: #fff;
        }

        nav {
            background-color: #0f0;
            color: #fff;
        }

        aside {
            background-color: #00f;
            color: #fff;
        }

        main {
            background-color: #ff0;
            color: #000;
        }

        footer {
            background-color: #f0f;
            color: #fff;
        }

    </style>
</head>

<body class="grail">
    <details>
        <summary>Notification</summary>
        <p>Details</p>
    </details>
    <header>Header</header>
    <nav>Navigation</nav>
    <aside>Left</aside>
    <main>Main</main>
    <aside>Right</aside>
    <footer>Footer</footer>
</body>

</html>

Upvotes: 0

Views: 52

Answers (2)

Dominika Wojewska
Dominika Wojewska

Reputation: 53

Have you tried vh based heights?

Having set the height of all the elements apart from main would be really helpful, as it allows to use calc().

Other than that, here is my solution for your problem:https://codepen.io/SwampWitch/pen/eYjrmNa?editors=1100

I wrapped main and aside in a div, then used display: flex on it, along with eyeballed value of height: 80vh. Using calc() would be much more elegant solution and a responsive one at that.

Upvotes: 1

Ronak
Ronak

Reputation: 419

Structure of HTML needs to be change to get the required output

<!DOCTYPE html>
<html lang="en" class="ctm">
  <head>
    <meta charset="UTF-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Consortium Test</title>


    <style>
      body {
        margin: 0;
        min-height: 100vh;
        background-color: #122334;
      }

      details {
        background-color: #f00;
        color: #fff;
      }

      header {
        background-color: #f44;
        color: #fff;
      }

      nav {
        background-color: #0f0;
        color: #fff;
      }

      aside {
        background-color: #00f;
        color: #fff;
      }

      main {
        background-color: #ff0;
        color: #000;
      }

      footer {
        background-color: #f0f;
        color: #fff;
      }

      .ctm .grail {
        display: flex;
        flex-direction: column;
        flex-wrap: wrap;

        justify-content: flex-start;
        align-content: space-between;

        gap: var(--ctm-gap, 1em) var(--ctm-gap, 1em);
      }

      .ctm .grail > details,
      .ctm .grail > header,
      .ctm .grail > nav,
      .ctm .grail > footer {
        width: 100%;
      }

      .ctm .grail > header {
        min-height: 4em;
      }

      .body main {
        flex-grow: 2;
      }

      /* .ctm .grail   */
      .body {
        display: flex;
        flex-direction: row;
        flex: 1;
        gap: 16px;
        /* wid */
      }
      .body aside {
        flex-grow: 1;
        min-width: min(6em, 100%);
      }
    </style>
  </head>

  <body class="grail">
    <details>
      <summary>Notification</summary>
      <p>Details</p>
    </details>
    <header>Header</header>
    <nav>Navigation</nav>
    <div class="body">
      <aside>Left</aside>
      <main>Main</main>
      <aside>Right</aside>
    </div>
    <footer>Footer</footer>
  </body>
</html>

Upvotes: 1

Related Questions