Skip to content

[css-gaps-1] Dropping decorations for suppressed gaps #13754

Closed

Description

@kbabbitt

In #13663 (comment) we resolved that, when varying gap decorations are assigned to a wrapping flex container, decorations are assigned to gaps in "linear" fashion, such that the sequence continues from one flex line to the next. An open question from that discussion is what to do with the decoration that would have appeared next to the last item in a flex line. Does that decoration get dropped from the sequence, or does it get assigned to the first gap in the following line?

One use case @fantasai brought up was a toolbar with varying decorations to separate items into groups. I constructed a straw example here: https://codepen.io/kevinbcmu/pen/ogzdvgE

Image

In my opinion, it's a little clunky to do this with gap decorations, because you have to keep your markup structure in sync with your decoration sequence. But I can't think of a better way to do it with the tools we currently have. I agree it's a case where dropping the decoration is what the author wants, and I haven't been able to come up with a plausible use case for not dropping it.

The other case where I think we'd want to drop a decoration is a gap suppressed due to fragmentation. Consider this example: https://codepen.io/kevinbcmu/pen/YPyYwBQ?editors=1100

Image

There's an auto repeater to set up dashed decorations for the intermediate rows, followed by a single value to set up solid decorations in the last row gap. If this example were fragmented on that last row gap, the author would not want the solid decoration pushed up to the preceding gap.

A third case worth considering is gaps suppressed due to collapsed tracks in grid. I've considered this a bit but haven't yet been able to construct a use case that points in one direction or the other.

