Search code examples
htmlcssflexboxcss-grid

Elements within flex container are "formatting" according to css grid layout


I might be having trouble understanding how CSS grids and flex work together. I have a top nav bar that spans across the screen, a main content area, sidebar and footer, which I made using CSS grids.

The top nav bar is displayed as flex, where the div items logo and menu are (flex-direction: column) laid vertically. In mobile view, I wanted to make it so that the div items logo and menu are (flex-direction: column) laid horizontally.

Here's where the problem lies:

HTML:

  <header id = "main-header">
     <div class="container nav-flex">
        <div class="site-logo">
          <div>
            beautiful blog
          </div>
        </div>
        <div class="main-header-nav">
          <div>hello</div>
            <label for="toggle">&#9776;</label>
            <div class="menu-nav">              
            </div>
        </div>
     </div>
  </header>

CSS:

#main-header { 
  grid-area: main-header; 
  text-align: center; 
}

.main-area {
  grid-area: ct-main;
}

.side-area {
  grid-area: ct-side;
}

.footer-area {
  grid-area: ft;
}

.nav-flex {
  background: #eee;
  display: flex; 
  flex-direction: row; 
}

.main-header-nav {
  display: flex;
  flex-direction: row; 
  align-items: center; /*vertically centers items*/
  justify-content: center; /*centers items*/

}

.site-logo { 
  flex: 3; 
  background: #eee; 
}

.main-header-nav { 
  flex: 1;
  background: #ddd; 
}

.container {
  display: grid;
  grid-template-columns: 2fr 1fr;
  grid-template-areas:
    "main-header main-header"
    "ct-main ct-side"
    "ft ft";
  max-width: 960px;
  margin: 0 auto;
}


@media only screen and (max-width:500px) { 
  .nav-flex {
    flex-direction: row; 
   }

}

The reason why I put .container was because the #main-header background is supposed to span the screen while everything in the container is to be 960 pixels.

The Problem: What is happening is that the top nav menu will only lay horizontally, with the logo div and menu div taking up the 2fr and 1fr spacing as laid out in my CSS grid, respectively--instead of the #main-header parent div spanning across, allowing me to lay the flex divs however I want.

When I remove the CSS grid code in .container, it works fine.

I am relatively new to CSS grids and Flexbox, but my understanding of it is that CSS grids are a way to set a layout in a 2d manner, and Flex is to arrange content in a certain way inside its flex container.

What I'm getting (1. maximized screen, 2. mobile screen view): maximized view

mobile screen view

What I'm trying to achieve (3. maximized screen, 4. mobile screen view): maximized view mobile screen view

I apologize if this question is worded confusingly. It's 2am and I can't figure this out. Just in case I'm being really confusing

Thank you so much!


Solution

  • You want your logo and menu to be displayed horizontally in mobile view, but vertically on desktop.

    When using flexbox, you define one direction the items flow no matter what the screen size is. Different results occur, once items start wrapping (flex-wrap) on smaller screens. They wrap, if there is not enough room for them to fit into one row or column.

    In your example, your items fit into the div on all possible screens, so they don't have to wrap. If you want them to wrap on smaller screens, you have to set heights for your items and the container and modify your css like this:

    .nav-flex {
      background: #eee;
      display: flex; 
      flex-direction: column;
      flex-wrap: wrap;
    }
    

    Afterwards, try playing around with the height of your container and your items. Check out this example: https://jsfiddle.net/fte69gd0/ By decreasing the screen height, the child elements align in a row because they don't fit into the container any more. In the example, I'm using vh and px as height measurements, but there are different options for sure.

    Although I would probably not use flexbox at all and have a look at the css media rule.