I have implemented a grid layout to display multiple rows, each containing 3 columns (an image, a label, and an SVG graphic). I need the ability to hide/unhide entire rows based on specific logic.
After experimenting with different methods and researching various blog posts, I have developed an approach that comes close to meeting my requirements.
However, there are two minor issues that I find concerning:
TheA helpful comment from @Paulie_D addressed this problem<img>
and<svg>
elements are not perfectly centered. The height of.grid-row
is 4px taller than necessary (104px vs. the 100px height of both<img>
and<svg>
). How can I eliminate this extra 4px in height?- During the transition, the content within the row and the surrounding grid do not move at the same speed. I would like the entire row to disappear as one cohesive unit, rather than individual components vanishing separately. Additionally, the final part of the row disappears from the top while the rest vanishes from the bottom. Is there a way to change this behavior?
function toggleRow() {
const i = d3.select('#row').property('value');
const row = d3.select('.grid-row:nth-child(' + i +')');
row.classed('visible', !row.classed('visible'));
}
:root {
--transitionLength: 0.4s;
--transitionTiming: ease;
}
.grid {
display: inline-grid;
grid-template-columns: 110px minmax(200px, max-content) 1fr;
row-gap: 5px;
}
.grid-row {
display: grid;
grid-template-columns: subgrid;
grid-template-rows: 0fr;
grid-column: 1 / 4;
align-items: center;
column-gap: 10px;
overflow: hidden;
background-color: lightgray;
transition: grid-template-rows var(--transitionLength) var(--transitionTiming);
}
.grid > .visible {
grid-template-rows: 1fr;
}
.grid-item {
min-height: 0;
transform: translateY(-100%);
visibility: hidden;
transition: transform var(--transitionLength) var(--transitionTiming),
visibility 0s var(--transitionLength) var(--transitionTiming);
}
.grid > .visible > .grid-item {
transform: translateY(0);
visibility: visible;
transition: transform var(--transitionLength) var(--transitionTiming),
visibility 0s linear;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/6.7.0/d3.min.js"></script>
<div class="grid">
<div class="grid-row visible">
<div class="grid-item img"><img src="https://picsum.photos/100" alt="Placeholder Image"/></div>
<div class="grid-item label">
<h2>Can be a long Line with several words...</h2>
</div>
<div class="grid-item svg">
<svg xmlns="http://www.w3.org/2000/svg" width="163.63" height="100" viewBox="0 0 18 11">
<rect width="18" height="11" fill="#fff" />
<path d="M0,5.5h18M6.5,0v11" stroke="#002F6C" stroke-width="3" />
</svg>
</div>
</div>
<div class="grid-row">
<div class="grid-item img"><img src="https://picsum.photos/100" alt="Placeholder Image" /></div>
<div class="grid-item label">
<h2>...or very short</h2>
</div>
<div class="grid-item svg">
<svg xmlns="http://www.w3.org/2000/svg" width="163.63" height="100" viewBox="0 0 18 11">
<rect width="18" height="11" fill="#fff" />
<path d="M0,5.5h18M6.5,0v11" stroke="#002F6C" stroke-width="3" />
</svg>
</div>
</div>
</div>
<br>
<input type="number" id="row" name="number" min="1" max="3" value="1" />
<button onclick="toggleRow()">Toggle Row</button>