0

I am a backend programmer by profession. But I have just started to learn flexbox and I want to hit the sky with flexbox.

So, I created a simplest design but which looks most complicated to me when creating it using flexbox.

Here is the design:

enter image description here

Guys, I am not able to figure out, how to use flexbox in such a case as there is no row or column. I don't know but is there anything like rowspan or colspan in flexbox that I can use to arrange these divs as shown in image above?

Here is my code:

HTML:

<div class="wrapper">
  <div class="div-wrapper1">
    <div class="inner-wrapper1">
      <div class="div1"></div>
      <div class="fake1"></div>
    </div>
    <div class="div2"></div>
  </div>  
  <div class="div-wrapper2">
    <div class="div3"></div>
    <div class="inner-wrapper2">
      <div class="fake2"></div>
      <div class="div4"></div>
    </div>
  </div>
  <div class="div-center"></div>
</div>

CSS:

.wrapper {
  height: 200px;
  width: 200px;
  border: 1px solid black;
  display: flex;
  flex-direction: column;
}

.div-wrapper1 {
  display: flex;
  flex: 1;
}

.div-wrapper2 {
  display: flex;
  flex: 1
}

.inner-wrapper1 {
  display: flex;
  flex: 3;
  flex-direction: column; 
}

.div1 {
  background-color: red;
  display: flex;
  flex: 3
}

.fake1 { 
  display: flex;
  flex: 1
}

.div2 {
  background-color: green;
  display: flex;
  flex: 2
}

.div3 {
  background-color: blue;
  display: flex;
  flex: 2
}

.inner-wrapper2 {
  display: flex;
  flex: 3;
  flex-direction: column; 
}

.div4 {
  background-color: yellow;
  display: flex;
  flex: 3
}

.fake2 { 
  display: flex;
  flex: 1
}

.div-center {
  background-color: black;
}

This is my output:

enter image description here

Here is the codepen

Vishal
  • 6,238
  • 10
  • 82
  • 158
  • @DavidThomas i don't want to use css grids. Because I am learning react-native and I want to apply it there where flexbox is supported. – Vishal Dec 20 '17 at 19:43
  • 1
    Flexbox is not designed for this type of layout (where rows and columns can overlap). You would need Grid. https://stackoverflow.com/q/44377343/3597276 – Michael Benjamin Dec 20 '17 at 20:25
  • Will it be okay if the html is restructured? –  Dec 20 '17 at 20:25
  • @Highdef yes thats totally fine but only use css flexbox not grids – Vishal Dec 20 '17 at 20:28
  • So it's not even that you're restricted from using grids for whatever reason, but simply because you're convinced flexbox is the one-size-fits-all solution and you simply refuse to use grids for something they were made to do? – BoltClock Dec 21 '17 at 04:05
  • @BoltClock Grids are easy to work with, then why should I refuse to use grids? But I am using react-native, where I cannot use css grids as it does not support css grids, so I have to rely on flexbox. – Vishal Dec 21 '17 at 05:16

1 Answers1

4

Maybe a solution is to simply add a negative margin to .div-wrapper1 and you will get the exact layout :

.wrapper {
  height: 200px;
  width: 200px;
  border: 1px solid black;
  display: flex;
  flex-direction: column;
}

.div-wrapper1 {
  display: flex;
  flex: 1;
}

.div-wrapper2 {
  display: flex;
  flex: 1;
  margin-top: -30px;
}

.div-wrapper3 {
  display: flex;
  flex: 1
}

.inner-wrapper1 {
  display: flex;
  flex: 3;
  flex-direction: column; 
}

.div1 {
  background-color: red;
  display: flex;
  flex: 3
}

.fake1 { 
  display: flex;
  flex: 1
}

.div2 {
  background-color: green;
  display: flex;
  flex: 2
}

.div3 {
  background-color: blue;
  display: flex;
  flex: 2
}

.inner-wrapper2 {
  display: flex;
  flex: 3;
  flex-direction: column; 
}

.div4 {
  background-color: yellow;
  display: flex;
  flex: 3
}

.fake2 { 
  display: flex;
  flex: 1
}

.div-center {
  background-color: black;
}
<div class="wrapper">
  <div class="div-wrapper1">
    <div class="inner-wrapper1">
      <div class="div1"></div>
      <div class="fake1"></div>
    </div>
    <div class="div2"></div>
  </div>  
  <div class="div-wrapper2">
    <div class="div3"></div>
    <div class="inner-wrapper2">
      <div class="fake2"></div>
      <div class="div4"></div>
    </div>
  </div>
  <div class="div-center"></div>
</div>

And if you want here is another solution without any negative values and a content inside the white part (simply adjust height/width as you need) :

.first,
.second {
  display: flex;
  height: 100px;
  width: 200px;
}

.first:before {
  content: "";
  background: red;
  flex: 3;
}

.first:after {
  content: "";
  background: green;
  flex: 2;
}

.second:before {
  content: "";
  background: blue;
  flex: 2;
}

.second:after {
  content: "";
  background: yellow;
  flex: 3;
}

.fake {
  display: flex;
  height: 20px;
  width: 200px;
}

.fake a {
  flex: 1;
  text-align: center;
}

.fake:before {
  content: "";
  background: blue;
  flex: 2;
}

.fake:after {
  content: "";
  background: green;
  flex: 2;
}
<div class="first">
</div>
<div class="fake">
  <a href="">link</a>
</div>
<div class="second">
</div>

Here is another solution by simply using multiple linear-gradient:

.box {
  display: flex;
  height: 220px;
  width: 200px;
  justify-content: center;
  align-items: center;
  background-image:linear-gradient(to right,red 66%,green 0%),
                   linear-gradient(to right,blue 33%,white 0%,white 66%,green 66%),
                   linear-gradient(to right,blue 33%,yellow 0%);
  
  background-size:100% 100px,100% 20px,100% 100px;
  background-position:top,center,bottom;
  background-repeat:no-repeat;
}
<div class="box">
  <a href="#">link</a>
</div>
Temani Afif
  • 245,468
  • 26
  • 309
  • 415
  • That's a good one. And what if I want to have a button in white area of the final output? – Vishal Dec 20 '17 at 20:32
  • @Vishal check my updated, i added anothe solution :) and i will add a button in this part ;) – Temani Afif Dec 20 '17 at 20:33
  • @Vishal check again, it's more simplified now :) less HTML code – Temani Afif Dec 20 '17 at 20:37
  • Thanks again. As I am using react-native, I can't use your second solution because I don't think that I can use order and pseudo selectors there. But negative margin is also a good one for me. – Vishal Dec 20 '17 at 20:40
  • @Vishal i removed order, they are useless at the end .. but you can replace before/after with simple divs ;) i used them to make the HTML more simple – Temani Afif Dec 20 '17 at 20:41
  • Thanks again. I will try that by replacing before and after with a div. i.e. View in react-native. – Vishal Dec 20 '17 at 20:43
  • @Vishal i added a third one with only a link in the HTML and created the layout using background colors if interested ;) – Temani Afif Dec 20 '17 at 21:23