html - CSS-only masonry layout but with elements ordered horizontally -


i need implement run-off-the-mill masonry layout. however, number of reasons don't want use javascript it.

enter image description here

parameters:

  • all elements have same width
  • elements have height cannot calculated server side (an image plus various amounts of text)
  • i can live fixed number of columns if have to

there trivial solution works in modern browsers, the column-count property.

the problem solution elements ordered in columns:

enter image description here

while need elements ordered in rows, @ least approximately:

enter image description here

approaches i've tried don't work:

now could change server side rendering , reorder items dividing number of items number of columns, that's complicated, error-prone (based on how browsers decide split item list columns), i'd avoid if possible.

is there newfangled flexbox magic makes possible?

flexbox

a dynamic masonry layout not possible flexbox, @ least not in clean , efficient way.

flexbox one-dimensional layout system. means can align items along horizontal or vertical lines. flex item confined row or column.

a true grid system two-dimensional, meaning can align items along horizontal , vertical lines. content items can span across rows , columns simultaneously, flex items cannot do.

this why flexbox has limited capacity building grids. it's reason why w3c has developed css3 technology, grid layout.


row wrap

in flex container flex-flow: row wrap, flex items must wrap new rows.

this means a flex item cannot wrap under item in same row.

enter image description here

notice above how div #3 wraps below div #1, creating new row. cannot wrap beneath div #2.

as result, when items aren't tallest in row, white space remains, creating unsightly gaps.

enter image description here


column wrap

if switch flex-flow: column wrap, grid-like layout more attainable. however, column-direction container has 4 potential problems right off bat:

  1. flex items flow vertically, not horizontally (like need in case).
  2. the container expands horizontally, not vertically (like pinterest layout).
  3. it requires container have fixed height, items know wrap.
  4. as of writing, has deficiency in major browsers the container doesn't expand accommodate additional columns.

as result, column-direction container not option in case, , in many other cases.


css grid with item dimensions undefined

grid layout perfect solution problem if various heights of content items pre-determined. other requirements within grid's capacity.

the width , height of grid items must known in order close gaps surrounding items.

so grid, best css has offer building horizontally-flowing masonry layout, falls short in case.

in fact, until css technology arrives ability automatically close gaps, css in general has no solution. require reflowing document, i'm not sure how useful or efficient be.

you'll need script.

javascript solutions tend use absolute positioning, removes content items document flow in order re-arrange them no gaps. here 2 examples:


css grid with item dimensions defined

for layouts width , height of content items known, here's horizontally-flowing masonry layout in pure css:

grid-container {    display: grid;                                                /* 1 */    grid-auto-rows: 50px;                                         /* 2 */    grid-gap: 10px;                                               /* 3 */    grid-template-columns: repeat(auto-fill, minmax(30%, 1fr));   /* 4 */  }    [short] {    grid-row: span 1;                                             /* 5 */    background-color: green;  }    [tall] {    grid-row: span 2;    background-color: crimson;  }    [taller] {    grid-row: span 3;    background-color: blue;  }    [tallest] {    grid-row: span 4;    background-color: gray;  }    grid-item {    display: flex;    align-items: center;    justify-content: center;    font-size: 1.3em;    font-weight: bold;    color: white;  }
<grid-container>    <grid-item short>01</grid-item>    <grid-item short>02</grid-item>    <grid-item tall>03</grid-item>    <grid-item tall>04</grid-item>    <grid-item short>05</grid-item>    <grid-item taller>06</grid-item>    <grid-item short>07</grid-item>    <grid-item tallest>08</grid-item>    <grid-item tall>09</grid-item>    <grid-item short>10</grid-item>    <grid-item tallest>etc.</grid-item>    <grid-item tall></grid-item>    <grid-item taller></grid-item>    <grid-item short></grid-item>    <grid-item short></grid-item>    <grid-item short></grid-item>    <grid-item short></grid-item>    <grid-item tall></grid-item>    <grid-item short></grid-item>    <grid-item taller></grid-item>    <grid-item short></grid-item>    <grid-item tall></grid-item>    <grid-item short></grid-item>    <grid-item tall></grid-item>    <grid-item short></grid-item>    <grid-item short></grid-item>    <grid-item tallest></grid-item>    <grid-item taller></grid-item>    <grid-item short></grid-item>    <grid-item tallest></grid-item>    <grid-item tall></grid-item>    <grid-item short></grid-item>  </grid-container>

jsfiddle demo


how works

  1. establish block-level grid container. (inline-grid other option)
  2. the grid-auto-rows property sets height of automatically generated rows. in grid each row 50px tall.
  3. the grid-gap property shorthand grid-column-gap , grid-row-gap. rule sets 10px gap between grid items. (it doesn't apply area between items , container.)
  4. the grid-template-columns property sets width of explicitly defined columns.

    the repeat notation defines pattern of repeating columns (or rows).

    the auto-fill function tells grid line many columns (or rows) possible without overflowing container. (this can create similar behavior flex layout's flex-wrap: wrap.)

    the minmax() function sets minimum , maximum size range each column (or row). in code above, width of each column minimum of 30% of container , maximum of whatever free space available.

    the fr unit represents fraction of free space in grid container. it's comparable flexbox's flex-grow property.

  5. with grid-row , span we're telling grid items how many rows should span across.


browser support css grid

  • chrome - full support of march 8, 2017
  • firefox - full support of march 6, 2017
  • safari - full support of march 26, 2017
  • edge - currently in development
  • ie11 - no support current spec; supports obsolete version

here's complete picture: http://caniuse.com/#search=grid


cool grid overlay feature in firefox

in firefox dev tools, when inspect grid container, there tiny grid icon in css declaration. on click displays outline of grid on page.

enter image description here

more details here: https://developer.mozilla.org/en-us/docs/tools/page_inspector/how_to/examine_grid_layouts


Comments

Popular posts from this blog

python Tkinter Capturing keyboard events save as one single string -

android - InAppBilling registering BroadcastReceiver in AndroidManifest -

javascript - Z-index in d3.js -