Activity

  1. mhochk commented on Apr 1, 2026

    @mhochk

    As a (contrived, arguably bad) collapsed tracks in grid example, I can imagine implementing a menu like this one as a single grid.

    Image

    Though not the approach I would recommend taking, I can imagine doing this with a hard-coded set of rows based on the maximum number of rows per section, and then using a gap decoration for the one dividing line.

    Section Title Row - Pinned
    10 auto-sized 'pinned item' rows (3 of which would be empty in the image above)
    Section Title Row - Frequent
    10 auto-sized 'frequent' rows (4 of which would be empty in the image above)
    5 auto-sized 'core window' rows (2 of which would be empty in the image above)

    And then row-rules to skip the first 22 rows, then make the 1 gray line, then skip the remaining rows.

    If we wanted to support this kind of (questionable) design, it would require us taking the drop/skip approach.

  2. mhochk commented on Apr 1, 2026

    @mhochk

    Slightly less contrived, but along the same route, I tossed together this codepen inspired by what a few of my stock/credit-card/bank sites look like.

    https://codepen.io/mhochk/pen/YPGLrza

    The first example shows what a lot of those sites show me - a collection of account-impacting items, grouped into "pending" and "posted/completed". The 2 groups almost visually match, but one of the groups shows an additional column. For this example I have them use the same style, and one just hide a column (though I don't think this is what the actual sites do).

    The second example shows dynamically hiding a column in a similar fashion. Fidelity currently does a full reload when you hide a column like this, but there's no reason why it couldn't just be a minor style change.

  3. kbabbitt commented on Apr 1, 2026

    @kbabbitt
    CollaboratorAuthor

    @mhochk I don't think that example shows collapsed grid tracks, unless I'm missing something - grid track collapsing is a behavior of auto-fit.

    I tried constructing an example, though I admit it's pretty contrived and not what I would reach for: https://codepen.io/kevinbcmu/pen/MYjGpNa?editors=1100

    Image

    If one of the "Widget N" rows is deleted, that row should collapse, and I think the expected behavior would be to retain the alternation rather than dropping a decoration such that you get two adjacent row rules of the same color.

  4. alisonmaher commented on Apr 2, 2026

    @alisonmaher
    Collaborator

    For flex, I agree that skipping the rule on wrap will likely be more common. However, I'm not convinced it necessarily should be the default (as opposed to an opt-in).

    For example, in the following demo, you have an image gallery that guarantees two items per flex line with different % fills per line. Each row also alternates between images of different color hues, and you want to create a decoration repeat pattern to match the hue of the images in that row: https://codepen.io/alisonmaher/pen/raMvgwj.

    If we skip style decorations by default, we will never render the second color in the repeat in this example, which could be confusing.

    Image

    Regarding gap suppression in fragmentation, I do think we should skip because otherwise that would mean decoration styles would shift up when printing.

    For grid collapsed tracks, we drop those tracks before tracks are finalized. I think they should be treated as not having gaps to begin with, and as such, we shouldn't skip decoration rules where they would have been.

  5. mhochk commented on Apr 2, 2026

    @mhochk

    @kbabbitt - I agree that my expectation as a dev would be that the alternating pattern was maintained. I forked your codepen to make a very contrived example with explicit placement, but I would expect the same with your dynamic example and this one - that the alternating pattern is maintained.
    https://codepen.io/mhochk/pen/KwgRLrM

  6. jav099 commented on Apr 2, 2026

    @jav099
    Collaborator

    Regarding flex wrap behavior, I am not entirely convinced that the more common use case would be "dropping". We should support it, but maybe as a toggle of some sort because otherwise it can lead to surprising and unintended behavior in a lot of common cases, where the author would be confused.

    Different behavior depending on viewport (mobile vs desktop)

    .flex {
      column-rule-color: repeat(auto, red blue);
    }
    

    Viewport A (desktop)

    Image

    Viewport B, drop at wrap (mobile)

    Image

    Viewport B , no drop at wrap (mobile)

    Image

    Here is a more concrete example, but in general this dropping behavior could be surprising whenever an author wants a certain "theme" where one color of the theme can seemingly randomly disappear. They may think its a bug, and would be really difficult to debug why one color is not present at all, say on mobile. This seems like a pretty common use case to me.

    .menu-section {
        display: flex;
        column-rule-color: repeat(auto, var(--bleu), var(--blanc), var(--rouge));
      }
    

    Viewport A (desktop)

    Image

    Viewport B, drop at wrap (mobile)

    Image

    Viewport B, no drop at wrap (mobile)

    Image

    In general I think the no drop at wrap model behavior follows the mental model of what a flexbox is more closely, which then doesn't lead to unexpected behavior which as a result can be hard for an author to debug, since intuitively it would probably not be the expected behavior. If the author is not intimately familiar with the gaps spec, it would seem like a bug to them that one color disappears in certain viewports.

  7. oSamDavis commented on Apr 2, 2026

    @oSamDavis
    Collaborator

    For flex wrapping, I do not think we should have the dropping behavior by default. This reasoning boils down to the same sentiment that motivated web authors choosing linear assignment in issue 13663: It's not immediately clear from the CSS what to expect if dropping is the default.

    For example, in this self-contained component I created for a notification card:

    Image
     column-rule-style: solid, dotted;

    If dropping were the default, there would be a solid line between Open and Preview and a dotted line between Preview and Remove, which doesn’t reflect the separation I want. I understand the need for dropping behavior when items shift and certain decorations need to stay with specific groups, but I don't think it should be the default.

    For fragmented gaps, we should apply dropping behavior to maintain consistency when printing.

  8. alisonmaher commented on Apr 6, 2026

    @alisonmaher
    Collaborator

    To expand further on my comment in #13754 (comment), I think what the default should be here may come down more to what is easier for authors to understand and debug as opposed to what may be more common.

    This is a similar debate to what was discussed/resolved in #13477 (comment). In that issue, we felt that it won't be as common to always show all decorations in the case of grid, but we decided showing all decorations made sense as the default, since it shows everything to the author, and they can then adjust further based on the decorations they want to show up.

    In the current issue, it seems we have some agreement that dropping decorations at the wrap points will be more common for authoring use cases, but not always, and dropping decorations by default may be confusing for authors, especially when first learning how to use the feature. It would be harder to debug why those decorations didn't show up, as opposed to seeing all your defined decorations, and then adjusting further based on your use case.

    As a result, in the same vein as #13477 (comment), I would propose to not drop decorations by default. However, we should add a way for authors to opt into this behavior, since there are compelling authoring use cases for wanting to drop decorations at wrap points.

  9. kbabbitt commented on Apr 10, 2026

    @kbabbitt
    CollaboratorAuthor

    I find @alisonmaher's point about debuggability to be compelling. Putting myself in the shoes of an author who has an existing flexbox and adds column-rule: 1px solid red, 1px solid blue to it, I'd be very confused as to why I mostly but don't always get alternation between red and blue decorations. So on that basis I thinnk not dropping should be the default.

    The toolbar case is important, but as alluded to in my original post, it really calls for some sort of primitive to attach decoration behavior to elements rather than to a given container's gaps. We haven't really explored that space yet, and in fact we've already deferred a similar idea out of level 1: decoration visibility on an element-by-element basis. So while I'm not 100% opposed to adding in an opt-in for dropping, I think the use case would be better served with new capabilities in a future level.


    Aside: At the F2F, there was some side discussion about deferring varying decorations as a whole out of level 1, for lack of use cases that couldn't be solved with tables. @oSamDavis has been doing some research on this. He was able to construct the calendar example, which I previously thought required advanced features, using only what's in level 1. He also found this example of a responsive grid layout with varying decorations (though the lines are subtle).

  10. 14 remaining items

  11. kbabbitt commented on Jun 11, 2026

    @kbabbitt
    CollaboratorAuthor

    Note to self: this still needs flex testcases to land; they're in review in https://chromium-review.googlesource.com/c/chromium/src/+/7898244

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

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions