Как создать адаптивную сетку карточек Angular-Material (с различным количеством столбцов)

Я пытаюсь создать сетку карт Angular-Material, которая ведет себя как сетка Bootstrap. В идеале карточки должны быть на всю ширину экрана для небольших экранов и переходить на два столбца при больших контрольных точках.

Демо с двумя карточками

Проблема в том, что AM создает столбцы для каждой карты. Я не понял, как указать количество столбцов для каждой точки останова.

Демо с 5 картами

Вот основа используемой мной разметки, которая переводит макет карты из строк в столбцы в первой точке останова:

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

Уже есть похожий вопрос на SO, но принятый ответ неудовлетворителен, поскольку он использует собственный CSS, а карты не имеют плавной ширины. Других подобных примеров я не нашел.

Я полагаю, что мог бы зацикливать каждые две карты с помощью Angular и создавать сложенные наборы, но это кажется излишне громоздким. Я должен думать, что Material обеспечивает лучшее решение. Кроме того, такие решения будут оставлять пробелы на странице, где карточки различаются по высоте. Материал, кажется, ориентирован на гибкий макет Masonry, и я хотел бы придерживаться этого.

Спасибо.


person isherwood    schedule 14.12.2015    source источник
comment
Возможно только с помощью css, даже с видом/стилем каменной кладки. designshack.net/articles/css/masonry/#bsap_1610   -  person g19fanatic    schedule 04.01.2016
comment
Вопрос в том, как это сделать с помощью Angular Material. У меня большой опыт работы с другими библиотеками и методами. Однако это похоже на недостаток AM, если только я что-то не упустил.   -  person isherwood    schedule 04.01.2016
comment
Я столкнулся с точно такой же проблемой, и нет собственного решения, которое сделает для вас сетку типа каменной кладки. Отзывчивость AM исходит от контейнеров flexbox, а не на уровне директив, поэтому они на самом деле не взаимодействуют друг с другом. На самом деле я создал сложенные наборы, как вы сами предложили.   -  person serraosays    schedule 05.01.2016
comment
используя css3, вы можете определить столбцы: 3 на своей md-карте, столбцы ширины медиа-запроса: 2 и, наконец, мобильные: столбцы: 1, например   -  person RobSeg    schedule 10.01.2016


Ответы (4)


Вы можете использовать материал Grid-List, он позволяет создавать собственные диапазоны столбцов и анимирует изменения при изменении ширины. .

Я адаптировал образец с сайта и добавил в содержании md-card. Обязательно добавьте layout-fill к md-card. Вы можете легко адаптировать образец для своего количества колонок.

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

Изменить:

Если вместо этого вы ищете какую-то шахматную сетку, вам нужно добавить библиотеку: 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. При этом вы настраиваете количество столбцов и их ширину. Я использовал медиа-запрос для точки останова 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:

Существует также версия masonry, которая не требует jQuery и простой директивы для ее использования: angular-masonry-directive. Вот пример, он работает аналогично другому.

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

person kuhnroyal    schedule 05.01.2016
comment
Первый пример кажется хорошим началом, но я не уверен, что смогу жить с фиксированной высотой. Я упростил демо для своих целей: codepen.io/anon/pen/YwZwbz второй оставляет разные пробелы между строками, как я уже упоминал в своем вопросе. Вероятно, это не сработает. - person isherwood; 05.01.2016
comment
Я заинтригован вашим обновлением, но третий пример (39), похоже, не демонстрирует отзывчивого поведения. Четвертый пример выглядит хорошим вариантом. - person isherwood; 06.01.2016
comment
Вы правы, 3-й несколько ограничен. Если вы запустите этот пример с большой шириной, а затем уменьшите ширину, он будет реагировать, а не наоборот. Однако он будет работать должным образом на разных устройствах с фиксированной шириной и/или перерисовкой, например. вращение устройства и т. д. Библиотека анализирует псевдо-блок ::before CSS и, должно быть, что-то там не так. - person kuhnroyal; 06.01.2016

если я правильно понял ваш вопрос, тогда используйте этот код и замените 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-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>
person Rishabh Jain    schedule 25.02.2016
comment
Это отличный ответ. Единственная проблема заключается в том, что список сетки имеет некоторые несовместимости, например, с бесконечной прокруткой. - person chrismarx; 14.04.2016
comment
@chrismarx, я согласен, но нельзя ли хранить список сетки внутри виртуального повтора? там мы можем реализовать бесконечную прокрутку.. - person Rishabh Jain; 15.04.2016
comment
Я думаю, что пробовал это, и у меня возникла эта проблема - github.com/angular/material/issues/5312 - person chrismarx; 15.04.2016

Если я правильно понял вопрос, это работает как шарм:

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

Планкер с несколькими точками останова: (изменить размер внутреннего окна, а не окна браузера) http://plnkr.co/edit/8QPYdzLD8qzEbdz5sesE?p=preview

Плункер был обновлен, чтобы показывать карты разной высоты.
Было сделано 2 директивы, поэтому самая большая высота всех карт хранится в памяти, и эта применяется ко всем картам.

person gr3g    schedule 09.01.2016
comment
Спасибо, но я не могу заставить его показать более одного изменения точки останова. Можете ли вы улучшить демо, чтобы показать хотя бы 3? - person isherwood; 10.01.2016
comment
Я разветвил версию с различным содержанием. Как видите, это не очень хорошо. Карточки сходятся вместе и отрезают содержимое. Мысли? plnkr.co/edit/VNyWOpCocKGfY0qX2IjK?p=preview - person isherwood; 11.01.2016
comment
Я начал делать улучшенный plnk с директивами, но это не имеет смысла: ?p=предварительный просмотр . Наконец у вас есть этот глупый вариант 2 plnkr.co/edit/ieafIYh6zVqI7ema3Mnz?p=preview и я отвечаю, что угловой материал имеет свои пределы. Я бы сделал 3 версии с ng-show/ng-hide для каждого блока по размеру окна. - person gr3g; 11.01.2016
comment
Спасибо за попытку. Это неприятная ситуация. - person isherwood; 11.01.2016
comment
См. обновленный плункер. Директивы работают. Все еще нужно обрабатывать высоту карты (на больших экранах 2-й столбец идет на 1-й. Я думаю, это довольно просто) - person gr3g; 12.01.2016
comment
Вам нужно изменить размер и остановить и запустить на самом деле... :/ - person gr3g; 12.01.2016

<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

person kTn    schedule 25.02.2016
comment
правильно, но что, если ваши карты не все одинаковой высоты - person chrismarx; 14.04.2016