6

Is there any way to make a fluid layout, where if a floating element doesn't fit, it would move to the left of the next line? Here is a picture of what I'm trying to achieve:

enter image description here

If there is space for both green and right elements, the red element floats to the right.

If there is not enough space (either green element is long, or screen is too small), the red element should wrap and align itself to the left.

This is what I currently have: fiddle

As you can see, the green element keeps aligning to the right after wrapping.

Code:

<div class="wrap">
    <div class="red">long long long long text</div>
    <div class="green">needs to align to the left</div>
</div>

.red {
    display: inline-block;
    border-color: red;
}
.green {
    float: right;
    width: 80px;
    border-color: green;
}
Alex Kulinkovich
  • 4,408
  • 15
  • 46
  • 50
skyisred
  • 6,855
  • 6
  • 37
  • 54

2 Answers2

4

Comments

This answer I am giving does not work with floats. Instead I am using the more modern CSS3 solution (so watch out with browser compatability) using display:flex. Flex offers a lot more easy options for future edits as well. It also resizes the height of all divs on a line to be the same height and probably a few more things ^^.

JSFiddle (resize the width in JSFiddle to see the effect)

HTML

<div class="wrap">
    <div class="red">long long long long text</div>
    <div class="green">needs to align to the left</div>
</div>

CSS (read the comments)

    div {
       border: 3px solid blue;
       padding: 5px;
    }
    .wrap {
        display: flex;/*create a flexbox (style it like a block item)*/
        display: -webkit-flex; /* Safari */
        flex-wrap: wrap;/*items in the flexbox will drop down when they do not fit this div*/
        -webkit-flex-wrap: wrap; /* Safari 6.1+ */
        justify-content: space-between;/*spaces content on a row keeping an item on the 
    right and one on the left and creating empty space inbetween unless the next item fits 
    in this space in which case the browser will do that (same effect as float: left, only 
    with a better transition)*/
        width: 50%;
        border: 3px solid blue;
        padding: 5px;
    }
    .red {
        border-color: red;
        flex: 0 1 180px;/*all you need to know here is that the 3th value is the width 
    of the item*/
        -webkit-flex: 0 1 180px; /* Safari 6.1+ */
        -ms-flex: 0 1 180px; /* IE 10 */

    }
    .green {
        border-color: green;
        flex: 0 1 100px;/*all you need to know here is that the 3th value is the width
    of the item*/
        -webkit-flex: 0 1 100px; /* Safari 6.1+ */
    -ms-flex: 0 1 100px; /* IE 10 */
}
Rob Monhemius
  • 4,822
  • 2
  • 17
  • 49
3

You can do this by treating the child divs as inner elements and then justify/outfill the contents of the parent div, like done here. Translating that solution for this question results in:

.wrap {
    text-align: justify;
}
.wrap div {
    vertical-align: top;
    display: inline-block;
    text-align: left;
}
.wrap::after {
    width: 100%;
    display: inline-block;
    content: ".";
    visibility: hidden;
}

div {
    background: lightblue;
    padding: 5px;
    margin-bottom: 5px;
}
.wrap {
    width: 200px;
    text-align: justify;
}
.wrap div {
    vertical-align: top;
    display: inline-block;
    text-align: left;
}
.red {
    background: salmon;
}
.green {
    width: 80px;
    background: lightgreen;
}
.wrap::after {
    width: 100%;
    display: inline-block;
    content: ".";
    visibility: hidden;
}
<div class="wrap">
    <div class="red">short text</div>
    <div class="green">needs to align to the right</div>
</div>
<div class="wrap">
    <div class="red">long long long long text</div>
    <div class="green">needs to align to the left</div>
</div>
<p>Next element</p>
Community
  • 1
  • 1
NGLN
  • 43,011
  • 8
  • 105
  • 200