Home > front end >  Creating 2x2 flex grid with different widths which stack
Creating 2x2 flex grid with different widths which stack

Time:07-09

I have been wrestling with flex and how to do a simple grid, with different widths, and then to make them stackable in mobile.

-------------------
menu  | A1     | B1
      | A2     | B2
--------------------

But then, when responsive, stacks to:

------------
    A1
------------
    B1
------------
    A2
------------
    B2

(the menu becomes a burger already)

So far I have:

.flex-row {
   display: flex;
   flex: 1;
   flex-direction: row;
   flex-wrap: wrap;
}

.flex-col {
   margin: 6px;
   padding: 0px;
   background-color: black;
   display: flex;
   justify-content: center;
   flex: 1;
   flex-direction: column;
   color: white;
}
<div >
 <div >
    menu here
 </div>
 <div >
   <div >A1</div>
   <div >B1</div>
   <div >A2</div>
   <div >B2</div>
 </div>
</div>

For some reason, I cannot get the width to work even when using something like flex: 0 0 15em;. In desktop, then things don't look good, and all show up as cols. Wondering how to break it so it's 2x2 on desktop (aside from the menu) and stacked in mobile.

CodePudding user response:

Try this solution with flex and css-variables. Firstly, I renamed parent the element of the columns for better usability. Then we create three values for margins, width A and width B. With the:nth-of-type pseudo-class and odd, even arguments we assign the width. The last step, we create a breakpoint (@media) for mobile devices and edit the values A, B.

.container {
  display: flex;
}

.sidebar-menu-col {
  flex: 1 0 auto;
}

.wrapper {
  width: 100%;
  display: flex;
  flex-wrap: wrap;
}

.flex-col {
  --margin: 6px;
  --A: 70%;
  --B: 30%;
  margin: var(--margin);
  padding: 0px;
  background-color: black;
  display: flex;
  justify-content: center;
  flex: 1;
  color: white;
}

.flex-col:nth-of-type(odd) {
  flex: 1 0 calc(var(--A) - var(--margin) * 2);
}

.flex-col:nth-of-type(even) {
  flex: 0 1 calc(var(--B) - var(--margin) * 2);
}

@media screen and (max-width: 560px) {
 .container {
    flex-flow: column;
  }
  .flex-col {
    --A: 100%;
    --B: 100%;
  }
}
<div >
  <div >menu here</div>
  <div >
    <div >A1</div>
    <div >B1</div>
    <div >A2</div>
    <div >B2</div>
  </div>
</div>

CodePudding user response:

you should be using grid instead for this. i have added display grid giving it 2 colums and 2 rows and in media querie for small devices it changes to 1 column and 4 rows..and i dnt understand the class you are targeting in css (.flex-row) as there are no html of that class..? and you shouldnt use same names for parent container and the childrens..

.container {
                display: flex;
                align-items: center;
                flex-wrap: wrap;
            }

            /* .flex-row {
                display: flex;
                flex: 1;
                flex-direction: row;
                flex-wrap: wrap;
            } */
            

            .flex-col-container {
                margin: 6px;
                padding: 0px;
                background-color: black;
                color: white;
                /* display: flex;
                justify-content: center; */
                display: grid;
                
                grid-auto-flow: row;
                grid-template-columns: 15em  5em; /*A1 and a2 is 15em & b1 and b2 is 5em*/
                grid-row: 2em 2em;/*2 rows with height of 2em*/
               

            }

            @media only screen and (max-width: 650px) {
                .flex-col-container {
                    grid-template-columns: 15em;/*1 column with width of 15em*/
                    grid-row: 2em 2em 2em 2em;/*4 rows with height of 2em*/

                }

            }
<div >
        <div >
            menu here
        </div>
        <div >
            <div >A1</div>
            <div >B1</div>
            <div >A2</div>
            <div >B2</div>
        </div>

  • Related