EvgenyK
EvgenyK

Reputation: 65

complex flex box. childs to flex-end, but first flex-start vertically

I'm pulling my hair at the moment and need some help.

I have complex flex box issue. I can edit CSS only, and can't update HTML.

Example on CodePen: https://codepen.io/anon/pen/RqYMZJ

This is the closest I could get, but there's still some space between child-6 and child-4 and child-5 :(

.main-parent {
    border:1px solid #000;
    display:flex;
}
.child-1 {
    background-color:red;
    width:50%;
    height:200px;
}
.parent {
    flex:1 1 auto;
    display:flex;  
    flex-wrap:wrap;
    flex-direction:row;
    align-items:flex-end;  
}
.child-3 {
    background-color:blue;  
    width:100%;
    align-self:flex-start;
}
.child-4 {
    background-color:green;
    height:40px;  
    margin: 0 0 0 0;
}
.child-5 {
    background-color:yellow;
    height:40px; 
    flex: 0;  
}

.child-6 {
    width:100%;
    background-color:lightblue;
    margin: 0 0 0 0;
}

I need to flex child to go as follows:

enter image description here

Upvotes: 0

Views: 119

Answers (1)

nemanja
nemanja

Reputation: 694

Here's one 'out of the box' solution. Please note, I am using your code as starter and your visual cue as final guide. This is far from good code or best practices, but it is a 'hack' to get you what you wanted. It's 'fragile' and the structure could break with any new factor introduced or any major change. That's why hacks should be avoided. For every new problem, you need another patch/hack (until there are no options left) :) With that being said, here's the code.

.main-parent {
  position: relative;
  border: 1px solid #000;
  display: flex;
}

.child-1 {
  background-color: red;
  min-width: 50%;
  min-height: 200px;
}

.parent {
  flex: 1 1 auto;
  display: flex;
  flex-wrap: wrap;
  flex-direction: row;
  align-items: flex-end;
}

.child-3 {
  background-color: blue;
  width: 100%;
  align-self: flex-start;
}

.child-4 {
  background-color: green;
  height: 40px;
  display: inline-block;
  width: auto;
  max-width: 50%;
}
.child-5 {
  background-color: yellow;
  height: 40px;
  display: inline-block;
  width: auto;
  max-width: 50%;
}

.child-6 {
  width: 50%;
  background-color: lightblue;
  position: absolute;
  bottom: 40px;
}
<div class="main-parent">
  <div class="child-1">1</div>
  <div class="parent">
    <div class="child-3">3<br><br>1<br><br>1</div>
    <div class="child-6">6 line</div>
    <div class="child-4">4</div>
    <div class="child-5">5</div>
  </div>
</div>

  • I have basically used your codepen and simply removed child-6 from the flow, by setting its position to absolute. Main parent now has position relative so it can serve as a reference.
  • Because you have hard-coded height of child-4 and child-5 to 40px, I have simply set the bottom value of child-6to that amount (40px).
  • Also, note that width of child-6is now 50%, because it is relative to the main parent.

I hope this solves your current problem, but please beware of similar approaches. They can easily 'bite you' when you least want/expect it.

P.S. One additional safety measure if you plan to change the height of children 4 and 5. I would use css variable for that and use it also for child-6 bottom value. For example:

:root {
  --your-variable-name: 40px;
}

.child-4,
.child-5 {
  height: var(--your-variable-name);
}

.child-6 {
  bottom: var(--your-variable-name);
}

Later if you decide to change 40px to (let's say) 60px, you need to do it only in one place, and it will automatically update everywhere and keep your elements the way you wanted them in the first place (6 directly on top of 4 and 5).

Upvotes: 1

Related Questions