I was recently prototyping a component layout that included a way to toggle the visibility of sibling elements inside a grid display. What tripped me up was, while these elements were hidden, all of the container's gap gutters remained, leaving undesired extra visual spacing. I expected these gutters to collapse. The reason they stick around is related to explicitly defining grid templates.
Template or auto layout?
What are the differences between grid-template-* and grid-auto-* when declared for columns or rows in a grid layout? Ire Aderinokun has a fantastic article that thoroughly explains these distinctions and I recommend giving it a read. I'll try to quickly summarize: grid-template-* sets explicit column and row tracks, while grid-auto-* creates implicit track patterns.
The following excerpt in the "How grid-auto works" section from the article stood out to me:
Unlike the grid-template-* properties, the grid-auto-* properties only accept a single length value.
After some experimentation and confirming through examples from the Syntax section in the grid-auto-rows MDN web docs, I found that multiple track-size values can be used as well. Let's try an example to create a layout commonly referred to as the pancake stack. Its value of auto 1fr auto will either:
explicitly size and position only the first three rows when used in grid-template-rows
act as a pattern to implicitly size each group of three rows in grid-auto-rows
Visualize the gap
In the CodePen demo below, tick on the "Hide elements" checkbox to assign display: none on all but the first two elements in both grid containers.
So what's happening here? When collapsed, the grid-template-rows container is slightly taller than its grid-auto-rows counterpart because of the extra space appearing beneath the remaining visible elements. Recall that rows are explicitly set with grid-template-rows. In this situation, the gap gutters still apply even when elements are hidden or removed from the container.
I ended up moving forward with grid-auto-rows for my component's layout needs. You can see a stripped down version of it in the CodePen below. The classic small screen navigation!
If using grid-template-* is preferred or necessary, the solution is to override the property value to match the expected visual result. The above demo could even get by on a single ruleset that applies the template only when the menu is open:
.nav.is-open{grid-template-rows: auto 1fr auto;}
This same solution can also work for grid-template-areas. While it leads to writing more code, it self-documents really nicely.
@hexagoncircle yep just another reason why CSS grid is maniacal. Imagine a "grid-gap-behavior: collapse;" property 😥
Such a great read on CSS grid templates
🔴🟣 CSS Grid Gap Behavior with Hidden Elements
by Ryan Mulligan @hexagoncircle @hexagoncircle@fosstodon.org
#CSS #cssgridgap #webdev
ryanmulligan.dev/blog/grid-gap/
숨겨진 요소가 있는 CSS 그리드 간격 동작
grid-template 및 grid-auto 레이아웃에서 항목을 숨길 때 CSS 간격 속성이 작동하는 방식에 대한 몇 가지 발견
(그냥 그리드 관련 글인가 궁금했는데 그리드에 대한 정보를 또 하나 발견... )
CSS Grid Gap Behavior with Hidden Elements, by @hexagoncircle@fosstodon.org:
ryanmulligan.dev/blog/grid-gap/
mentioned in https://zahidecconsultants.com/2023/10/23/edition-312-by-anselm-hannemann/