Reputation: 5859
How do I group div
items by year in a CSS grid without specifying the year in the CSS? The year is included as a data-group
attribute in every div. I want to pick the last div
s of any year for .year
, .link
and .title
and group them with a border.
I need to do something like below but it doesn't work at all. I need to group items by year without actually knowing what year it is.
.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>
Upvotes: 3
Views: 769
Reputation: 14312
This cannot be done using CSS only, but as you tagged javascript I assume you are happy with a solution using js.
The difficulty in doing this is that we are not just looking for the last element with the data-group
for that year - we are looking for last data-group for each class type for each year. Therefore we have to keep track of the classes and years that we have found.
Based on the HTML you have provided, the code below will find the last year
, link
and title
classes for each year and add a CSS class with a border.
What is it doing:
processedDivs
in the code belowdata-group
attributeWorking Example:
/* 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>
Upvotes: 2
Reputation: 2711
This isn't really a CSS grid issue. The issue is that there's no CSS selector available to group elements by attribute value.
Also, :last-of-type
will only find the last element of a given element type, not the last with a certain attribute or attribute value. Doesn't matter if you know the possible values for data-group
or not, :last-of-type
won't help.
Your best options here are:
<div class="year-group"> ... </div>
, and add a border to .year-group
.grid
, and either wrap the grouped years in a containing element as above, or do something like adding a has-bottom-border
classname to the last div
for each year.Upvotes: 0