I have two side-by-side grid columns. I want the grid to be the width of its container. Within that space, I want to ensure that it will always be the case that as much of each column's content is as visible as possible.
I made this demo where the grid is 300px wide, and the two columns are content editable so you can type to change the content length (and thus the values of min-content
and max-content
will also change as you type).
I am using grid-template-columns: minmax(min-content, 1fr) minmax(min-content, 1fr);
which is my best attempt yet to achieve what I want, but still isn't sufficient.
html, body {
width: 300px;
}
html * {
border: 1px solid black;
}
span {
cursor: pointer;
}
body {
display: grid;
grid-template-columns: minmax(min-content, 1fr) minmax(min-content, 1fr);
}
<span contenteditable></span>
<span contenteditable></span>
When there is nothing in the columns, the grid is balanced 50/50. Each column is 150px wide. This is good.
When there is more than 150px of content in one column, it becomes wider and begins to expand into the space the other column had available to itself. This is also good.
But: when the sum of the two columns' contents is greater than 300px, the grid starts overflowing horizontally:
Instead I would like the grid's width to be constrained to 300px, and the widest cell should shrink itself until as much as possible of the smaller cell's content is visible:
And the cell's overflow-x: ellipsis
is applied.
This should happen in the other direction too. Current and undesirable behaviour:
Desired behaviour:
When each cell on its own is already wider than half the grid, 150px in this case (current undesired behaviour):
They should both be shrunk until proportionally balanced (desired behaviour):
With a final (optional) goal of having constrained widths which are representative of their actual content widths:
I am surprised I haven't yet been able to find a standard solution for balancing side-by-side grid columns, it seems like it would be a common use case. It's very similar to this: Is it possible to set proportional grid columns based on content?, except I don't know the proportions ahead of time and they're co-dependent. I would really appreciate being pointed towards anything I may have missed.
To try to achieve this, I have tried a variety of grid-template-columns
values already, but there seems to be a CSS-expressivity problem that the widths of columns cannot depend on the contents of the other columns. Unfortunately calc(min-content/100%)
seems to invalidate the property value. I may just be missing a way to accomplish it with pure CSS, I would be over the moon if there were a CSS-only answer.
I have been trying with JavaScript since but because min-content and max-content cannot be discovered easily using JavaScript I thought I would ask here before committing several more hours to pursuing the solution I have thought of for now: allowing the grid width to be totally unlimited, measuring the outerWidth of each cell, then setting grid-template-columns
as the outerWidth / sumOfBothOuterWidth
percentage for each cell. All of this would have to be put into some MutationObserver callback too, so that it can re-calculate widths when content changes. Luckily because of using percentage values instead of hardcoded ones, resizing the window/container should redraw automatically.
Could anyone recommend an alternative solution?
The best answer would be CSS-only, and I will generally prefer solutions that require less JavaScript DOM manipulation and JavaScript calculation.