Выбор элементов в последней строке CSS-сетки на основе класса и атрибута данных

#javascript #html #css

#javascript #HTML #css

Вопрос:

Как сгруппировать div элементы по годам в CSS-сетке без указания года в CSS? Год включен в качестве data-group атрибута в каждый div. Я хочу выбрать последние div числа любого года для .year , .link и .title и сгруппировать их с рамкой.

Мне нужно сделать что-то вроде приведенного ниже, но это вообще не работает. Мне нужно сгруппировать элементы по годам, фактически не зная, какой это год.

 .year[data-group="unknown"]:last-of-type {
      border-bottom: 1px solid gray;
}  
 <div class="grid">
          <div data-group="2018" class="year">2018</div>
          <div data-group="2018" class="link"><a href="#"></a></div>
          <div data-group="2018" class="title">Avengers: Infinity War <span>as Natasha Romanoff / Black Widow</span></div>

          <div data-group="2017" class="year">2017</div>
          <div data-group="2017" class="link"><a href="#"></a></div>
          <div data-group="2017" class="title">Ghost In The Shell <span>as Major Mira Killian / Motoko Kusanagi</span></div>

          <div data-group="2017" class="year">2017</div>
          <div data-group="2017" class="link"><a href="#"></a></div>
          <div data-group="2017" class="title">Thor: Ragnarok <span>as Natasha Romanoff / Black Widow (archive footage / uncredited)</span></div>

</div>
      

Комментарии:

1. вы хотите иметь bottom-border под div.year каким неизвестным или под всеми, относящимися к этому году

2. Из того, что я могу сказать, не совсем ясно, чего вы пытаетесь достичь. Может быть, вы могли бы разделить свою сетку на разделы гибкой компоновки и оформить их?

Ответ №1:

Это невозможно сделать, используя только CSS, но поскольку вы отметили javascript, я предполагаю, что вы довольны решением с использованием js.

Трудность в этом заключается в том, что мы не просто ищем последний элемент с data-group для этого года — мы ищем последнюю группу данных для каждого типа класса для каждого года. Поэтому мы должны отслеживать найденные классы и годы.

На основе предоставленного вами HTML-кода приведенный ниже код найдет последние классы year , link и title для каждого года и добавит класс CSS с границей.

Что это делает:

  1. Создайте класс CSS для стилизации
  2. Создайте массив для отслеживания каждого года и комбинации классов (например, 2017 .year, 2017 .link и т.д.) — Я назвал это processedDivs в приведенном ниже коде
  3. Получите список всех элементов с data-group атрибутом
  4. Перебирайте их в обратном порядке … это означает, что первые элементы определенного типа, которые мы обрабатываем в цикле out, на самом деле являются последними в ваших данных
  5. Проверьте, добавили ли мы этот год и класс в наши обработанные разделы
  6. если нет, то мы впервые нашли этот класс и год, поэтому добавьте наш стиль CSS

Рабочий пример:

 /* 2. array to keep a record of the years and classes we have processed */
let processedDivs = new Array; 

/* 3. get all years in an array */
let allYears = document.querySelectorAll('[data-group]');

/* 4. loop through the Divs in reverse so we add the style to the first in our list*/
for (i = allYears.length-1; i >= 0; i--) {
    // Get the year and class name
    year = allYears[i].getAttribute('data-group');
    className = allYears[i].className;

    // 5. if we haven't added the CSS to this class for this year...
    if (processedDivs.indexOf(year className) === -1) {
        processedDivs.push(year className);           // add to the list
        allYears[i].classList.add("year-separator")  // add the CSS class
    }
}  
 /* 1. our class to apply to the last "row" for each year */
.year-separator {
    border-bottom: 1px solid gray;
}
.grid { 

  display: grid;
  grid-template-columns: 50px 50px 1fr;
}
.grid div {

}  
 <div class="grid flex-row-container">
      <div data-group="2018" class="year">2018</div>
      <div data-group="2018" class="link"><a href="#"></a></div>
      <div data-group="2018" class="title">Avengers: Infinity War <span>as Natasha Romanoff / Black Widow</span></div>

      <div data-group="2017" class="year">2017</div>
      <div data-group="2017" class="link"><a href="#"></a></div>
      <div data-group="2017" class="title">Ghost In The Shell <span>as Major Mira Killian / Motoko Kusanagi</span></div>

      <div data-group="2017" class="year">2017</div>
      <div data-group="2017" class="link"><a href="#"></a></div>
      <div data-group="2017" class="title">Thor: Ragnarok <span>as Natasha Romanoff / Black Widow (archive footage / uncredited)</span></div>

    </div>  

Комментарии:

1. @ONYX у вас это сработало или вам нужна дополнительная помощь с этим?

Ответ №2:

На самом деле это не проблема CSS-сетки. Проблема в том, что нет CSS-селектора, доступного для группировки элементов по значению атрибута.

Кроме того, :last-of-type будет найден только последний элемент данного типа элемента, а не последний с определенным атрибутом или значением атрибута. Не имеет значения, знаете ли вы возможные значения для data-group или нет, :last-of-type это не поможет.

Ваши лучшие варианты здесь:

  1. Измените разметку, если у вас есть над ней контроль. Группируйте каждый год чем-то вроде <div class="year-group"> ... </div> и добавляйте границу к .year-group
  2. Используйте javascript для изменения разметки или добавления имен классов, если у вас нет прямого контроля над разметкой HTML. Выполните итерацию по дочерним узлам .grid и либо оберните сгруппированные годы в содержащий элемент, как указано выше, либо сделайте что-то вроде добавления has-bottom-border имени класса к последнему div для каждого года.