I'm trying to create a grid of Angular-Material cards that behaves somewhat like a Bootstrap grid. Ideally, cards will be full-width for small screen widths and jump to two columns at larger breakpoints.
Demo with 2 cards
The problem is that A-M creates columns for each card. I haven't figured out how to specify the number of columns for each breakpoint.
Demo with 5 cards
Here's the basis of the markup I'm using, which takes the card layout from rows to columns at the first breakpoint:
<div ng-app layout="column" layout-gt-sm="row" class="layout-sm-column layout-row">
<div flex class="flex" ng-repeat="i in [1,2,3,4,5] track by $index">
<md-card>
There's a similar question on SO already, but accepted answer is unsatisfactory as it uses custom CSS and the cards aren't fluid-width. I've found no other similar examples.
I suppose I could loop every two cards with Angular and create stacked sets, but that seems needlessly cumbersome. I have to think that Material provides for a better solution. Also, such solutions would leave whitespace in the page where cards vary in height. Material seems geared toward a Masonry-like flex layout, and I'd like to stick with that.
Thanks.
You can use the material Grid-List, it allows for custom col-spans and animates the changes when the width changes.
I adapted the sample from the site and added md-card
in the contents. Make sure to add layout-fill
on the md-card
.
You can easily adapt the sample for your column count.
http://codepen.io/anon/pen/QypjWY
I also adapted your 5 card sample. You need to know the height of the cards in order to use the Grid-List, but you can easily achieve the 100% height on small screens. You can use ratios or fixed CSS heights for the rows and then it is your cards job to display the content in a flexible way.
<md-grid-list ng-app="app" layout-fill flex
md-cols-sm="1"
md-cols-md="2"
md-cols-gt-md="5"
md-row-height-sm="100%"
md-row-height="600px"
md-gutter="8px">
<md-grid-tile ng-repeat="i in [1,2,3,4,5] track by $index">
<md-card layout-fill>
http://jsfiddle.net/2afaok1n/34/
Edit:
If you are instead looking for some kind of staggered grid, then you have to add a library: angular-deckgrid, it just provides the grid layout, everything in the content is angular-material. Unlike angular-masonry this library doesn't have any dependencies. If you are not worried about adding jQuery and the like then you can also use angular-masonry.
<div ng-app="app" ng-controller="DeckController" flex layout="column">
<deckgrid class="deckgrid" flex source="data">
<md-card>
The important part for the deck layout is the CSS configuration. With this you configure the number of columns and their width. I have used a media query for the angular-material sm
breakpoint to switch to single column layout.
.deckgrid::before {
content: '4 .column.column-1-4';
font-size: 0;
visibility: hidden;
}
.deckgrid .column {
float: left;
}
.deckgrid .column-1-4 {
width: 25%;
}
.deckgrid .column-1-1 {
width: 100%;
}
@media screen and (max-width: 960px) {
.deckgrid::before {
content: '1 .column.column-1-1';
}
}
http://jsfiddle.net/2afaok1n/39/
Edit 2:
There is also a masonry version which doesn't require jQuery and a simple directive to use it: angular-masonry-directive. Here is an example, it works similar to the other one.
http://jsfiddle.net/xjnp97ye/1/
If I understood the question right, this works like a charm:
<body ng-app="app" ng-cloak>
<div layout="column" layout-gt-sm="row" layout-wrap>
<div flex="25" flex-gt-sm="50" ng-repeat="i in [1,2, 3, 4, 5] track by $index">
<md-card>
<!-- You code-->
</md-card>
</div>
</div>
</body>
Plunker with multiple breakpoints : (resize the inner window, not the browser window)
http://plnkr.co/edit/8QPYdzLD8qzEbdz5sesE?p=preview
The plunker has been updated to show cards with different height.
2 directives have been made, so the biggest height of all cards is kept in memory and this one is applied to all cards.
<div ng-repeat="i in [1,2, 3, 4, 5] track by $index" flex-xs="100" flex-sm="50" flex-md="50" flex="33">
<md-card>
<md-card-title >
<md-card-title-text >
<span class="md-headline">Demo Title {{i}}</span>
<span class="md-subhead">Demo Description</span>
</md-card-title-text>
</md-card-title>
</md-card>
</div>
Check this example: http://codepen.io/ktn/pen/jqNBOe
if i understood your question right
Then use this code and replace the hello with anything you like
<md-grid-list md-cols-lg="12" md-cols-gt-lg="15" md-cols-xs="3" md-cols-sm="6" md-cols-md="9" md-row-height-gt-md="1:1" md-row-height-md="1:1" md-row-height="1:2" md-gutter-gt-md="16px" md-gutter-md="8px" md-gutter="4px">
<md-grid-tile ng-repeat="contact in contacts" md-colspan="3" md-rowspan-gt-sm="4" style="background:red;">
hello
</md-grid-tile>
</md-grid-list>