如何创建响应式(可变列数)Angular-Material 卡片网格

Posted

技术标签:

【中文标题】如何创建响应式(可变列数)Angular-Material 卡片网格【英文标题】:How to create a responsive (varying column count) Angular-Material card grid 【发布时间】:2016-03-20 10:45:18 【问题描述】:

我正在尝试创建一个 Angular-Material 卡片网格,其行为有点像 Bootstrap 网格。理想情况下,小屏幕宽度的卡片将是全宽的,并在较大的断点处跳转到两列。

Demo with 2 cards

问题在于 A-M 为每张卡片创建列。我还没有弄清楚如何为每个断点指定列数。

Demo with 5 cards

这是我使用的标记的基础,它在第一个断点处将卡片布局从行变为列:

<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>

已经有一个similar question on SO,但接受的答案并不令人满意,因为它使用自定义 CSS 并且卡片不是流体宽度。我没有找到其他类似的例子。

我想我可以用 Angular 循环每两张卡片并创建堆叠的集合,但这似乎不必要地麻烦。我不得不认为 Material 提供了更好的解决方案。此外,此类解决方案会在卡片高度不同的页面中留下空白。 Material 似乎适合于类似 Masonry 的 flex 布局,我想坚持下去。

谢谢。

【问题讨论】:

可能只使用 css,即使是砖石外观/风格。 designshack.net/articles/css/masonry/#bsap_1610 问题是如何使用 Angular Material 来做到这一点。我对其他库和技术有很多经验。不过,这似乎是 A.M. 的不足,除非我遗漏了什么。 我遇到了同样的问题,并且没有本地解决方案可以为您制作砖石类型的网格。 AM 的响应来自 flexbox 容器,而不是指令级别,因此它们之间并没有真正的交流。我实际上按照您自己的建议创建了堆叠集合。 使用 css3,您可以在 md 卡上定义列:3,媒体查询宽度列:2,最后是移动:列:1,例如 【参考方案1】:

您可以使用材质Grid-List,它允许自定义 col-spans 并在宽度变化时为变化设置动画。

我改编了网站上的示例,并在内容中添加了md-card。确保在md-card 上添加layout-fill。 您可以根据列数轻松调整样本。

http://codepen.io/anon/pen/QypjWY

我还改编了您的 5 张卡片样本。您需要知道卡片的高度才能使用 Grid-List,但您可以轻松地在小屏幕上实现 100% 的高度。您可以对行使用比率或固定 CSS 高度,然后以灵活的方式显示内容是您的卡片工作。

<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-
    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/

编辑:

如果您正在寻找某种交错网格,那么您必须添加一个库:angular-deckgrid,它只是提供网格布局,内容中的所有内容都是角度材质。不像angular-masonry 这个库没有任何依赖。如果你不担心添加 jQuery 之类的,你也可以使用 angular-masonry。

<div ng-app="app" ng-controller="DeckController" flex layout="column">
   <deckgrid class="deckgrid" flex source="data">
       <md-card>

甲板布局的重要部分是CSS configuration。使用它可以配置列数及其宽度。我已使用媒体查询对 angular-material sm 断点切换到单列布局。

.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/

编辑 2:

还有一个不需要 jQuery 的砌体版本和一个简单的指令来使用它:angular-masonry-directive。这是一个示例,它的工作原理与另一个类似。

http://jsfiddle.net/xjnp97ye/1/

【讨论】:

第一个例子似乎是一个好的开始,但我不确定我是否能接受固定的高度。我已经为我的目的简化了演示:codepen.io/anon/pen/YwZwbz 第二个在行之间留下不同的空白,正如我在问题中提到的那样。它可能行不通。 我对您的更新很感兴趣,但第三个示例 (39) 似乎没有表现出响应行为。第四个示例看起来是个不错的选择。 你说得对,第三个有点局限。如果您以较大的宽度运行该示例,然后减小宽度,它将响应响应,但反之则不行。但是,它将在具有固定宽度和/或重绘的不同设备上按预期工作,例如设备旋转等。该库解析伪 ::before CSS 块,并且必须在那里出错。【参考方案2】:

如果我理解你的问题 然后使用此代码并将 hello 替换为您喜欢的任何内容

<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- 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>

【讨论】:

这是一个很好的答案。唯一的问题是网格列表有一些不兼容,例如,无限滚动 @chrismarx 我同意,但网格列表不能保存在虚拟重复中吗?在那里我们可以实现无限滚动.. 我想我试过了,但遇到了这个问题-github.com/angular/material/issues/5312【参考方案3】:

如果我正确理解了这个问题,这就像一个魅力:

<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:(调整内部窗口的大小,而不是浏览器窗口) http://plnkr.co/edit/8QPYdzLD8qzEbdz5sesE?p=preview

plunker 已更新,可显示不同高度的卡片。 已制定了 2 个指令,因此所有卡片的最大高度都保存在内存中,并且此指令适用于所有卡片。

【讨论】:

谢谢,但我无法让它显示多个断点更改。你能改进演示以显示至少 3 个吗? 我已经分叉了一个内容不同的版本。如您所见,它做得不好。卡片一起运行并切断内容。想法? plnkr.co/edit/VNyWOpCocKGfY0qX2IjK?p=preview 我开始使用指令改进 plnk,但这没有任何意义:plnkr.co/edit/8QPYdzLD8qzEbdz5sesE?p=preview。最后你有这个愚蠢的选项 2 plnkr.co/edit/ieafIYh6zVqI7ema3Mnz?p=preview 我的回答是有棱角的材料有它的限制。我会在窗口大小上使用 ng-show/ng-hide 每个块制作 3 个版本 感谢您的努力。这是一个令人沮丧的情况。 查看更新的 Plunker。指令正在发挥作用。仍然需要处理卡片的高度(在更大的屏幕上,第 2 列在第 1 列。我认为这很容易)【参考方案4】:
<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>

查看此示例:http://codepen.io/ktn/pen/jqNBOe

【讨论】:

对,但如果你的卡片高度不一样怎么办

以上是关于如何创建响应式(可变列数)Angular-Material 卡片网格的主要内容,如果未能解决你的问题,请参考以下文章

响应式布局中的动态列数和行数

Rcpp 创建具有可变列数的 DataFrame

用可变字体做响应式设计

使用 HTML/CSS(响应式设计)使可变数量的 div 并排放置在相同的高度上?

html5 自动适应,响应式表格,HTML表格自适应

如何创建响应式电子邮件模板?