Search code examples
cssflexboxcss-floatcss-grid

Stacking 3 elements both sides on window resize with CSS using inline, flex, float or whatever


I know there are many questions about this, the most of them says this is not possible because they ask about 1 method only, this question is about any method, I simply can't believe this is not possible with CSS.

I have 3 elements, 2 of them are stacked on the left and the other one is taller and his width fills the remaining space, when the screen goes smaller they stack, so the right element moves between first and last element:

enter image description here

I tried different methods like display:inline-block, float:left (and right), display:flex (and some flex properties) and even tables! I can not achieve it.

These are my 3 best attempts:

.test_inline div{display:inline-block;}
.test_inline .right{flex-grow:1; width: calc(100% - 130px);min-width:100px;}

.test_flex{display:flex;flex-wrap: wrap}
.test_flex .right{flex-grow:1; width: calc(100% - 130px);min-width:100px;}

.test_float .left{float:left;}
.test_float .right{display: flow-root;}

/* */

.main{ margin: 50px; }
div div{ border: 1px solid #333; }
.left{ width: 100px; }
.right{ height: 50px; }
<div class='main test_inline'>
  <div class='left'>1 Top left</div>
  <div class='right'>2 Right</div>
  <div class='left'>3 Bottom Left</div>
</div>
<div class='main test_flex'>
  <div class='left'>1 Top left</div>
  <div class='right'>2 Right</div>
  <div class='left'>3 Bottom Left</div>
</div>
<div class='main test_float'>
  <div class='left'>1 Top left</div>
  <div class='right'>2 Right</div>
  <div class='left'>3 Bottom Left</div>
</div>

Thank you for your help!


Solution

  • I simply can't believe this is not possible with CSS.

    It is possible. In fact, it's fairly simple with CSS Grid.

    No need for floats, inline block, absolute positioning or even flex.

    jsFiddle demo

    .test_grid {
      display: grid;
      grid-template-columns: 150px 1fr;
      grid-template-rows: 50px 50px;
      grid-gap: 5px;
    }
    
    .right {
      grid-row: span 2;
    }
    
    @media ( max-width: 600px) {
      .test_grid {
        grid-template-columns: 1fr;
        grid-template-rows: 50px 50px 50px 50px;
      }
    }
    
    /* */
    
    .main {
      margin: 50px;
    }
    
    div div {
      border: 1px solid #333;
    }
    <div class='main test_grid'>
      <div class='left'>1 Top left</div>
      <div class='right'>2 Right</div>
      <div class='left'>3 Bottom Left</div>
    </div>