Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[css-display-4] Add new inner display type 'stacked' #8321

Closed
Que-tin opened this issue Jan 17, 2023 · 19 comments
Closed

[css-display-4] Add new inner display type 'stacked' #8321

Que-tin opened this issue Jan 17, 2023 · 19 comments

Comments

@Que-tin
Copy link

Que-tin commented Jan 17, 2023

We currently have no easy CSS native way to stack items onto each other without using things like grid and position: absolute. Often times using these makes things unnecessary complex or makes no sense from a design standpoint.
A new inner display type called e.g. display: stacked would help creating stacked layouts more easily and make complex stacks easier to implement.

The idea would be that display: stacked would stack all elements on top of each other. CSS Properties like align-self, justify-self, place-self, align-items, justify-items & place-items could be used to position all or individual items inside of the element, order could be used to order the element on the stack (behaviour would be the same as z-index inside of this context).

/* single-value syntax */
.stacked {
  display: stacked;
}

/* two-value syntax */
.stacked2 {
  display: block stacked;
}

An alternative would be to create a new value for flex-direction called stack.

/* flex-direction */
.stacked {
  flex-direction: stack;
}
@Loirooriol
Copy link
Contributor

So would this behave like a grid container with a single row and column, with all the contents placed in that single cell?

@jakearchibald
Copy link
Contributor

So would this behave like a grid container with a single row and column, with all the contents placed in that single cell?

That's how I've done this in the past, and it feels like the ideal way to do it.

@Que-tin demo: https://jsbin.com/kokecap/edit?html,css,output

@Loirooriol
Copy link
Contributor

Loirooriol commented Jan 17, 2023

Yeah I guess you can use

.stacked { display: grid }
.stacked > * { grid-area: 1 / 1 / 2 / 2 }

but this misses pseudo-elements and children of display: contents. But rather than adding a new display type, maybe this functionality could be backed into grid-auto-flow? Then it would just be

.stacked { display: grid; grid-auto-flow: 1 / 1 / 2 / 2 }

Or #4002 proposes grid-items-column and grid-items-row (and grid-items-area shorthand I guess?)

@Que-tin
Copy link
Author

Que-tin commented Jan 17, 2023

So would this behave like a grid container with a single row and column, with all the contents placed in that single cell?

That's how I've done this in the past, and it feels like the ideal way to do it.

@Que-tin demo: https://jsbin.com/kokecap/edit?html,css,output

@jakearchibald Maybe my specification wasn't clear enough, sorry.

Yeah I know that this could be done this way, and that's how I do it as well as of now. Thats why I said We currently have no easy CSS native way to stack items onto each other without using things like grid and position: absolute. I know that it is possible, but wouldn't it be useful to have a property for that? It would be way easier to maintain and to recognize inside of the CSS.

I am not talking about a resolving a problem that can't be resolved as of now, but about an improvement to the overall experience.

It feels kind of hacky to use a grid with only one row and one column, no? I mean is that even a grid according to what a grid is? I am open for discussion on this topic. :)

@Que-tin
Copy link
Author

Que-tin commented Jan 17, 2023

So would this behave like a grid container with a single row and column, with all the contents placed in that single cell?

Yep, exactly that. The problem with using a grid is that you can easily break it if you somehow override the placement of the individual elements and put them in multiple columns and / or rows.

Specifically with cascade layers that would easily be possible.

@jakearchibald
Copy link
Contributor

Yeah I know that this could be done this way, and that's how I do it as well as of now. Thats why I said We currently have no easy CSS native way to stack items onto each other without using things like grid and position: absolute. I know that it is possible, but wouldn't it be useful to have a property for that?

Right, but you can do it with two properties right now. I get that you're suggesting that it's one property, but it's also a whole new layout system to learn. Although, if you're saying behaves exactly like a 1x1 grid, then it seems like leaving the definition as a 1x1 grid is better than creating an alias for that?

@Que-tin
Copy link
Author

Que-tin commented Jan 17, 2023

