htmlcssflexbox

Flex ordering issue: is it possible to change the flow order?


This is my attempt to create a CSS template with the following features:

Here my code:

:root {
  --color-text: #521D03;
  --color-menu-background: #33dd00;
  --color-content-background: #FFFFFF;
  --color-lines: #521D03;
}

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

body {
  margin: 0;
}

.container {
  display: flex;
  flex-direction: column;
}

.button {
  display: block;
  font-weight: bold;
  font-size: 32px;
  line-height: 0.9em;
  text-decoration: none;
  letter-spacing: 0.02em;
  color: var(--color-text);
}

.box {
  padding: 1em;
  box-sizing: border-box;
  display: flex;
  flex-flow: column;
  color: var(--color-text);
}

.box-menu {
  background-color: var(--color-menu-background);
  text-align: center;
  justify-content: space-around;
}

.box-data {
  background-color: var(--color-content-background);
  background-color: #aaaaaa;
  flex: 1;
}

.box-footer {
  background-color: var(--color-menu-background);
  line-height: 1em;
  text-align: center;
}

.box-menu .menu-header {
  display: flex;
  flex-direction: column;
  justify-content: center;
}

.box-data .data-header {
  flex: 0 0 auto;
  display: flex;
  flex-direction: column;
  justify-content: center;
}

.box-data .data-content {
  flex: 1 1 auto;
  display: flex;
  flex-direction: column;
  justify-content: center;
}

.box-data .data-footer {
  flex: 0 1 150px;
  text-align: center;
}

/* Larger viewports */
@media (min-width: 1200px) {
  .container {
    flex-direction: row;
    flex-wrap: wrap;
  }

  .box-menu,
  .box-data,
  .box-footer {
    flex-basis: 50%;
  }

  .box-menu {
    height: calc(100% - 150px);
  }

  .box-footer {
    height: 150px;
  }

  .box-data {
    height: 100%;
    overflow-y: auto;
  }
}
<div class="container">
  <div class="box box-menu">

    <div class="menu-header">
      <h1>MY LOGO</h1>
    </div>

    <div class="menu-content">
      <a class="button" href="/">MENU 1</a>
      <a class="button" href="/">MENU 2</a>
      <a class="button" href="/">MENU 3</a>
    </div>

  </div>
  <div class="box box-data">

    <div class="data-header">
      <div class="nav-section">
        <h3>MY NAV</h3>
      </div>
    </div>

    <div class="data-content">
      MY LONG CONTENT

      <p>
        Lorem ipsum dolor sit amet consectetur adipiscing elit. Quisque faucibus ex sapien vitae pellentesque sem placerat. In id cursus mi pretium tellus duis convallis. Tempus leo eu aenean sed diam urna tempor. Pulvinar vivamus fringilla lacus nec metus bibendum egestas. Iaculis massa nisl malesuada lacinia integer nunc posuere. Ut hendrerit semper vel class aptent taciti sociosqu. Ad litora torquent per conubia nostra inceptos himenaeos.
      </p>
      <p>
        Lorem ipsum dolor sit amet consectetur adipiscing elit. Quisque faucibus ex sapien vitae pellentesque sem placerat. In id cursus mi pretium tellus duis convallis. Tempus leo eu aenean sed diam urna tempor. Pulvinar vivamus fringilla lacus nec metus bibendum egestas. Iaculis massa nisl malesuada lacinia integer nunc posuere. Ut hendrerit semper vel class aptent taciti sociosqu. Ad litora torquent per conubia nostra inceptos himenaeos.
      </p>
      <p>
        Lorem ipsum dolor sit amet consectetur adipiscing elit. Quisque faucibus ex sapien vitae pellentesque sem placerat. In id cursus mi pretium tellus duis convallis. Tempus leo eu aenean sed diam urna tempor. Pulvinar vivamus fringilla lacus nec metus bibendum egestas. Iaculis massa nisl malesuada lacinia integer nunc posuere. Ut hendrerit semper vel class aptent taciti sociosqu. Ad litora torquent per conubia nostra inceptos himenaeos.
      </p>
      <p>
        Lorem ipsum dolor sit amet consectetur adipiscing elit. Quisque faucibus ex sapien vitae pellentesque sem placerat. In id cursus mi pretium tellus duis convallis. Tempus leo eu aenean sed diam urna tempor. Pulvinar vivamus fringilla lacus nec metus bibendum egestas. Iaculis massa nisl malesuada lacinia integer nunc posuere. Ut hendrerit semper vel class aptent taciti sociosqu. Ad litora torquent per conubia nostra inceptos himenaeos.
      </p>
      <p>
        Lorem ipsum dolor sit amet consectetur adipiscing elit. Quisque faucibus ex sapien vitae pellentesque sem placerat. In id cursus mi pretium tellus duis convallis. Tempus leo eu aenean sed diam urna tempor. Pulvinar vivamus fringilla lacus nec metus bibendum egestas. Iaculis massa nisl malesuada lacinia integer nunc posuere. Ut hendrerit semper vel class aptent taciti sociosqu. Ad litora torquent per conubia nostra inceptos himenaeos.
      </p>
      <p>
        Lorem ipsum dolor sit amet consectetur adipiscing elit. Quisque faucibus ex sapien vitae pellentesque sem placerat. In id cursus mi pretium tellus duis convallis. Tempus leo eu aenean sed diam urna tempor. Pulvinar vivamus fringilla lacus nec metus bibendum egestas. Iaculis massa nisl malesuada lacinia integer nunc posuere. Ut hendrerit semper vel class aptent taciti sociosqu. Ad litora torquent per conubia nostra inceptos himenaeos.
      </p>
      <p>
        Lorem ipsum dolor sit amet consectetur adipiscing elit. Quisque faucibus ex sapien vitae pellentesque sem placerat. In id cursus mi pretium tellus duis convallis. Tempus leo eu aenean sed diam urna tempor. Pulvinar vivamus fringilla lacus nec metus bibendum egestas. Iaculis massa nisl malesuada lacinia integer nunc posuere. Ut hendrerit semper vel class aptent taciti sociosqu. Ad litora torquent per conubia nostra inceptos himenaeos.
      </p>
      <p>
        Lorem ipsum dolor sit amet consectetur adipiscing elit. Quisque faucibus ex sapien vitae pellentesque sem placerat. In id cursus mi pretium tellus duis convallis. Tempus leo eu aenean sed diam urna tempor. Pulvinar vivamus fringilla lacus nec metus bibendum egestas. Iaculis massa nisl malesuada lacinia integer nunc posuere. Ut hendrerit semper vel class aptent taciti sociosqu. Ad litora torquent per conubia nostra inceptos himenaeos.
      </p>
    </div>

    <div class="data-footer">
      <div class="menu-content">
        <a class="button clear">MY BUTTON</a>
      </div>
    </div>

  </div>

  <div class="box box-footer">
    MY FOOTER
  </div>

