Flexbox or Column CSS for positioning elements like this

怎甘沉沦 提交于 2019-12-25 00:13:52

问题


Is there any solution to avoid the float and to use flexbox and make this type of layout like in my representation? I don't have any example but this picture with what I need.

I'll try to explain in words:

  • This grid starts from 1025px and with 2 columns and the big red square in the right side.
  • From 1100px I need 3 columns and the big red square in the right
  • From 1680px I will have 4 columns and the big red square in the right.

 

  1. The position of the items must be like in my picture
  2. Depending of the aspect ratio, 4 items will go down with the others: 5,6,7,8 will go down with 9, 10, and so on.
  3. The big red must have always the same height with the first two rows.
  4. All the layout is fluid and responsive

I can make this very easy with FLOAT and some JS to calculate the exact same height of the first two rows and make the big red have the same but I want to use flexbox if its possible.

The code I have so far

.grid {
  display: flex;
  flex-direction: row;
}
.item {
  width: 16%;
  margin: 5px;
}
.red-box {
  
}
<div class="grid">
  <div class="red-box">big box</div>
  
  <div class="item">Item 1</div>
  <div class="item">Item 2</div>
  <div class="item">Item 3</div>
  <div class="item">Item 4</div>
  <div class="item">Item 5</div>
  <div class="item">Item 6</div>
  <div class="item">Item 7</div>
  <div class="item">Item 8</div>
  <div class="item">Item 9</div>
  <div class="item">Item 10</div>  
  <div class="item">Item 11</div>
  <div class="item">Item 12</div>
  <div class="item">Item 13</div>
  <div class="item">Item 14</div>
  <div class="item">Item 15</div>
  <div class="item">Item 16</div>
  <div class="item">Item 17</div>
  <div class="item">Item 18</div>
  <div class="item">Item 19</div>
  <div class="item">Item 20</div>
</div>

回答1:


If you combine Flexbox with absolute position, you can accomplish that.

What I did was to make use of the order property to position the red element in the upper right corner. With this one can then control its position using media queries.

To force a wrap on the end of the 2nd row, I used a pseudo element with the same size as the right_corner element, and use the order property to position it.

To center the red element I use an absolute positioned wrapper and Flexbox, that will take twice its height, and by that cover 2 rows.

Stack snippet

.container {
  display: flex;
  flex-wrap: wrap;
  counter-reset: num;
}

.container .right_corner > div {
  position: absolute;
  left: 0;
  top: 0;
  width: 100%;
  height: calc(200% + 10px);
  display: flex;
  justify-content: center;
  align-items: center;
}

.container .right_corner > div > div {
  width: 300px;
  min-width: 300px;
  height: 250px;
  background: red;
}

.container::before,
.container > div {
  height: 150px;
  margin: 5px;
}

.container > div:not(:first-child) {
  background: lightgray;
}

.container .right_corner {
  position: relative;
  order: 1;
}

.container::before {
  content: '';
  order: 3;
}

.container > div:nth-child(n+2)::before {
  counter-increment: num;
  content: counter(num);
}

@media (max-width: 800px){
  .container > div:nth-child(n+4) {
    order: 2;
  }
  .container > div:nth-child(n+6) {
    order: 4;
  }
  .container > div:not(:first-child) {
    width: calc((100% / 4) - 10px);
  }
  .container .right_corner {
    width: calc((100% / 2) - 10px);
  }
  .container::before {
    width: calc((100% / 2) - 10px);
  } 
}

@media (min-width: 801px) and (max-width: 1000px){
  .container > div:nth-child(n+5) {
    order: 2;
  }
  .container > div:nth-child(n+8) {
    order: 4;
  }
  .container > div:not(:first-child) {
    width: calc((100% / 5) - 10px);
  }
  .container .right_corner {
    width: calc((100% / 2.5) - 10px);
  }
  .container::before {
    width: calc((100% / 2.5) - 10px);
  } 
}

@media (min-width: 1000px) {
  .container > div:nth-child(n+6) {
    order: 2;
  }
  .container > div:nth-child(n+10) {
    order: 4;
  }
  .container > div:not(:first-child) {
    width: calc((100% / 6) - 10px);
  }
  .container .right_corner {
    width: calc((100% / 3) - 10px);
  }
  .container::before {
    width: calc((100% / 3) - 10px);
  }
}
<div class='container'>

  <div class='right_corner'>
    <div>
      <div></div>
    </div>
  </div>

  <div></div>
  <div></div>
  <div></div>
  <div></div>
  
  <div></div>
  <div></div>
  <div></div>
  <div></div>

  <div></div>
  <div></div>
  <div></div>
  <div></div>

  <div></div>
  <div></div>
  <div></div>
  <div></div>

  <div></div>
  <div></div>
  <div></div>
  <div></div>

</div>



回答2:


My attempt on jsfiddle.net. It is without absolute positioning and pseudo elements.

And the same code here in the below snippet:

body {
  background-color: black;  
}

.grid {
  display: flex;
  flex-flow: row wrap;
}

.grid > div {
  display: flex;
  justify-content: center;
  align-items: center;
}

.item {
  width: calc(33.33% - 10px);
  margin: 5px;
  height: 60px;
  background-color: gainsboro;  
}

.red-box {
  box-sizing: border-box;
  width: calc(33.33% - 60px);
  margin: 30px 30px;
  height: 80px;
  margin-bottom: -70px; 
  order: 2!important;
  background-color: red;
  border: 2px solid gainsboro;      
}

.red-box > div {
  background-color: red;
  height: 60%;
  width: 60%;
  border: 2px solid gainsboro; 
}    

@media (max-width: 499px) {
  .grid > div:nth-child(-n+3) {
    order: 1;
  }
  .grid > div:nth-child(n+4) {
    order: 3;
  }      
  .grid>div:nth-child(5) {
    margin-right: calc(33.33% + 5px);
  }
}

@media (min-width: 500px) and (max-width: 999px) {
  .grid > div:nth-child(-n+4) {
    order: 1;
  }
  .grid > div:nth-child(n+5) {
    order: 3;
  } 
  
  .item {
    width: calc(25% - 10px);
   }
   .red-box {
    width: calc(25% - 60px);
   }
   .grid>div:nth-child(7) {
     margin-right: calc(25% + 5px);
   }
}

@media (min-width: 1000px) {
  .grid > div:nth-child(-n+5) {
    order: 1;
  }
  .grid > div:nth-child(n+6) {
    order: 3;
  } 
  
  .item {
    width: calc(20% - 10px);
   }
   .red-box {
    width: calc(20% - 60px);
   }
   .grid>div:nth-child(9) {
     margin-right: calc(20% + 5px);
   }
}
<div class="grid">
  <div class="red-box"></div>

  <div class="item">Item 1</div>
  <div class="item">Item 2</div>
  <div class="item">Item 3</div>
  <div class="item">Item 4</div>
  <div class="item">Item 5</div>
  <div class="item">Item 6</div>
  <div class="item">Item 7</div>
  <div class="item">Item 8</div>
  <div class="item">Item 9</div>
  <div class="item">Item 10</div>  
  <div class="item">Item 11</div>
  <div class="item">Item 12</div>
  <div class="item">Item 13</div>
  <div class="item">Item 14</div>
  <div class="item">Item 15</div>
  <div class="item">Item 16</div>
  <div class="item">Item 17</div>
  <div class="item">Item 18</div>
  <div class="item">Item 19</div>
  <div class="item">Item 20</div>
</div>


来源:https://stackoverflow.com/questions/48444823/flexbox-or-column-css-for-positioning-elements-like-this

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!