Right, but you can do it with two properties right now. I get that you're suggesting that it's one property, but it's also a whole new layout system to learn. Although, if you're saying behaves exactly like a 1x1 grid, then it seems like leaving the definition as a 1x1 grid is better than creating an alias for that?

As mentioned in the comment above yours, building that with a grid is pretty error prone. One could easily break the wanted behaviour. There is no way to ensure that the grid will always have a single row and column.

From the idea how it's currently implemented it should work similar to a 1x1 grid to prevent having to learn a while new layout system. But from the general conditions and error boundaries it should work different.

E.g. there shouldn't be the possibility to position the elements inside on some kind of grid or anything. So grid-row, grid-column .... When I said it behaves like a 1x1 grid I was only refering to the positioning possibilites, with align, justify and place, of the individual elements inside of a grid.

@jakearchibald
Copy link
Contributor

As mentioned in the comment above yours, building that with a grid is pretty error prone. One could easily break the wanted behaviour. There is no way to ensure that the grid will always have a single row and column.

I guess I don't see the reason for this vs a special display value that generates and guarantees a 2x2 grid.

I like the idea of solving the issues around other layout children though #8321 (comment).

@Que-tin
Copy link
Author

Que-tin commented Jan 17, 2023

As mentioned in the comment above yours, building that with a grid is pretty error prone. One could easily break the wanted behaviour. There is no way to ensure that the grid will always have a single row and column.

I guess I don't see the reason for this vs a special display value that generates and guarantees a 2x2 grid.

I like the idea of solving the issues around other layout children though #8321 (comment).

I guess I misunderstood the concept of #8321 (comment). After rereading it seems like a better solution.
But what would happen if you e.g. place a child in 3 / 3 / 4 / 4? Would these definitions just be ignored?

@jakearchibald
Copy link
Contributor

Explicit cell placement takes priority over auto placement. Those definitions wouldn't be ignored.

@SebastianZ
Copy link
Contributor

And what about grid-auto-flow: 1 / 1 / 10 / 10? Would that mean that the items would stretch over the spanned grid area or would they still be placed in single grid cells but somehow be distributed across that area?

Sebastian

@Que-tin
Copy link
Author

Que-tin commented Jan 17, 2023

And what about grid-auto-flow: 1 / 1 / 10 / 10? Would that mean that the items would stretch over the spanned grid area or would they still be placed in single grid cells but somehow be distributed across that area?

Sebastian

From a pure logic stand point on how grid-auto-flow is specified it would be the first one and I also think this would be the best solution if we are looking for an easy understandable / adaptable addition. Else how would one differentiate between the different cases? When would the elements be placed in single cells and when would they span?

@Que-tin
Copy link
Author

Que-tin commented Jan 17, 2023

@Loirooriol Should I update the title & description to smth. else? I mean we are definitely not talking about an addition css-display anymore, aren't we?

@jimmyfrasche
Copy link

could it be grid-auto-flow: stack?

@Loirooriol
Copy link
Contributor

And what about grid-auto-flow: 1 / 1 / 10 / 10?

I was thinking that the auto-placement algorithm could be restricted to only place in that the specified area instead of all the grid, and it could be used in combination with [ row | column ] || dense. And when the area is filled, then it goes back to the beginning or keeps reusing the last cell? Not sure if that's useful in general. I didn't give it much thought TBH.

With grid-items-column and grid-items-row then it's clear that the items would span the specified tracks.

could it be grid-auto-flow: stack?

What would this do if grid-template defines multiple tracks? Authors might want to chose on which cell the items will stack.

Should I update the title & description to smth. else?

I mean, you can still ask for a new display value, but a new grid feature that also addresses other usecases like #4002 seems more likely to be added. You can update if you are no longer asking for the display value.

@Que-tin
Copy link
Author

Que-tin commented Jan 18, 2023

I was thinking that the auto-placement algorithm could be restricted to only place in that the specified area instead of all the grid, and it could be used in combination with [ row | column ] || dense. And when the area is filled, then it goes back to the beginning or keeps reusing the last cell? Not sure if that's useful in general. I didn't give it much thought TBH.

