Проблема

Карточки веб-дизайна — отличный способ представить коллекции информации (например, посты в блогах) в более организованном, удобоваримом формате.

К сожалению, содержание, которое они содержат, часто изменчиво — заголовки или выдержки разной длины могут оставлять неудобные пробелы и делать ваши карточки визуально непоследовательными. Нет буэно!

Решение

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

ОБНОВЛЕНИЕ: благодаря @jpuchevictoria я теперь знаю, что существует решение на чистом CSS. Элемент карты должен быть установлен на display: flex, а элемент содержимого карты должен быть установлен на flex-grow: 1. Просто!

Удивительно, но это довольно легко решить с помощью Javascript. Вы можете следовать инструкциям ниже или ознакомиться с JSFiddle.

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

HTML-разметка

<div id=’grid’>
<div class=’card’>
  <div class=’media’> </div>
  <div class=’content’>
    <h3>This post title is a normal length and looks ok</h3>
    <p>by The Author</p>
  </div>
</div>
... more cards

Стили CSS

Элементу контента присваивается display:flex и justify-content: space-between, чтобы распределить элементы title и author на противоположные концы.

Это не работает из коробки, потому что content не имеет фиксированной высоты — вот тут-то и появляется Javascript.

.content {
  padding: 20px; 
  display:flex;
  justify-content: space-between;
  flex-direction: column;
  box-sizing: border-box;
}
... other styles

Javascript-код

По сути, нам нужно выполнить три задачи:

  1. Найдите самый высокий элемент контента
  2. Установите для каждого элемента содержимого это значение
  3. Сотрите стиль высоты, как только все карты будут на своих линиях (мобильный телефон)

Первая часть скрипта JSFiddle добавляет в окно прослушиватель событий изменения размера и выполняет первоначальную настройку.

Карточки с индексами 0 и 1 сравниваются, чтобы определить, находятся ли карточки более чем в одном столбце (их не нужно настраивать на мобильных устройствах, где есть только один столбец).

if (oneTop == twoTop) {

Строка ниже уменьшает элементы содержимого карты до константы, содержащей наибольшую высоту. Примечание. Перед использованием reduce необходимо использовать оператор распространения, чтобы преобразовать NodeList в настоящий массив.

const largest = [...$cards].reduce((largestHeight,$card) => {

Наконец, мы берем наибольшую высоту элемента контента и применяем ее к элементу контента каждой карточки. Это позволяет Flexbox работать правильно — закреплять заголовок вверху содержимого карточки, а автора — внизу.

$card.querySelector('.content').style.height = largest + 'px';

Миссия выполнена!

Заворачивать

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

Ваше здоровье!

— Эндрю, Sherpa Design Co.