web-dev-qa-db-fra.com

Comment créer une grille de cartes réactive (nombre de colonnes variable)

J'essaie de créer une grille de cartes Angular-Material qui se comporte un peu comme une grille Bootstrap. Idéalement, les cartes seront pleine largeur pour les petites largeurs d'écran et passeront à deux colonnes à des points d'arrêt plus grands .

Démo avec 2 cartes

Le problème est que A-M crée des colonnes pour chaque carte. Je n'ai pas compris comment spécifier le nombre de colonnes pour chaque point d'arrêt.

Démo avec 5 cartes

Voici la base du balisage que j'utilise, qui prend la disposition des cartes des lignes aux colonnes au premier point d'arrêt:

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

Il y a déjà une question similaire sur SO , mais la réponse acceptée n'est pas satisfaisante car elle utilise du CSS personnalisé et les cartes ne sont pas fluides. Je n'ai trouvé aucun autre exemple similaire.

Je suppose que je pourrais boucler toutes les deux cartes avec Angular et créer des ensembles empilés, mais cela semble inutilement lourd. Je dois penser que Material fournit une meilleure solution. De plus, de telles solutions laisseraient des espaces dans la page où les cartes varient en hauteur. Le matériau semble orienté vers une disposition flexible de type maçonnerie, et je voudrais m'en tenir à cela.

Merci.

17
isherwood

Vous pouvez utiliser le matériau Grid-List , il permet des colonnes personnalisées et anime les changements lorsque la largeur change.

J'ai adapté l'échantillon du site et ajouté md-card dans le contenu. Assurez-vous d'ajouter layout-fill sur le md-card. Vous pouvez facilement adapter l'échantillon à votre nombre de colonnes.

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

J'ai également adapté votre échantillon de 5 cartes. Vous devez connaître la hauteur des cartes pour pouvoir utiliser la Grid-List, mais vous pouvez facilement atteindre la hauteur de 100% sur de petits écrans. Vous pouvez utiliser des ratios ou des hauteurs CSS fixes pour les lignes, puis c'est le travail de vos cartes d'afficher le contenu de manière flexible.

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

Modifier:

Si vous recherchez plutôt une sorte de grille décalée, vous devez ajouter une bibliothèque: angular-deckgrid , elle fournit simplement la disposition de la grille, tout dans le contenu est du matériel angulaire. Contrairement à angular-masonry cette bibliothèque n'a pas de dépendances. Si vous n'êtes pas préoccupé par l'ajout de jQuery et similaires, vous pouvez également utiliser la maçonnerie angulaire.

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

La partie importante pour la disposition du deck est la configuration CSS . Avec cela, vous configurez le nombre de colonnes et leur largeur. J'ai utilisé une requête multimédia pour le point d'arrêt sm angular-material pour passer à la disposition sur une seule colonne.

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

Édition 2:

Il existe également une version de maçonnerie qui ne nécessite pas jQuery et une simple directive pour l'utiliser: directive angulaire-maçonnerie . Voici un exemple, il fonctionne de manière similaire à l'autre.

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

18
kuhnroyal

si j'ai bien compris votre question, utilisez ce code et remplacez le bonjour par tout ce que vous aimez

<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>
2
Rishabh Jain

Si j'ai bien compris la question, cela fonctionne comme un charme:

<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 avec plusieurs points d'arrêt: (redimensionner la fenêtre intérieure, pas la fenêtre du navigateur) http://plnkr.co/edit/8QPYdzLD8qzEbdz5sesE?p=preview

Le plunker a été mis à jour pour afficher les cartes de différentes hauteurs.
2 directives ont été faites, donc la plus grande hauteur de toutes les cartes est gardée en mémoire et celle-ci est appliquée à toutes les cartes.

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

Vérifiez cet exemple: http://codepen.io/ktn/pen/jqNBOe

1
kTn