I can't think of a use case where one of these scenarios would be more useful than just spanning. I mean the only thing different from the normal grid flow would be the reusing of the cells right?

Would it make sense to combine the naming of these two? e.g. grid-auto-flow-column, grid-auto-flow-row, grid-auto-flow-area ...
I don't see it being used as grid-auto-flow in combination with the keywords, if the element would always be spanning row-column and dense would make no sense in combination with these.

This whole thing also seems like a good addition to subgrid in my opinion. But I think we are currently only extending the specification on #4002. What happened to it tho?

I like the idea of just doing smth. like:

.layout {
   display: grid;
   grid-template-columns: 1rem 1fr 1rem;
   
   /* All the following lines would lead to the same result */
   grid-auto-flow-column: 2;

   grid-auto-flow-column: 2 / 3;

   grid-auto-flow-area: auto / 2;

   grid-auto-flow-area: auto / 2 / auto / 3;
 }

going back to the conext of stacking it would just be:

.layout {
   display: grid;

   /* All the following lines would lead to the same result */
   grid-auto-flow-area: 1 / 1;

   grid-auto-flow-area: 1 / 1 / 2 / 2;
 }

Of course this should also work with the -start & -end properties.

Thinking about it even further maybe it would be possible to implement an even more programatic layouting approach, by allowing functions and maybe repeat to be used to exclude and include certain cells based on the index of the current row and line, just an idea, didn't think too much about it.

@Loirooriol
Copy link
Contributor

With that behavior I would use the "items" notation from #4002:

  • grid-items-column-start: sets the default grid-column-start for the items
  • grid-items-column-end: sets the default grid-column-end for the items
  • grid-items-row-start: sets the default grid-row-start for the items
  • grid-items-row-end: sets the default grid-row-end for the items
  • grid-items-column: shorthand for grid-items-column-start and grid-items-column-end
  • grid-items-row: shorthand for grid-items-row-start and grid-items-row-end
  • grid-items-area: shorthand for the 4 longhands

@tabatkins
Copy link
Member

I generally agree with Jake here - this is just a 1x1 display:grid container.

The main objection seems to be that anonymous items will auto-flow, thus expanding the grid, so it might be useful to have a way of telling anonymous items what cell to flow into.

I don't think this makes sense in practice, tho. If multiple items stack into the same grid cell, they almost by definition obscure each other. You need a way to style them individually, so you can control which one is on top and visible at any given time, but you can't do this for anonymous items. So a stacked context with anonymous items would just be unusable, and there's no way to auto-prop your way out of that. (This includes the anonymous contents of display:contents items, etc.)

And if we ignore anonymous items for this use-case, then we already have all the tools we need to solve it - display:grid; grid: 100px / 50px; on the parent and grid-area: 1 / 1; on the children. You can go out of your way to screw this up by putting items in different cells or giving them wider spans, but there's no reason for you to do so, and we don't generally add guardrails to prevent people from messing up their page on purpose.

The one place I can still potentially see a use-case for grid-auto-flow:stacked; would be to ensure that if you display:contents an element, its non-anonymous children still stack properly without having to be explicitly targeted with a grid-area definition, but again, if they're stacked you need to be able to control which is on top, so you'll need to have targeted rules for such elements anyway, so asking for them to get a grid-area in addition to whatever else you're doing seems feasible.

So, all things considered, I think we can close this; the use-case is already solved in a short and easy manner. We could theoretically make it slightly shorter and easier with a custom solution, but it would be a very minor improvement, and without evidence that this use-case is common and the current solution is hampering devs, I don't think it's worthwhile adding more to CSS.

@Loirooriol, thoughts?

@Loirooriol
Copy link
Contributor

Yes I think that's fair, adding something only for this minor improvement is probably not worth it. I was considering ideas to also cover other usecases, but these can be discussed e.g. in #4002.

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

No branches or pull requests

6 participants