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-grid-3] Adding auto placement override capibilities #8655

Open
Que-tin opened this issue Mar 28, 2023 · 5 comments
Open

[css-grid-3] Adding auto placement override capibilities #8655

Que-tin opened this issue Mar 28, 2023 · 5 comments
Labels
css-grid-3 Masonry Layout

Comments

@Que-tin
Copy link

Que-tin commented Mar 28, 2023

Problem

There currently is no way to override the auto placement behaviour inside of grids. Algorithmic placement of elements inside of a grid to achieve patterns (e.g. checkboard) is therefore only possbile by manually styling all child elements.
There should be an easier way to create complex grid placements.

While discussing in #8321 I got pointed to #4002 which brings up the idea of default grids columns, rows and areas. This draft is building up on this idea.

Solution

I am thinking about the following properties + naming to solve this:

  • grid-auto-placement-column-start
  • grid-auto-placement-column-end
  • grid-auto-placement-column
  • grid-auto-placement-row-start
  • grid-auto-placement-row-end
  • grid-auto-placement-row
  • grid-auto-placement-area

as well as the following function:

  • grid()

grid-auto-placement-x

The grid-auto-placement-x properties are defined onto the grid element itself, specifying the auto placement override. Overrides can be plain numbers of type <integer> e.g.

div {
  display: grid;
  grid-auto-placement-area: 1 / 1;
}

This example would result in an easier form of the so called Grid Stack including ::before and ::after. All elements would therefore be placed on 1 / 1.

Setting grid-columns, grid-rows, grid-areas etc. on a grid-item automatically opts out of the auto placement as it is. Additionally auto placement overrides settings shall not be inherited.

grid()

The grid function is pretty similar to sibling-index() discussed in #4559. Depending on the implementation details it could actually behave the same. Right now I got two different ideas how it could work, these are described in the section The two implementations.

Base

The idea behind grid() is to get the index of the current item that's being placed inside of the grid. The function would have a similar syntax to the Relative Color Syntax by providing a parameter i that represents the index. I was thinking about the following:

div {
  display: grid;
  grid-auto-placement-area: grid(i) / grid(i);
}

This example would place elements diagonally inside of the grid.

The two implementations

Easy way

Same as sibling-index() just get the index of the current element that needs to be placed onto the grid.

Hard way

Only takes elements into account that are actually placed onto the grid. e.g. if a sibling has display: contents all children of it would therefore increase the index rather than the sibling itself.

If there is a case for it one could also think about ignoring elements that have opted out of the auto-placement by providing cols and / or rows manually.

With this implementation sibling-index() and grid() could exist complementary to each other.

Advanced

Combining grid() with various functions like Stepped Value Functions and calc() you could e.g. create a checkboard layout in a single line:

div {
  --columns: 5
  grid-placement-area: grid(round(up, i, var(--columns))) / grid(calc(mod(i * 2, var(--columns)) + 1));
}
@fantasai fantasai added the css-grid-3 Masonry Layout label Mar 29, 2023
@Que-tin Que-tin changed the title [css-grid-2] Adding auto placement override capibilities [css-grid-3] Adding auto placement override capibilities Mar 29, 2023
@Loirooriol
Copy link
Contributor

Some thoughts:

  • Additionally to i, this should probably have access to the number of columns and rows in the explicit grid.
  • Seems problematic when some items have an explicit position: probably i shouldn't be incremented for them, and auto placement should have some way of avoiding overlaps.

@Que-tin
Copy link
Author

Que-tin commented Mar 29, 2023

  • Additionally to i, this should probably have access to the number of columns and rows in the explicit grid.

Thought about this initially as well, but I'm not really sure if this makes sense or is possible in all cases. If you haven't set any grid-template wouldnt the number of columns and rows be determined by the grid-auto-placement value?

If you then use grid() inside of the grid-auto-placement wouldn't that result in a reference to result of the function it is used in? If you know what I mean.

But yeah there are probably a couple of more parameters that are technically already there to place items onto the grid that could be exposed and would increase the power and amount of use-cases for the grid() function.

  • Seems problematic when some items have an explicit position: probably i shouldn't be incremented for them

Isn't that what I wrote under Hard way? Maybe I'm understanding something wrong not sure:

one could also think about ignoring elements that have opted out of the auto-placement by providing cols and / or rows manually

  • , and auto placement should have some way of avoiding overlaps.

Not sure about that one, what exactly do you mean? Can you provide an example?

@Loirooriol
Copy link
Contributor

wouldnt the number of columns and rows be determined by the grid-auto-placement value?

Yes, the final number of tracks depends on placement. But the number of explicit tracks doesn't, and can still be useful. Just like grid-column: auto / -1 places in the last explicit column.

Isn't that what I wrote under Hard way?

Yes sorry, I missed that sentence.

Not sure about that one, what exactly do you mean? Can you provide an example?

<div style="display: grid; grid-auto-placement-area: grid(i) / grid(i);">
  <div></div>
  <div style="grid-area: 1 / 1"></div>
</div>

The 1st item has i = 1 and is placed at 1 / 1. The 2nd item has a definite position and is also placed at 1 / 1, so they overlap.

The current spec avoids this kind of things by 1st placing items with definite positions, and then the others filling the gaps, either sparsely or densely.

@Que-tin
Copy link
Author

Que-tin commented Mar 29, 2023

  • Yes, the final number of tracks depends on placement. But the number of explicit tracks doesn't, and can still be useful. Just like grid-column: auto / -1 places in the last explicit column.

Got it, agree.

  • The 1st item has i = 1 and is placed at 1 / 1. The 2nd item has a definite position and is also placed at 1 / 1, so they overlap.

I personally would want to have exactly this as wanted behaviour tbh. I mean e.g.

<div style="display: grid; grid-auto-placement-area: 1 / 1;">
  <div></div>
  <div></div>
</div>

would also auto place all elements on top of each other and this would be the wanted behaviour. I'm generally speaking if you add an auto placement you should know how and where it places the elements onto the grid so you can actually leverage this and place elements on top of each other if you want to manually place them. But I'm open for discussion there.

@Que-tin
Copy link
Author

Que-tin commented Jun 10, 2024

Something similar could be achieved with a combinaiton of @function and selectors in sibling functions.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
css-grid-3 Masonry Layout
Projects
None yet
Development

No branches or pull requests

3 participants