Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Responsive flexbox - change margins from horizontal to vertical after wrapping?

I have a simple layout concept that can be summarized by this picture: before wrapping

This can be easily achieved using flexbox. As you can see, the div #1 and div #3 touch the borders of their container. Also, the margin between div #1 and div #2 is equal to the margin between div #2 and div #3. It can be done with:

.inner-div{
   margin-left:10px;
}

.inner-div:first-child{
    margin-left:0px;
}

Now, let say that the viewport's width decreases. I want those divs to wrap to form a nice column. And I'd like them to look like this:

desirable

But if those divs retain their horizontal margin configuration, they look something like this instead:

undesirable

Which, as you can guess, is undesirable.

How to change margins for those inner divs when their container is so narrow that they get "wrapped"? Is there a way to write a conditional rule that would apply only to "wrapped" divs? Or am I missing the point and the solution is very obvious and I just overlooked that part of flex-box capabilities? I'd like to see a solution that would not involve predicting what container/screen width would case the layout to change from row to column, because I think that is the most maintainable option.

like image 473
Kuba Orlik Avatar asked Jul 13 '14 14:07

Kuba Orlik


People also ask

How do you remove margins from flex-wrap?

So what you would do is use grid-gap for spacing between the items. Then use padding for the same spacing between the items and the container. The last row margin problem is eliminated.

How margin Auto Works in flexbox?

If you apply auto margins to a flex item, that item will automatically extend its specified margin to occupy the extra space in the flex container, depending on the direction in which the auto-margin is applied.


1 Answers

You can absolutely use negative margins to achieve that.

Take a look at this fiddle: http://jsfiddle.net/287vW/

If you don't even bother removing the margin from the first element but leave it, and globally reduce the margin of the container, you will end up with a consistent result.

Let's assume you have the following structure:

<div class="margin">
    <div class="container">
        <div class="box one"></div>
        <div class="box two"></div>
        <div class="box three"></div>
    </div>
</div>

Then you can apply these styles:

.margin {
    border:3px solid #000000;
}

.container {
    display:flex;
    flex-wrap:wrap;
    margin:-10px 0 0 -10px;
}

.box {
    height:100px;
    background-color:#555555;
    margin:10px 0 0 10px;
    flex-grow:1;
    min-width:300px;
}

Even though we keep all margins on the elements, the negative margin of the container removes them.

Consult the JS Fiddle mentioned above for the result.

I'm sure this can be achieved with one div less, but I think you can figure that out yourself now.

Hope it helped :)

P.S.: If you want to know more about negative margins, see this article on smashing mag: http://www.smashingmagazine.com/2009/07/27/the-definitive-guide-to-using-negative-margins/

like image 129
Victor Purolnik Avatar answered Oct 02 '22 19:10

Victor Purolnik