2

I'm trying to float two elements at the right of a "figure" element using flex but it end up floating just div1 at the right of figure and div2 is moved bellow, if I make div1 and div2 narrow enough, they are floated inline at the right of figure.

This is the CSS:

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

Desired Result: How should it look:

Actual Result:

How does it looks:

Michael Benjamin
  • 346,931
  • 104
  • 581
  • 701
Flupkear
  • 2,135
  • 7
  • 29
  • 32
  • 1
    There are several ways to solve this, but they depend on how flexible you are with the html. @highdef's answer is the best if you can add a div to wrap the two divs. If you can't you should post the exact html you are dealing with and the constraints you're operating under. – vlasits Dec 13 '17 at 19:57
  • I'm altering the HTML to go with @highdef solution, I think it's the best one. – Flupkear Dec 13 '17 at 20:10

4 Answers4

3

How it works?

First, you make a flex-container (flexc in this case) and apply the display:flex property on it which aligns the elements by default in row alignment. If you want an element to preserve its dimensions set it to flex:0 0 auto; else you can make use of flex:1; which shrinks or grows as the browser is resized.

Then to align the contents in column (div1 and div2) you can just wrap then in a different container and since div isn't an inline container, and the flex property doesn't have any effect on any other than the direct children of the flex parent, they are aligned in seperate lines.

.flexc {
  display: flex;
  justify-content: flex-start;
}

#fig {
  flex: 0 0 auto;
  width: 200px;
  height: 200px;
  background: gray;
  text-align: center;
  color: white;
  margin: 10px;
  border: 2px solid black;
}

#d1,
#d2 {
  width: 200px;
  height: 50px;
  background: purple;
  text-align: center;
  color: white;
  margin: 10px;
  border: 2px solid black;
}
<div class="flexc">
  <div id="fig">Figure</div>
  <div class="col">
    <div id="d1">div1</div>
    <div id="d2">div2</div>
  </div>
</div>

Without altering the html:

.flexc {
  display: flex;
  flex-direction:column;
  position:relative;
}

#fig {
  flex: 0 0 auto;
  width: 200px;
  height: 200px;
  background: gray;
  text-align: center;
  color: white;
  margin: 10px;
  border: 2px solid black;
}

#d1,
#d2 {
  position:absolute;
  left:250px;
  width: 200px;
  height: 50px;
  background: purple;
  text-align: center;
  color: white;
  margin: 10px;
  border: 2px solid black;
}
#d2{
top:70px;
}
<div class="flexc">
  <div id="fig">Figure</div>
    <div id="d1">div1</div>
    <div id="d2">div2</div>
</div>
  • This is a good answer if you can alter the html. – vlasits Dec 13 '17 at 19:52
  • I was hoping on not having to alter the HTML structure, there isn't a way to float the elements in columns? maybe using flex-direction: column – Flupkear Dec 13 '17 at 19:55
  • You can't make use of flex-direction column in the same parent container without an additional intermediate container like I did but if you want it without altering the html, let me see. –  Dec 13 '17 at 19:57
  • You can get that effect by using floats. That's exactly how they work when your container has a width doesn't accommodate the width of all three divs. – vlasits Dec 13 '17 at 19:59
  • @Flupkear Added another solution. You can make use of relative and absolute position like I have and use flex-direction:column on the main container. –  Dec 13 '17 at 20:01
  • @vlasits float property is ignored inside a flexbox. –  Dec 13 '17 at 20:02
  • True... so my recommendation is don't use flexbox. I can't think of a situation where you'd be locked into it. But OP hasn't fully specified all of the constraints of the situation so it's hard to guess. – vlasits Dec 13 '17 at 20:05
  • 1
    @vlasits Yeah, i know. Well all solutions are there now, they can select according to their preference. –  Dec 13 '17 at 20:05
  • Thanks for the suggestions, I'll go with your original solution, adding a container for the right side elements. – Flupkear Dec 13 '17 at 20:07
  • @Flupkear No problem :) –  Dec 13 '17 at 20:07
  • You prolly ought to re-edit to reflect your original answer... for posterity. – vlasits Dec 13 '17 at 20:08
  • 1
    @vlasits I have both the solutions here. –  Dec 13 '17 at 20:08
1

Not sure what your HTML looks like, but display: flex is best used on the container wrapping all the elements you want aligned. Imagine it to be the largest box that you put smaller boxes inside.

flexbox example

Codepen example demonstrating this: https://codepen.io/corviday/pen/VyYdar

Following this hierarchy with .container as your largest box, since you want two columns, you can divide it further into two smaller boxes (.left in red and .right in blue in this case).

From there you would need to group div1/div2 together to float the way you'd like, and would be the items that fill the box .right.

corv
  • 31
  • 5
  • 1
    This is a good solution if you can alter the original html. OP explained in a comment that they didn't want to do that, though. – vlasits Dec 13 '17 at 20:07
0

You can use Bootstrap to resolve or put div1 and div2 in one div main to drop div main

Bootstrap exemple

<div class='container'>
  <div class="col-md-12">
    <div class="col-md-6">
      1 text
    </div>
    <div class="col-md-6">
        <div class="col-md-6">
          2 text
        </div>
        <div class="col-md-6">
          3 text       
        </div>
    </div>
  </div>
</div>
0

I think the best layout engine to use for your use case is hinted at in your description of the problem: Floats.

Here is a solution that doesn't require you to alter your html.

<div class="container">
  <div class="medium-box">figure</div>
  <div class="small-box">div 1</div>
  <div class="small-box">div 2</div>
</div>

.container{
  width: 500px;
}

.medium-box {
  height: 200px;
  width: 200px;
  margin: 10px;
  background: grey;
  float:left
}

.small-box {
  float:left;
  height: 30px;
  width: 200px;
  background: blue;
  margin: 10px;
}

https://codepen.io/stacyvlasits/pen/aVPZbY

vlasits
  • 2,215
  • 1
  • 15
  • 27