Looking to create a uniform list in HTML, where the columns inside each panel line up perfectly. See the desired layout:
https://i.sstatic.net/FbbPu.png
In this example, Col_1
has a width of "BBBBB"
, as it is the widest content in that column, while Col_2
has a width of "0x12345678"
, and so on...
I've searched for CSS solutions but couldn't find any that would work outside the parent container of the elements. Each list item's container acts as a parent to the "grid", making synchronization difficult.
My attempt involved using JavaScript to find the widest element in each column, setting its width to all others, and observing changes with ResizeObserver. However, triggering a resize event every time an item was added to the DOM tree was not ideal.
The JavaScript code I used looked like this:
// Initialize ResizeObserver once
var resizeObserver = new ResizeObserver((entries) => {
for (var entry of entries) {
var elem = $(entry.target);
console.log("Elem resized", elem);
// Call the resizeColumn() function here
}
});
// The following code executes every time new data arrives in the listData variable
var listPanel = $("#listPanel");
listData.forEach((entry) => {
listPanel.append(createListEntry(entry)); // createListEntry() adds a new list item with content
});
requestAnimationFrame(() => {
listPanel.find("[col-group='Col_1']").each((key, elem) => {
resizeObserver.observe(elem); // This immediately triggers the callback for some reason
});
});
resizeColumn("Col_1"); // This should equalize the columns in Col_1 after displaying the list,
// But the ResizeObserver call gets triggered multiple times for each item listed
I wish to resolve this without relying on pure HTML/CSS and explore potential JavaScript modifications to prevent triggering the ResizeObserver when showing items.
---------------------------------- EDIT --------------------------------------
The closest working solution involves having the listItem
class set to display: contents
. Unfortunately, this removes the box styling options like background color or borders due to its nature. Using Firefox-only subgrid
would be ideal, but unsupported.
html, body {
padding: 0.5rem;
background: #121212;
color: #ffffff;
font-family: verdana;
}
.listContainer {
display: inline-grid;
grid-template-columns: auto auto auto 1fr;
}
.listItem {
display: contents;
background: #45729a;
border: 1px solid yellow;
}
.listCell {
background: #ef4536;
border-radius: 0.25rem;
padding: 0.5rem;
margin: 0.25rem;
}
<div class="listContainer">
<div class="listItem">
<div class="listCell">AAA</div>
<div class="listCell">0x00001</div>
<div class="listCell">aaaaaaaaaaaaaaaaaaaaaaaaaaa</div>
<div class="listCell">true</div>
</div>
<div class="listItem">
<div class="listCell">BBBBB</div>
<div class="listCell">0x00</div>
<div class="listCell">bbbbbb</div>
<div class="listCell">false</div>
</div>
<div class="listItem">
<div class="listCell">C</div>
<div class="listCell">0x12345678</div>
<div class="listCell">ccc</div>
<div class="listCell">true</div>
</div>
</div>