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.
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:
while need elements ordered in rows, @ least approximately:
approaches i've tried don't work:
- making items
display: inline-block
: wastes vertical space. - making items
float: left
: lol, no.
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.
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.
column wrap
if switch flex-flow: column wrap
, grid-like layout more attainable. however, column-direction container has 4 potential problems right off bat:
- flex items flow vertically, not horizontally (like need in case).
- the container expands horizontally, not vertically (like pinterest layout).
- it requires container have fixed height, items know wrap.
- 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:
-
masonry javascript grid layout library. works placing elements in optimal position based on available vertical space, sort of mason fitting stones in wall.
source: http://masonry.desandro.com/
how build site works pinterest
[pinterest] cool site, find interesting how these pinboards laid out... purpose of tutorial re-create responsive block effect ourselves...
source: https://benholland.me/javascript/2012/02/20/how-to-build-a-site-that-works-like-pinterest.html
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
- establish block-level grid container. (
inline-grid
other option) - the
grid-auto-rows
property sets height of automatically generated rows. in grid each row 50px tall. - the
grid-gap
property shorthandgrid-column-gap
,grid-row-gap
. rule sets 10px gap between grid items. (it doesn't apply area between items , container.) 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'sflex-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'sflex-grow
property.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.
more details here: https://developer.mozilla.org/en-us/docs/tools/page_inspector/how_to/examine_grid_layouts
Comments
Post a Comment