Reputation: 707
I am trying to use md-card to create a grid of article cards. On large displays I would want it to be 3 cards wide, tablet size 2 cards wide, smartphone 1 card wide. Although the images won't be the exact same size, I would like all the cards to be the same size without distorting the image.
I am at a loss as to how to achieve this. I seriously want to avoid hard coding set widths and heights for the cards and want them instead to be fluid with the size of the display. I am thinking I need to use flex attributes?
This is what it looks like now:
Here is the structure of my card view:
<md-content>
<section class="cards" ng-if="view === 'Articles'">
<div layout="row" layout-sm="column" layout-align="center" layout-wrap>
<md-card flex="33" ng-repeat="article in home.articles | filter:searchCard">
<img ng-src="{{article.imagePath}}" alt="Test image">
<div class="card_content">
<a href="/article/{{article.id}}"><h3 class="md-subhead article_card_title">{{article.title}}</h3></a>
<div class="card_agency">
<span class="agency_name">{{article.agency}}</span>
</div>
</div>
</md-card>
<h1 class="md-display-1" ng-show="(home.articles | filter:searchCard).length == 0">No results!</h1>
</div>
</section>
</md-content>
Any insight on how to make these cards responsive would be so so so appreciated!
Upvotes: 2
Views: 5070
Reputation: 3180
This is simpler than you think. Since you want cards to keep their original size (so they don't distort the image) you should not set flex percentage, but let them grow and shrink as they need. To achieve the effect you want, try the following:
<div layout="row" layout-align="center stretch" layout-wrap>
<md-card ng-repeat="article in home.articles | filter:searchCard">
...
</md-card>
</div>
Cards will only take up as much space as they need and if they overflow the row, they will be wrapped because of the layout-wrap attribute. This doesn't ensure that you will always have 3 cards on desktop, 2 cards on tablet and 1 card on mobile, but will ensure that cards will always have as much space as they need to fit on the screen.
If you really want to have that kind of layout, the way to do it would be this:
<div layout="row" layout-align="center stretch" layout-wrap>
<md-card flex="95" flex-gt-sm="45" flex-gt-md="30" ng-repeat="article in home.articles | filter:searchCard">
...
</md-card>
</div>
Because cards have a margin, you have to set a the next smaller flex percentage. So instead of flex = 33%, you should use 30% and instead of 50% use 45% (or manually set the max-width and flex-basis to 47% or so on your CSS file).
Hope this helps.
Upvotes: 0
Reputation: 96
You are asking for all images to potentially be different sizes while at the same time maintain the size of element they exist in.
Think about that. If you have a slice of pizza and it's too big for your plate, where does the extra pizza go? Off your plate. Unless you want to "distort" your pizza, fold it up, Then it will fit! I guess the other thing you could do is cut off the pieces of pizza that don't fit (crop), then it might work! if we shrink the pizza, that would cause issues because then it fits the plate but the plate is not completely full of pizza.
I use the example above because technically it is not possible to do what you ask. I may be misunderstanding what you want.
I would suggest using md-grid-list and putting the md-card directive within the grid. Give the grid the layout you desire and remove all styling from your cards.
I was having similar issues when trying to use md-card to scale. Instead restricting it with md-grid is easier to work with.
<md-content layout-padding>
<md-grid-list md-cols="2" md-gutter="0px" md-row-height="5.8:10">
<md-grid-tile ng-repeat="cat in catalogs">
<md-card md-ink-ripple>
<catalog-select type="cat">
</catalog-select>
</md-card>
</md-grid-tile>
</md-grid-list>
</md-content>
note: catalog-select is a custom directive, it references a templateUrl, but I'll paste the code they carry, which is:
<md-card-content>
<img ng-src="{{ type.img }}"/>
<md-card-title>
<md-card-title-text>
<h4> {{ type.year }} </h4>
<h5> {{ type.title }} </h5>
</md-card-title-text>
</md-card-title>
</md-card-content>
I wanted my code to keep the cards 2 in a row (or two columns) thus: md-cols="2" there is good documentation on how to adjust the layout of the md-grid-list directive how you like: https://material.angularjs.org/latest/api/directive/mdGridList
Hope this at least helps. Using the flex="33" on the md-card seems like it would work, but the md-card's primary function is for looks not for layout. They created grid-list for the latter.
Hopefully this helps.
Upvotes: 2