</div>

The smaller viewport code is working fine. When it switches to the two columns layout the box-footer is placed (as expected) after the box-data causing a gap:

gap

I tried to fix with the order property, but it changes the order of the items, not the order of the flow.

As far as I understand, flex will count 1. upper left, 2. upper right, 3. lower left, etc... Instead, to match my needs it should be 1 upper left (menu), 2 lower left (footer) and 3 upper right (data).

How to place the box-footer just below the box-menu without any gap?


Solution

  • For this kind of layout, using grid layout instead of flex is more appropriate. You can define the grid-template you want depending on the screen size:

    .container {
      display: grid;
      grid-template:
        "menu"
        "data"
        "footer";
    }
    
    @media (min-width: 1200px) {
      .container {
        grid-template:
          "menu data"
          "footer data";
        grid-template-columns: 1fr 1fr;
      }
    }
    

    And then assign each grid-area:

    .box-menu {
      grid-area: menu;
    }
    
    .box-data {
      grid-area: data;
    }
    
    .box-footer {
      grid-area: footer;
    }
    

    Here is the updated snippet:

    :root {
      --color-text: #521D03;
      --color-menu-background: #33dd00;
      --color-content-background: #FFFFFF;
      --color-lines: #521D03;
    }
    
    html,
    body,
    .container {
      height: 100%;
    }
    
    body {
      margin: 0;
    }
    
    .container {
      display: grid;
      grid-template:
        "menu"
        "data"
        "footer";
    }
    
    .button {
      display: block;
      font-weight: bold;
      font-size: 32px;
      line-height: 0.9em;
      text-decoration: none;
      letter-spacing: 0.02em;
      color: var(--color-text);
    }
    
    .box {
      padding: 1em;
      box-sizing: border-box;
      color: var(--color-text);
    }
    
    .box-menu {
      background-color: var(--color-menu-background);
      text-align: center;
      grid-area: menu;
    }
    
    .box-data {
      background-color: var(--color-content-background);
      grid-area: data;
      background-color: #aaaaaa;
    }
    
    .box-footer {
      background-color: var(--color-menu-background);
      line-height: 1em;
      text-align: center;
      grid-area: footer;
      height: max-content;
    }
    
    .box-data .data-footer {
      text-align: center;
    }
    
    /* Larger viewports */
    @media (min-width: 1200px) {
      .container {
        grid-template:
          "menu data"
          "footer data";
        grid-template-columns: 1fr 1fr;
      }
    
      .box-data {
        overflow-y: auto;
      }
    }
    <div class="container">
      <div class="box box-menu">
    
        <div class="menu-header">
          <h1>MY LOGO</h1>
        </div>
    
        <div class="menu-content">
          <a class="button" href="/">MENU 1</a>
          <a class="button" href="/">MENU 2</a>
          <a class="button" href="/">MENU 3</a>
        </div>
    
      </div>
      <div class="box box-data">
    
        <div class="data-header">
          <div class="nav-section">
            <h3>MY NAV</h3>
          </div>
        </div>
    
        <div class="data-content">
          MY LONG CONTENT
    
          <p>
            Lorem ipsum dolor sit amet consectetur adipiscing elit. Quisque faucibus ex sapien vitae pellentesque sem placerat. In id cursus mi pretium tellus duis convallis. Tempus leo eu aenean sed diam urna tempor. Pulvinar vivamus fringilla lacus nec metus bibendum egestas. Iaculis massa nisl malesuada lacinia integer nunc posuere. Ut hendrerit semper vel class aptent taciti sociosqu. Ad litora torquent per conubia nostra inceptos himenaeos.
          </p>
          <p>
            Lorem ipsum dolor sit amet consectetur adipiscing elit. Quisque faucibus ex sapien vitae pellentesque sem placerat. In id cursus mi pretium tellus duis convallis. Tempus leo eu aenean sed diam urna tempor. Pulvinar vivamus fringilla lacus nec metus bibendum egestas. Iaculis massa nisl malesuada lacinia integer nunc posuere. Ut hendrerit semper vel class aptent taciti sociosqu. Ad litora torquent per conubia nostra inceptos himenaeos.
          </p>
          <p>
            Lorem ipsum dolor sit amet consectetur adipiscing elit. Quisque faucibus ex sapien vitae pellentesque sem placerat. In id cursus mi pretium tellus duis convallis. Tempus leo eu aenean sed diam urna tempor. Pulvinar vivamus fringilla lacus nec metus bibendum egestas. Iaculis massa nisl malesuada lacinia integer nunc posuere. Ut hendrerit semper vel class aptent taciti sociosqu. Ad litora torquent per conubia nostra inceptos himenaeos.
          </p>
          <p>
            Lorem ipsum dolor sit amet consectetur adipiscing elit. Quisque faucibus ex sapien vitae pellentesque sem placerat. In id cursus mi pretium tellus duis convallis. Tempus leo eu aenean sed diam urna tempor. Pulvinar vivamus fringilla lacus nec metus bibendum egestas. Iaculis massa nisl malesuada lacinia integer nunc posuere. Ut hendrerit semper vel class aptent taciti sociosqu. Ad litora torquent per conubia nostra inceptos himenaeos.
          </p>
          <p>
            Lorem ipsum dolor sit amet consectetur adipiscing elit. Quisque faucibus ex sapien vitae pellentesque sem placerat. In id cursus mi pretium tellus duis convallis. Tempus leo eu aenean sed diam urna tempor. Pulvinar vivamus fringilla lacus nec metus bibendum egestas. Iaculis massa nisl malesuada lacinia integer nunc posuere. Ut hendrerit semper vel class aptent taciti sociosqu. Ad litora torquent per conubia nostra inceptos himenaeos.
          </p>
          <p>
            Lorem ipsum dolor sit amet consectetur adipiscing elit. Quisque faucibus ex sapien vitae pellentesque sem placerat. In id cursus mi pretium tellus duis convallis. Tempus leo eu aenean sed diam urna tempor. Pulvinar vivamus fringilla lacus nec metus bibendum egestas. Iaculis massa nisl malesuada lacinia integer nunc posuere. Ut hendrerit semper vel class aptent taciti sociosqu. Ad litora torquent per conubia nostra inceptos himenaeos.
          </p>
          <p>
            Lorem ipsum dolor sit amet consectetur adipiscing elit. Quisque faucibus ex sapien vitae pellentesque sem placerat. In id cursus mi pretium tellus duis convallis. Tempus leo eu aenean sed diam urna tempor. Pulvinar vivamus fringilla lacus nec metus bibendum egestas. Iaculis massa nisl malesuada lacinia integer nunc posuere. Ut hendrerit semper vel class aptent taciti sociosqu. Ad litora torquent per conubia nostra inceptos himenaeos.
          </p>
          <p>
            Lorem ipsum dolor sit amet consectetur adipiscing elit. Quisque faucibus ex sapien vitae pellentesque sem placerat. In id cursus mi pretium tellus duis convallis. Tempus leo eu aenean sed diam urna tempor. Pulvinar vivamus fringilla lacus nec metus bibendum egestas. Iaculis massa nisl malesuada lacinia integer nunc posuere. Ut hendrerit semper vel class aptent taciti sociosqu. Ad litora torquent per conubia nostra inceptos himenaeos.
          </p>
        </div>
    
        <div class="data-footer">
          <div class="menu-content">
            <a class="button clear">MY BUTTON</a>
          </div>
        </div>
    
      </div>
    
      <div class="box box-footer">
        MY FOOTER
      </div>
    
    </div>