CSS Flexbox Responsive Layout and % widths

Jack picture Jack · Jun 4, 2017 · Viewed 7.5k times · Source

Using angular/flex-layout, I have a simple two-column layout.

<div fxFlex fxLayout="row">
    <div fxFlex="35%">
        <!-- Left Column -->
    </div>
    <div fxFlex="65%">
        <!-- Right Column -->
    </div>
</div>

On small displays I want the columns to wrap, right below left.

Using angular/flex-layout's Responsive API, I add a breakpoint for small screens (between 600px and 959px) with fxLayout.sm="column" on the container element:

<div fxFlex fxLayout="row" fxLayout.sm="column">
    <div fxFlex="35%">
        <!-- Left Column, Top Row -->
    </div>
    <div fxFlex="65%">
        <!-- Right Column, Bottom Row -->
    </div>
</div>

On small screens the Left Column becomes the Top Row, and Right Column, the Bottom Row.

However, fxFlex="35%" and fxFlex="65%" attributes are still honored, and so the rows overlap. The Top Row occupies 35% of the display height, since it previously occupied 35% of the display width.

Please see this Plunker for an example of the problem. Note, I used the fxLayout.xs breakpoint rather than fxLayout.sm to demonstrate the problem since Plunker's divides the display up into small sections.

I can fix this by explicitly removing fxFlex using the Responsive API (i.e. fxFlex=""):

<div fxFlex fxLayout="row" fxLayout.sm="column">
    <div fxFlex="35%" fxFlex.sm="">
        <!-- Left Column, Top Row -->
    </div>
    <div fxFlex="65%" fxFlex.sm="">
        <!-- Right Column, Bottom Row -->
    </div>
</div>

Please this Plunker for an example of the solution.

There are two problems with this. Firstly, it feels very, very hacky. Secondly, assuming I want the same behaviour for small and extra small displays, I end up with:

<div fxFlex fxLayout="row" fxLayout.sm="column" fxLayout.xs="column">
    <div fxFlex="35%" fxFlex.sm="" fxFlex.xs="">
        <!-- Left Column, Top Row -->
    </div>
    <div fxFlex="65%" fxFlex.sm="" fxFlex.xs="">
        <!-- Right Column, Bottom Row -->
    </div>
</div>

Unless there's any easier way to use the Responsive API for displays below a certain dimension, rather than set breakpoints explicitly?

Answer

DGarvanski picture DGarvanski · Oct 13, 2017

The angular-flex-layout Responsive API also has a gt-sm (greater than small) property.

To avoid having to add every screen size with an fxFlex="" value you can just do something like this:

<div fxFlex fxLayout="row" fxLayout.sm="column" fxLayout.xs="column">
    <div fxFlex.gt-sm="35%">
        <!-- Left Column, Top Row -->
    </div>
    <div fxFlex.gt-sm="65%">
        <!-- Right Column, Bottom Row -->
    </div>
</div>

Or you can use the lt-lg (less than large) property and have

<div fxFlex fxLayout="row" fxLayout.sm="column" fxLayout.xs="column">
    <div fxFlex="35%" fxFlex.lt-lg="">
        <!-- Left Column, Top Row -->
    </div>
    <div fxFlex="65%"  fxFlex.lt-lg="">
        <!-- Right Column, Bottom Row -->
    </div>
</div>