cssflexbox

CSS Flexbox with a component returning TopBar and SideBar and another one returning main content


I am having troubles getting my main content next to the sidebar in a flexbox layout. My TopBar and SideBar components are combined into a single component, so they are returned in a single parent div. Is there a solution using CSS flexbox or do I have to use grid?

This is basically how it is returned:

<div style="display: flex; flex-wrap: wrap;">
  <div id="ParentNav">
    <div style="width: 100%; height: 48px; background-color: blue;">TopBar</div>
    <div style="width: 256px; min-height: calc(100vh - 48px); background-color: grey;">SideBar</div>
  </div>
  <div style="flex-grow: 1; background-color: gold;">Main content</div>
</div>

This is what I would like to achieve visually, but I cannot return the TopBar and SideBar seperately.

<div style="display: flex; flex-wrap: wrap;">
  <div style="width: 100%; height: 48px; background-color: blue;">TopBar</div>
  <div style="width: 256px; min-height: calc(100vh - 48px); background-color: grey;">SideBar</div>
  <div style="flex-grow: 1; background-color: gold;">Main content</div>
</div>


Solution

  • If you can't modify html...

    I think it's possible to set the position of the topbar to absolute and match it by giving margin as high as the topbar at the top of the navbar, main content.

    As long as the style can be applied freely.

    Method 1

    position absolute, and margin

    .wrapper {
      position: relative;
    }
    
    .top-bar {
      position: absolute;
    }
    
    .side-bar {
      margin-top: 48px;
    }
    
    .main-content {
      margin-top: 48px;
    }
    <div class="wrapper" style="display: flex; flex-wrap: wrap;">
      <div id="ParentNav">
        <div class="top-bar" style="width: 100%; height: 48px; background-color: blue;">TopBar</div>
        <div class="side-bar" style="width: 256px; min-height: calc(100vh - 48px); background-color: grey;">SideBar</div>
      </div>
      <div class="main-content" style="flex-grow: 1; background-color: gold;">Main content</div>
    </div>

    Method2

    use grid set the properties as contents so that ParentNav's children can be handled in the grid.

    #ParentNav

    .wrapper {
      display: grid;
      grid-template-columns: 256px 1fr;
      grid-template-rows: 48px 1fr;
      height: 100vh;
    }
    
    .wrapper>#ParentNav {
      display: contents;
    }
    
    .wrapper>#ParentNav>.top-bar {
      grid-column-start: 1;
      grid-column-end: -1;
      grid-row: 1;
    }
    
    .wrapper>#ParentNav>.side-bar {
      grid-column: 1;
      grid-row: 2;
    }
    
    .wrapper>.main-content {
      grid-column: 2;
      grid-row: 2;
    }
    <div class="wrapper">
      <div id="ParentNav">
        <div class="top-bar" style="width: 100%; height: 48px; background-color: blue;">TopBar</div>
        <div class="side-bar" style="width: 256px; min-height: calc(100vh - 48px); background-color: grey;">SideBar</div>
      </div>
      <div class="main-content" style="flex-grow: 1; background-color: gold;">Main content</div>
    </div>