Skip to content

[css-gaps] Gap decorations with collapsed gutters #11814

Closed

Description

@Loirooriol

https://drafts.csswg.org/css-grid/#collapsed-gutter

When a collapsed track’s gutters collapse, they coincide exactly—​the two gutters overlap so that their start and end edges coincide.

Does this mean that the gap decorations will overlap? That doesn't sound great.

Activity

  1. kbabbitt commented on Mar 5, 2025

    @kbabbitt
    Collaborator

    Interesting. Naively, I'd have expected the two gutters adjacent to a collapsed track to consolidate down to a single gutter rather than overlapping each other.

    I suppose one use case for the spec'ed behavior might be where you have varying gap decorations over the grid, and if a track changes state from collapsed to un-collapsed or vice-versa, you want gap decorations in subsequent tracks to "stay with" those tracks. But then that means either you have overlapped decorations, or you need to define which one "wins" like we do for collapsing table borders.

  2. Loirooriol commented on Mar 5, 2025

    @Loirooriol
    ContributorAuthor

    This is also somewhat related to #10813. My conclusion there was that a collapsed track gets assigned the size of minus one gutter (and that's why the gutters overlap). But that's not great for decorations, so if we do something else, we need to think how abspos "items" will be affected.

  3. kbabbitt commented on Mar 24, 2025

    @kbabbitt
    Collaborator

    I tracked the text specifying that gutters overlap back to ac37030 by @tabatkins, which was introduced after discussion in #172, in which @fantasai wrote:

    We ended up collapsing gutters by specifying that they coincide, because the location of the gutters and the lines can be detected by abspos, so we can't just drop them. If at some point we add explicitly collapsing columns as a feature (e.g. via visibility: collapse), this behavior would be the correct one to have for that as well.

    Meanwhile, Gaps leaves the definition of where gutters exist to other specifications. That's intentional, so that gap decorations can be defined the same way regardless of container type. So from the perspective of Gaps, if the gaps overlap, then the decorations would overlap as well.

    With those points in mind, I was tempted to look for a solution in Grid, where we'd somehow still collapse grid line positions but consolidate down to a single gap. But that got me worried about introducing weird discontinuities in cases where gaps cross the threshold from being exactly-overlapping to almost-overlapping (animation perhaps?).

    I guess my take depends on whether such discontinuities could be a thing. If they could, then overlapping decorations seems like not-great-but-least-surprising behavior. If that's not a situation we need to worry about, then my preference would be to solve this with some sort of change to Grid that makes sense both for gap decorations and for abspos per #10813.

  4. fantasai commented on Apr 3, 2025

    @fantasai
    Collaborator

    CSS2.1 collapsed border conflict resolution rules: https://www.w3.org/TR/CSS2/tables.html#border-conflict-resolution

  5. css-meeting-bot commented on Apr 3, 2025

    @css-meeting-bot
    Member

    The CSS Working Group just discussed [css-gaps] Gap decorations with collapsed gutters, and agreed to the following:

    • RESOLVED: Suppress all but one decoration if gaps are coincident due to track collapsing, and use the same rules as border collapsing
    The full IRC log of that discussion <fantasai> s/Topic/Subtopic/
    <emeyer> kbabbitt: Oriol pointed out the way collapse tracks work in grid, when a track get collapsed, the gutters to either side overlap
    <emeyer> …That’s fine if they’re empty, but will cause decorations to overlap
    <emeyer> …I want to leave the definition of where gaps are to other specifications
    <emeyer> …There are reasons to have overlapping gutters
    <TabAtkins> q+
    <emeyer> …But there could be an animation of a gutter collapsing down could cause weird discontiunities
    <emeyer> …I’m leaning to leaving the behavior as is, since it seems to cause the fewest surprises
    <astearns> ack TabAtkins
    <emeyer> …But wanted to open the floor
    <emeyer> TabAtkins: I don’t recall the reasons to have only a single gutter; can you restate?
    <emeyer> kbabbitt: The PR that landed the change was that gutters can be detected by abspos elements within the grid
    <emeyer> TabAtkins: Ah. I think we should suppress the display of one of the gutters when they overlap
    <emeyer> …We could do it by making all but one of the gutters transparent
    <emeyer> …I don’t think people would like overlapping multiple decorations
    <emeyer> …We could say that if gutters overlap, all but one are transparent in some way, and could say that if they’re animated together, the transparent ones could be faded out
    <emeyer> kbabbitt: Your proposal is to define this in gaps to say if two gutters are exactly coincdental, draw only one decoration
    <emeyer> TabAtkins: Yes
    <astearns> ack fantasai
    <emeyer> …When a track collapses, and gutters are coincident, only one paint
    <emeyer> fantasai: Collapsing a gap is binary right now; you’re either collapsed or you’re not
    <emeyer> …I don’t know how we would even define otherwise
    <emeyer> …I agree with Tab that we should paint only one
    <emeyer> …We should do something similar to border-collapse rules, where you use whichever is most prominent
    <emeyer> astearns: I did not know we had those rules!
    <florian> q+
    <emeyer> fantasai: I’m pretty cranky about the border-collapse code
    <emeyer> …The rules about which border wins prioritize which style looks weirder
    <emeyer> …Here, we don’t have a hierarchy for resolving conflicts
    <emeyer> …If we ever have a region concept, we probably want the outermost border to win
    <emeyer> …The boundary is most prominent, usually
    <emeyer> astearns: Could there be decorations on the outside of subgrids that we should consider?
    <oriol> BTW, rules for border collapsing conflicts are in https://drafts.csswg.org/css-tables/#border-specificity
    <emeyer> fantasai: Yeah, if you have gap decorations that are more outside, they should get priority
    <emeyer> kbabbitt: The conflicts rules in the context of tables are in the tables spec?
    <emeyer> fantasai: They’re in CSS 2.1
    <astearns> ack florian
    <fantasai> https://www.w3.org/TR/CSS2/tables.html#border-conflict-resolution
    <emeyer> kbabbitt: We’d just point to those
    <emeyer> florian: I agree that tables got it wrong, because an edge is a specific thing
    <emeyer> …I think saying the edges of a subgrid should win; parts that are special shoudl win ver parts that are generic
    <emeyer> s/ver/over/
    <emeyer> astearns: Any other comments or questions?
    <emeyer> (silence)
    <emeyer> Proposed resolution is that we’ll suppress all but one decoration if gaps are coincident due to collapsing
    <emeyer> kbabbitt: I’d say for any reason
    <emeyer> fantasai: If we end up with negatively sized tracks and decorations overlap, both should be painted
    <emeyer> kbabbitt: Fair
    <emeyer> astearns: And amend the resolution to say we’ll use the same rules as border collapsing
    <emeyer> Objections?
    <emeyer> (silence)
    <oriol> In fact in flexbox you can have overlapping gaps with items with negative margins, right? So better restrict to collapsed gaps.
    <emeyer> RESOLVED: Suppress all but one decoration if gaps are coincident due to track collapsing, and use the same rules as border collapsing
  6. oSamDavis commented on Nov 6, 2025

    @oSamDavis
    Collaborator

    After further consideration, I’d like the CSSWG to revisit the resolution regarding coincident gap decorations caused by collapsed tracks. The current resolution states that all but one decoration should be suppressed when tracks collapse, using border-collapsing rules to determine which decoration “wins.”

    While I understand the intent behind this approach, I believe it introduces unnecessary complexity and reduces predictability. Border-collapsing rules were designed for tables, where competing border styles are visually apparent and hierarchical precedence makes sense. Applying those rules to grid gaps feels less intuitive to web authors. Authors also lose direct control over which gap decorations appear in visible gutters.

    Additionally, I believe collapsed tracks are somewhat of an implementation detail of auto-fit. Most authors use auto-fit to fill available space, not to necessarily reason about collapsed tracks. They typically don’t expect these internal mechanics to influence visual outcomes.

    Proposed resolution

    Gap decorations should map cleanly to visible gutters in the order they are specified. This approach is simpler, predictable, and gives authors explicit control.

    Example

    Consider:

    grid-template-rows: repeat(auto-fit, 20px);
    row-rule-color: red blue green yellow brown teal purple

    Under the current resolution, for the first visible gap, {red, blue, green} would compete, and border-collapsing rules might select blue. The next visible gap might then show yellow:
    Image

    With my proposal, decorations would apply sequentially to visible gaps in declaration order, producing a clearer and more consistent result:
    Image

  7. 6 remaining items

  8. moved this from Thursday Morning to Thursday Afternoon in CSS WG TPAC 2025 agendaon Nov 12, 2025
  9. css-meeting-bot commented on Nov 13, 2025

    @css-meeting-bot
    Member

    The CSS Working Group just discussed [css-gaps] Gap decorations with collapsed gutters, and agreed to the following:

    • RESOLVED: Undo previous resolution. Apply gap-decos *after* collapse (assuming collapsed tracks come from auto-fit, which is currently the only way to do it)
    The full IRC log of that discussion <TabAtkins> kbabbitt: in Grid, when you have repeat(auto-fit, ...), it generates as many tracks as necessary to fill the space, and then will collapse the unneeded tracks if there's few items
    <TabAtkins> kbabbitt: the way Grid is defined, those gaps still exist, they're just between 0-width tracks and overlap
    <TabAtkins> kbabbitt: we previously resolved to suppress all but one. went with table border-collapse rules to choose
    <TabAtkins> kbabbitt: based on comments iv'e gotten since, think that's wrong choice algo
    <TabAtkins> kbabbitt: the scenarios for picking the styles are different from in tables
    <alisonmaher> q+
    <TabAtkins> kbabbitt: gap-repeat has a repeat() syntax too, and it would be less confusing to just still use that pattern.
    <TabAtkins> kbabbitt: so I'd like to propose we undo the previous resolution and just assign decors to gaps as if the collapsed tracks don't exist
    <TabAtkins> alisonmaher: i support this change, want to give an example
    <TabAtkins> alisonmaher: if you're using gaps to switch between colors, like `repeat(black, gray)`, if you use table rules you could end up with adjacent gap decos with the same color, rather than laternating
    <TabAtkins> alisonmaher: I think authors would find that confusing and would prefer to see the repetition pattern maintained
    <TabAtkins> +1
    <astearns> ack alisonmaher
    <astearns> ack fantasai
    <TabAtkins> fantasai: for cases where we're getting this from repeated tracks this is fine
    <TabAtkins> fantasai: we've discussed collapsing empty tracks in other situations. not sure this approach would work for those cases.
    <TabAtkins> fantasai: but for the existing collapse cases, it's fine
    <TabAtkins> astearns: so you're fine with undoing previous resolution? and figuring out future stuff in the future?
    <TabAtkins> fantasai: yes
    <TabAtkins> astearns: objections?
    <TabAtkins> RESOLVED: Undo previous resolution. Apply gap-decos *after* collapse (assuming collapsed tracks come from auto-fit, which is currently the only way to do it)
  10. kbabbitt commented on Feb 12, 2026

    @kbabbitt
    Collaborator
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Type

No type

Projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions