w3c / csswg-drafts

CSS Working Group Editor Drafts
https://drafts.csswg.org/
Other
4.48k stars 659 forks source link

[css-grid] Property "grid-item-of": display any element as part of any given grid #2530

Open tobireif opened 6 years ago

tobireif commented 6 years ago

I want to be able to display any element located anywhere in the HTML tree as part of any given grid (without changing the HTML / the DOM).

For example:

#foo {
  display: grid;
}
#bar {
  display-as-grid-item-of: "#foo";
  /*
  Where to place it in grid #foo :
  */
  grid-row: 5;
  grid-column: 3;
}

Update: A more complete example:

.any_selector.pointing_to_the_grid {
  display: grid;
  /* Any additional normal Grid stuff here: */
  grid-template-columns: repeat(2, auto);
}
.any_selector.pointing_to_the_element {
  /* The new feature: */
  grid-item-of: .really_any_selector. pointing.to_the_grid;
  /* The element gets auto-placed in the grid as if it were appended as grid child. */
  /* Optional: Where to place it in the Grid: */
  grid-row: 1;
  grid-column: 2;
  /* Any additional Grid item properties here. */
}
mrego commented 6 years ago

This is similar what's suggested in Eric Meyer's example: https://21fb920ea3b040f8acad2b67bc992b92.production.codepen.plumbing/ericmeyer/subgrid-inner-alignment.html

Which is linked from https://codepen.io/rachelandrew/project/full/68cc7a5da9cfbb56c6e8366d7d92e6ba/XWYGMD/ (via https://github.com/w3c/csswg-drafts/issues/2280#issuecomment-380078275).

tobireif commented 6 years ago

I don't think that subgrid would provide the full flexibility of my wish. I'll be happy to be proven wrong though 😀

Subgrid is looking good for the listed use cases, but my wish is not mainly about lining up stuff, instead it's more about "reordering" across the complete DOM tree.

To illustrate:

This

<body>
  <div id="foo">
    <div>some</div>
    <div>content</div>
    <div>here</div>
  </div>
  <div id="bar">also some content</div>
</body>

plus this

#foo {
  display: grid;
  grid-template-columns: repeat(2, auto);
}
#bar {
  display-as-grid-item-of: "#foo";
  /*
  Where to place it in grid #foo :
  */
  grid-row: 1;
  grid-column: 2;
}

would make #bar appear in the grid #foo, as grid item of grid #foo, as if the markup would have been

<body>
  <div id="foo">
    <div>some</div>
    <div>content</div>
    <div>here</div>
    <div id="bar">also some content</div>
  </div>
</body>

Element #bar gets laid out as part of grid #foo, in this example at the location grid-row: 1; grid-column: 2 . (If grid-row and grid column would not be specified, the element would get laid out as if it would have been added as last child of #foo).

This feature would allow the CSS Grid user to place any element located anywhere in the page DOM into any layout grid.

It might be a feature for Grid 2 or Grid 3.

mrego commented 6 years ago

The example I linked, dunno why it only works if linked from @rachelandrew's codepen) is the one called Inner alignment. It's not only subgrids, but it's about named grids, check the proposed CSS there:

  #outer {display: grid(pagecolumns);}
  #inner .thing1, #inner .thing2 {display: pagecolumns;}

If I got it correctly that would be naming a grid container and referring it from somewhere else.

tobireif commented 6 years ago

Interesting.

That would make .thing1 and .thing2 get laid out as part of the grid with ID #outer, right? That might fulfil my wish.

Is it a requirement of that proposed feature that #inner is a descendant of #outer? (As their names might imply.) In the feature I want there'd be no such restriction. The element that gest moved into the given grid could be located anywhere in the whole page DOM - it could be part of a sibling tree, or it could even be a grandchild of the given grid. (One obvious restriction would be that you can't place eg the grid itself into that same grid.)

Another aspect: The grid #outer already has a "name" (something to refer to it / a selector), so I'd prefer my syntax where it's not necessary to create an additional name for the grid into which the other element gets moved. eg

#some_selector {
  display: grid;
  grid-template-columns: repeat(2, auto);
}
#some_other_selector {
  display-as-grid-item-of: "#some_selector";
  /*
  Where to place it in the grid #some_selector :
  */
  grid-row: 1;
  grid-column: 2;
}

But the syntax display: grid(foo) with display: foo would be OK for me as well if the effect is the same - that the element with display: foo gets laid out as grid item of the element which has display: grid(foo), and that it's possible (optionally) to specify the grid-row and grid-column in which the "layout-moved" item should appear (this is crucial - when I move an element into a Grid I need to be able to specify where exactly that Grid item should appear).

Is there a ticket for that other feature/syntax? We should cross-link them.

tobireif commented 6 years ago

This functionality would be a really useful addition to Grid.

SelenIT commented 6 years ago

I like the approach suggested in @mrego's comment very much! From the first look, it seems that the only requirement that the grid items should come in the source document after the element that defines the grid (either as its descendants, its following siblings or any of its ancestor's following siblings) is enough to prevent any circularity. These grid items would be taken out of the flow (just as if they were absolutely positioned) and placed into the well-defined visual context. Sounds great!

The only downside I can see is the discrepancy between source order and visual order, but this problem is not new for CSS Grid, so I'm sure browsers find a way to solve it, and that solution would apply to this proposal, too.

tabatkins commented 6 years ago

Since I'm thinking of it...

The CSS specs themselves would strongly benefit from this. Right now the ToC sidebar is positioned using a fairly hacky combo of position:fixed (on the sidebar) and a big left margin (on the body), and we have to be really careful that things work out properly. With this we could just make html into a two-column grid, and pull the ToC up into the first column, and put body in the second.

(Alternately, the old Template Layout idea of being able to have a grid item that was just "the rest of the stuff all flowed together" (the @ cell) would work here, since the ToC is top-level in body - we'd make body a grid, just make ToC a normal grid item, and make the second column a "catch-all" cell to get the rest of body's contents.)

The reason we can't just use Grid right now is that we have to support both "inline" ToC (between the Abstract/Status and the rest of the spec) and sidebar ToC, so we can't just put the ToC and the rest of the content into two container elements. (Tho, if we had a way to span across the entire implicit grid (#2402), we could just use the existing markup, and let all the non-ToC elements just create a bunch of implicit rows...)

AmeliaBR commented 6 years ago

This sounds like a use-case that should be addressed in an updated CSS Regions spec. It breaks down as (a) defining a named region that is laid out as a grid area, and (b) defining a container element to flow into that region.

Regions was all about creating a layout tree that is independent from the DOM tree, and which can be dynamically adjusted. The current spec was abandoned, as far as I understand, because of objections to its reliance on dummy markup to define the layout tree. But the rest of the spec is still worth considering. For many use-cases, including this one.

tobireif commented 6 years ago

This sounds like a use-case that should be addressed in an updated CSS Regions spec.

I sincerely don't think that that's the case.

I simply want to be able to display any element as grid-item of any given grid - no matter where it is located in the DOM tree (with the exception of eg the grid parent element). That's all - there's no region and no flowing into regions.

When I write eg this

#the_grid {
  display: grid;
  grid-template-columns: repeat(2, auto);
}
#the_element {
  display-as-grid-item-of: "#the_grid";
  /*
  Where to place it in the Grid :
  */
  grid-row: 1;
  grid-column: 2;
}

... #the_element becomes a Grid item of #the_grid, as if it were a DOM tree child of #the_grid. That's all. The result should be the same as if #the_element had been moved from its location in the DOM tree to become a child of #the_grid (eg always as last child - it can still get moved/positioned in that grid layout using grid-row etc). Nothing less should happen, and definitely nothing more - thus it is purely a Grid wish (which could be generalized so that it can also be used with Flexbox) and is not a Regions feature or wish.

And yes, Regions should also get finished 😀

tobireif commented 6 years ago

The CSS specs themselves would strongly benefit from this.

Glad to hear that!

And I think that many more projects could benefit from the new feature.

There's a given DOM tree, and Grid gives us the freedom to lay out eg a sub-tree in nearly any possible way (yay!) But when the design process identifies that eg one element from outside of that sub-tree should get displayed as part of that mentioned grid, then that currently could only be solved by moving it in the DOM tree (eg using JS). That's a bit hacky - the beauty of Grid, Flexbox, etc is that the DOM tree does not have to get modified in order to apply the layout.

(I'm aware that I'm mostly preaching to the choir 😀 but reasoning about the feature can help with crystallizing the details.)

The example from above, with a more general property name display-as-layout-item-of:

#the_grid {
  display: grid;
  /* Any additional normal Grid stuff here: */
  grid-template-columns: repeat(2, auto);
}
#the_element {
  /* The new feature: */
  display-as-layout-item-of: "#the_grid";
  /* Where to place it in the Grid: */
  grid-row: 1;
  grid-column: 2;
}

I hope that the new functionality will get added to Grid 😀

SelenIT commented 6 years ago

Honestly, I also wouldn't like to make this issue too broad by adding more generic concepts like Regions to its scope. I'd rather leave it a Grid-specific issue, since Grids (unlike most other CSS mechanisms) is "container-first", so once a grid is defined, it can potentially create "slots" with the definite size and position for elements that are not loaded yet. And since the structure of the grid is well-defined, I don't see strict reasons why these elements necessarily have to be direct children of the grid container.

The only note regarding the proposed syntax, I don't like identifying the grid by the ID of the element in the source document language. I'd prefer naming grids in CSS only, like in @mrego's example above or something like this:

#the_grid {
  display: grid;
  /* Naming the Grid with the CSS identifier, similarly to naming grid areas etc.: */
  grid-name: my-super-grid;
  /* Any additional normal Grid stuff here: */
  grid-template-columns: repeat(2, auto);
}
#the_element {
  /* The new feature — attaching the element to the named grid: */
  grid-item-of: my-super-grid;
  /* Other grid placements properties as usually: */
  grid-row: 1;
  grid-column: 2;
}
tobireif commented 6 years ago

Thanks for you input!

once a grid is defined, it can potentially create "slots" with the definite size and position for elements that are not loaded yet.

You're referring to the loading phase, but just in case someone might misunderstand the above:

Just to clarify:

The element would get rendered as if it had been appended to the children elements of the grid container element. There's no need for the web developer to create "slots" with the definite size and position - the layout-moved element would simply get rendered as if it were a DOM tree child of the Grid container element. It would get placed via auto-placement just as if it would be an actual DOM tree sibling of the other grid items in that grid. Optionally, the layout-moved item could get positioned using eg grid-row and grid-column.

I don't like identifying the grid by the ID of the element in the source document language.

You could use any selector 😀and you could easily avoid using IDs.

I'd prefer naming grids in CSS only

Selectors are CSS 😀(The ID selectors in my above example are just plain CSS selectors.)

Since we already have a system for pointing at elements (CSS selectors) we don't have to (and thus should not) add an additional system for pointing at elements. And we don't have to (and thus should not) require the web developer to create names. We can already point at the grid (using CSS selectors) - without having to add the line grid-name: the-name.

.any_selector > .pointing_to_the_grid {
  display: grid;
  /* Any additional normal Grid stuff here: */
  grid-template-columns: repeat(2, auto);
}
footer .any_selector .pointing_to_the_element {
  /* The new feature: */
  grid-item-of: ".really_any_selector .pointing.to_the_grid";
  /* The element gets placed in the grid as if it were appended to the grid children. */
  /* Optional: Where to place it in the Grid: */
  grid-row: 1;
  grid-column: 2;
  /* Any additional Grid item properties. */
}
SelenIT commented 6 years ago

@tobireif, yes, by mentioning "slots" for future elements (implicitly) created by the Grid I just wanted to note that the proposed extension for the Grid mechanism is quite progressive-loading-friendly (which may be important for the implementers). Thanks for the clarification!

But regarding referencing the elements by CSS selectors I'm not convinced yet, AFAIK, CSS never used selectors as values before, it would be a new idiom for CSS parsers and could be therefore harder to implement than reusing the common pattern of naming things in CSS. Also, selectors can change if DOM is modified dynamically, while grid names assigned through CSS property would be unaffected in the same case. And if at some point in the future it becomes possible for the element to establish more than one grid (this idea is cropping up from time to time), then referencing the grid by name would be more unambiguous and flexible than referencing its originating element by selector.

tabatkins commented 6 years ago

CSS never used selectors as values before,

Not technically true, but at least there it's limited to ID selectors.

That said, I still agree that declaring names manually is better.

bradkemper commented 6 years ago

I, for one, would be estactic if we could have grid slots as regions that anything could flow into. I think it is a fantastic pairing. A lot of work has already gone into regions before it entered its deep slumber, and finally we have a good existing mechanism (grid) for creating the regions without the extra markup that distracted so many people.

bradkemper commented 6 years ago

The current spec was abandoned, as far as I understand, because of objections to its reliance on dummy markup to define the layout tree.

No, Chrome killed it by declaring they weren’t interested in implementing it.

tobireif commented 6 years ago

CSS never used selectors as values before

That's not an argument against it 😀

Having a selector as value looks unfamiliar, but that's not an issue.

it would be a new idiom for CSS parsers

Every CSS implementation supports CSS selectors.

By the way, the quotes probably aren't necessary:

grid-item-of: .the_grid;

Also, selectors can change if DOM is modified dynamically, while grid names assigned through CSS property would be unaffected in the same case.

When naming a grid you're always binding it to an element, right? ... to which you point using a CSS selector 😉

if at some point in the future it becomes possible for the element to establish more than one grid (this idea is cropping up from time to time), then referencing the grid by name would be more unambiguous and flexible than referencing its originating element by selector.

If that will indeed get specd, then that is a good reason for naming.

Pointing to eg the grid named "grid_two" of an element could be done using something like this

grids-of(.the_grid_element)[grid_two]
/* grids-of(.selector)[name] */

... or using the (if I understood you correctly) global names you're suggesting.

My main wish is the functionality enabling us to display any element as grid item of any grid. I'll sure take it - no matter whether it requires me to declare names (even if there's just one grid for the grid parent); or whether it allows me to point at the respective grid parent using a selector without having to declare names when there's just one grid for that element.

tobireif commented 6 years ago

I, for one, would be estactic if we could have grid slots as regions that anything could flow into.

Unfortunately that's out of scope for this here issue. My ticket is a feature suggestion of extremely narrow scope: it does nothing else but have the same layout-effect as if you'd move one element into a grid tree - that's all. This here feature must keep that minimal scope. I'm sure you'll understand. Please (really and sincerely) feel free to create a separate ticket for your related but separate wish. Thanks!

If you're lucky, @AmeliaBR will also support the ticket / contribute to it.

I, for one, would be estactic if we could have grid slots as regions that anything could flow into. I think it is a fantastic pairing. A lot of work has already gone into regions before it entered its deep slumber, and finally we have a good existing mechanism (grid) for creating the regions without the extra markup that distracted so many people.

Please don't forget to include these great points in the new ticket.

And I also hope that Regions itself will get finished and implemented!

Perhaps your suggestion could get filed as suggestion for the CSS Regions spec (this ticket here is prefixed with "[css-grid]" and applies only to the Grid spec).

Sincerely: Good luck with your Regions feature suggestion!

SelenIT commented 6 years ago

When naming a grid you're always binding it to an element, right? ... to which you point using a CSS selector

My point here was that the same element can match different CSS selectors in different moments of time (e.g. div:nth-child(2) becomes div:nth-child(4) if two more divs are dynamically inserted before it). To maintain the reference to the same grid, you will have to update this selector after any DOM change. With manually named grid, this would not be the case — the DOM and CSS concerns are separated better.

My main wish is the functionality enabling us to display any element as grid item of any grid.

Mine too. That's why I'm for the syntax that would be (probably) easier and faster to implement! :)

tobireif commented 6 years ago

My point here was that the same element can match different CSS selectors in different moments of time

When naming a grid you're always binding it to an element, right?

... to which you point using a CSS selector.

That selector can get broken just as well, right?

I'm for the syntax that would be (probably) easier and faster to implement! :)

CSS selectors are implemented already.

But I'm still open to offering naming (eg in addition to selectors or as sole ref mechanism), especially for cases where there actually are more than one grid for the given grid parent.

tobireif commented 6 years ago

@meyerweb The example that @mrego linked above was created by you, so I thought I'd @ you so that you can chime in 😀regarding the whole ticket.

SelenIT commented 6 years ago

When naming a grid you're always binding it to an element, right?

Strictly speaking, not necessarily. IMO, the biggest advantage of the whole approach is that the grid can be defined absolutely anywhere, e.g. inside the @page rule or even with some dedicated @-rule like @grid my-super-grid { /* grid properties here */ } introduced by some future CSS extensions.

That selector can get broken just as well, right?

Less likely. With named grid, I don't have to bother about the DOM relations between the place where the Grid is defined and the element I want to place onto it at all. The proposed approach opens the possibility to completely decouple the visual structure from the DOM structure, and relying to DOM relations (in form of selectors) seems to be kind of step back to me.

CSS selectors are implemented already.

But parsing CSS values as arbitrary selectors is not yet. It might be "not technically true" again, but even implementing the ID-limited case mentioned above by @tabatkins seems to be rather problematic.

That said, I support your proposal in general and hope that it makes it to the implementation. If implementers find the selector-based approach easier, I would be completely fine with it! :)

tobireif commented 6 years ago

Can you post some example code which is declaring a name? (It would have to be complete, and should show the naming you're referring to, used as part of the move-into-grid feature, and it should be simply Grid 1 plus this here feature). Then I might understand better how it might be less brittle.

fantasai commented 6 years ago

On 05/16/2018 01:42 AM, Brad Kemper wrote:

The current spec was abandoned, as far as I understand, because of objections to its reliance on dummy markup to define the layout tree.

No, Chrome killed it by declaring they weren’t interested in implementing it.

Both are true. And also the regions implementation in webkit/blink was pretty messy iirc.

That first reason was the main reason Opera and Mozilla objected, though.

meyerweb commented 6 years ago

@meyerweb The example that @mrego linked above was created by you, so I thought I'd @ you so that you can chime in 😀regarding the whole ticket.

I’m in favor of the general concept, as you might expect. The exact syntax I’m more agnostic about. Using properties that refer to custom identifiers in the idiom of grid areas (e.g., SelenIT’s example) is fine with me, and could benefit from being an approach familiar to authors. Using a syntax like the one I came up with is fine with me as well.

The only thing I’d want to be aware of is making sure whatever syntax is devised works well with, or at least does not complicate:

  1. The future ability to flow content between grid areas/slots/whatever in a Regions-like way.
  2. The future ability to refer directly to grid cells/tracks for direct styling.

I think those are both important capabilities to preserve. I’m not saying I see ways they would conflict here, just that I’d want that on the list of Things To Be Careful About™.

tobireif commented 6 years ago

With named grid, I don't have to bother about the DOM relations between the place where the Grid is defined and the element I want to place onto it at all.

When you'd use grid-item-of: .selector_for_the_grid, I don't think you'd have to "bother about the DOM relations between the place where the Grid is defined and the element". You'd simply point to the grid parent using any selector you want.

The proposed approach opens the possibility to completely decouple the visual structure from the DOM structure, and relying to DOM relations (in form of selectors) seems to be kind of step back to me.

At some point you'd have to point to the element to which you want to apply the grid / the name. You'd do that using selectors. So we could (as long as there can only be one grid per element) use selectors directly - without requiring names.

If names are generally better then we should replace selectors with naming in CSS in all places - but that would require a lot of declaring of names. So I'm happy with using selectors.

That said, I support your proposal in general and hope that it makes it to the implementation.

Great to hear! (I'd like to repeat that @meyerweb had created an example before I submitted this ticket. I didn't know about it when I submitted the ticket - in any case: credit where credit is due.)

If implementers find the selector-based approach easier, I would be completely fine with it! :)

I think that grid-item-of: .selector_for_the_grid would work out nicely (selectors are a complete and supported way of pointing to an element eg the grid parent), and that naming is not required (when one of the features that require naming gets specd then it can feature naming), and that supporting selectors as values is not very hard (selectors are implemented already, just the delimiter is ; instead of { ), and that naming always (at some point) gets applied via selectors so we can just as well use selectors, and that the CSS user should not be required to write a line that's not necessary (the line which declares the name).

But I have a hunch that I'm completely outnumbered 😀so I'll (obviously and in any case) let the CSS WG decide.

One main item we seem to agree on is that there could be a new property, and that it could be named grid-item-of- that's fundamentally positive and promising 😀

SelenIT commented 6 years ago

You'd simply point to the grid parent using any selector you want.

Let's say I want to add a new component to the Grid on a page that is built using something like CSS Modules, so class names for different components are generated dynamically and they have no IDs. I see that the component that defines the Grid is always the first div in the body, so I have to use grid-item-of: body > div:first-child; to put my component into that Grid. But then, at some point some other component dynamically inserts another div (e.g. a popup) before this div. Oops, my selector suddenly becomes incorrect, so my component is no longer the Grid item. Also, what happens if there are several elements matching my selector, and all they define different Grids?

In the CSS Houdini terms, making the basic working prototype of the bare functionality of placing any element onto any existing Grid would require only CSS Layout API (to name the Grid, the existing Custom properties can be used). However, implementing the selector-referencing mechanism would require using CSS Parser API (which is still in development) to introduce the whole new type of CSS values as well (even CSS Properties and Values API doesn't seem to allow this yet).

So requiring this mechanism to rely on selectors seems to make the implementation harder. And I can't agree that using selectors is so much better for authors, too. So I'd prefer to have the functionality of placing any element onto any Grid and using selectors for this as two separate issues, to prevent the latter from hampering the former.

If names are generally better then we should replace selectors with naming in CSS in all places

Selectors are great for what they are: to select DOM elements. They are not so great for non-DOM things belonging to the CSS box tree only (pseudo-elements are trying, but they are tricky and browsers always have problems with them).

One of the reasons why old Regions failed was probably their unnecessary coupling with DOM. And I don't want this proposal to end that way:(

One main item we seem to agree on is that there could be a new property, and that it could be named grid-item-of

Yes! 👍

tobireif commented 6 years ago

I have to use grid-item-of: body > div:first-child;

No, you could use any type of selector, eg class names you mentioned.

what happens if there are several elements matching my selector, and all they define different Grids?

When you apply the name, you're using a selector:

.foo .bar {
  display: grid;
  grid-name: the-grid;
}

Thus the issue you describe exists in both approaches.

As long as the name gets applied using a selector, all pros and cons of using selectors apply to both approaches.

However, implementing the selector-referencing mechanism would require using CSS Parser API (which is still in development) to introduce the whole new type of CSS values as well (even CSS Properties and Values API doesn't seem to allow this yet).

Every CSS implementation supports selectors - they don't have to wait for Houdini.

And I can't agree that using selectors is so much better for authors, too

Sure it's better not being required to write a line that's not necessary. Making up a name and declaring that name is not necessary because we can point to the element using eg a simple and short selector. It points to the element that is the grid. As long as elements can have only one grid that would work perfectly fine. (And .foo .bar { display: grid; grid-name: the-grid; } also supports just one grid per element as far as I can see.)

One of the reasons why old Regions failed was probably their unnecessary coupling with DOM.

Pointing to grid elements using selectors doesn't require any specific HTML/DOM structure, and it doesn't require adding any markup, and it doesn't require any changes to the markup or the DOM.

I still would be OK with it if the CSS WG would require CSS users to create and declare and bind a name for each respective grid. (And I strongly suspect that that's what the CSS WG will do anyways).

SelenIT commented 6 years ago

you could use any type of selector, eg class names you mentioned

I considered a component case where class names are dynamically generated by the component code, so I wouldn't know them in advance (but would have some control over the CSS inside the components). In this case, the selector-based approach would be too limiting for me.

Every CSS implementation supports selectors

But not as property values (except that very limited and still mostly theoretical ID-only case of nav-up etc. mentioned by @tabatkins). CSS has a very limited set of value types it can interpret. Extending this set is not so easy as it might seem.

it's better not being required to write a line that's not necessary

Agree, but there are valid cases where I strongly feel it is necessary. Also, the ability to name grids was already requested as a separate feature. If, e.g., the syntax ends up with something lilke .my-element { display: grid(my-super-grid), grid(another-grid); } (and comma-separated set of grid declarations following the pattern of multiple background values), then naming the exact grid becomes necessary and wouldn't require extra line in the same time. Maybe ideally we could have both options at some point? :)

tobireif commented 6 years ago

I considered a component case where class names are dynamically generated by the component code, so I wouldn't know them in advance (but would have some control over the CSS inside the components). In this case, the selector-based approach would be too limiting for me.

In your code examples you're using selectors when applying the name(s), thus there is no difference regarding the aspects you list. In both cases you'd point at the grid element using a selector (in your examples you point at the grid element using a selector, where you name it). And when a future feature requires naming it can (and should) require naming.

then naming the exact grid becomes necessary

(Sorry for the repetition:) When a future feature requires naming it can (and should) require naming.

Maybe ideally we could have both options at some point? :)

Yes, I also had considered this. Allow grid-item-of: selector(.the-grid), and also offer grid-name: the-grid & grid-item-of: the-grid so that naming can be used where necessary. But think it's more important to get the fundamental functionality of the feature, and to get it specd and implemented in the sooner-than-later future. This requires that the feature wish stays lean. So I'd suggest to have either selectors or naming for pointing to the respective grid, not both. I could live with either option.

SelenIT commented 6 years ago

you're using selectors when applying the name(s)

Yes, but I dont control these selectors nor know them — they are generated and encapsulated in the component's code. So one component doesn't know (and shouldn't know) another component's selector(s). But there can be common CSS things that components share (theming variables etc.), and the name of the common Grid can be one of these things.

it's more important to get the fundamental functionality of the feature, and to get it specd and implemented in the sooner-than-later future.

True! 💯

tobireif commented 6 years ago

I hope that grid-item-of will get added to Grid 3.

tobireif commented 6 years ago

What do the CSS WG and the editors of the Grid specs think about adding grid-item-of to Grid 3?

tobireif commented 5 years ago

Perhaps grid-item-of could get added to the agenda?

SebastianZ commented 5 years ago

For the ones that are for using regions for this use case, how would you imaging this to work exactly? Can you provide an example?

If CSS Regions is not revived for this use case, it still needs to be clarified what happens when the value of grid-item-of applies to more than one element. Would the element be duplicated? Or would there be some algorithm to place it in only one of them?

Sebastian

tobireif commented 5 years ago

... regions ...

Sorry, regions are out of scope for this here issue. (Discussion regarding any Regions-related issues/wishes can take place in separate/new tickets.)

And yes, Regions should get revived.

what happens when the value of grid-item-of applies to more than one element

Two aspects:

.any_selector.pointing_to_the_grid {
  display: grid;
  /* Any additional normal Grid stuff here: */
  grid-template-columns: repeat(2, auto);
}
.any_selector.pointing_to_the_elements {
  grid-item-of: .any_selector.pointing_to_the_grid;
  /* The elements get auto-placed in the grid as if it were appended as grid child. */
  /* Optional: Where to place them in the Grid: */
  grid-row: 1;
  grid-column: 2;
  /* Any additional Grid item properties here. */
}

The elements get auto-placed in the grid as if they were appended as grid children.

If there's code below "Optional: Where to place them in the Grid:", then they get placed in that same place and do overlap - which might may well be intended by the CSS author. But typically the CSS author would use grid-item-of for one element (plus placement code such as grid-row & grid-column). There also could be syntax for applying grid-item-of to multiple elements and placing each one differently, but that might become a bit complex. It'd be simpler to do grid-item-of plus optional placement code (eg grid-row & grid-column) for each of the multiple elements (and for a spec to support only that).

What happens if the value of grid-item-of points to more than one grid? It'd be an error. The feature wish is to be able to add an element to a grid although the element is not a child of that grid element. The element can not get added to two grids. One way of handling that error would be to add it to the first of the referenced grids (in document order).

SelenIT commented 5 years ago

One way of handling that error would be to add it to the first of the referenced grids

I'd say that this solution would be perfectly in line with the general logic of the Grid layout, similarly to how multiple grid lines with the same name are handled (e.g. named-line defaults to named-line 1). With the explicitly named grids, the same behavior could be reused for the grids themselves. E.g., if there are two grid instances named my-super-grid, setting simply grid-item-of: my-super-grid would attach the element to the first of them, while grid-item-of: my-super-grid 2 would attach it to the second one.

SebastianZ commented 5 years ago

... regions ...

Sorry, regions are out of scope for this here issue. (Discussion regarding any Regions-related issues/wishes can take place in separate/new tickets.)

I also don't think that regions are the solution for this, but I wanted the advocates of that solution to explain how they imagine regions can help here.

One way of handling that error would be to add it to the first of the referenced grids (in document order).

That's the most obvious solution. I also believe the element should only be applied to one grid. Duplicating it would probably not be possible or quickly have too big effects on the performance if there are many grids.

Sebastian

tobireif commented 4 years ago

I hope that this ticket will get considered for the next version of CSS Grid.

ByteEater-pl commented 4 years ago

How about a name CSS property and extending the syntax of selectors in property values and APIs (but not rules) with a sigil or functional notation for name selectors? Would that satisfy both of you, @SelenIT and @tobireif?

tobireif commented 4 years ago

@ByteEater-pl Can you provide a (complete) code example?

ByteEater-pl commented 4 years ago
#foo {
    name: my-grid;
}
#bar {
    display-as-grid-item-of: named(my-grid); /* or $my-grid or my-grid! or `my-grid` or something */
}
#baz {
    display-as-grid-item-of: #foo; /* same result as above */
}

but this is prohibited (or just matches nothing in this context?):

named(my-grid) { /* declarations */ }
SelenIT commented 4 years ago

@ByteEater-pl doesn't this proposal basically repeat the @tobireif's idea to allow both CSS selectors and explicit naming for referencing the grid container from this comment?

I completely agree with @tobireif that the most important thing is to get the functionality of the feature implemented, so I could live with either option, too. My guess is that explicit naming might be easier to implement (and have some extra benefits for generated components that I outlined above), but I might be wrong here.

ByteEater-pl commented 4 years ago

It's similar, but there are 2 differences: • My name applied to all elements (and possibly pseudo-elements); grid-name's very name suggests it's designed only for grids. • Instead of wrapping selectors in selector(), I propose marking the name reference and simply including it in the syntax of selectors. So e.g. this would work:

display-as-grid-item-of: .my-component:focus-within named(my-grid)
tobireif commented 4 years ago

I simply need a way for saying "display this element as part of this grid" (or eg as part of a Flexbox-list) - any way.

This would work fine: display-as-item-of: selector(#any_selector_pointing_to_the_grid); (no need to declare names, no need to extend the CSS-selectors syntax)

Having a mechanism other than the above (which uses existing CSS-selectors syntax inside the parens) is not necessary IMHO. If you and others see the need for such alternative (or additional) mechanisms, please feel free to continue to discuss their details - but my requirements would be satisfied by the above example, thus I don't need any other mechanism, thus I'll stay out of discussing their details 😀

tobireif commented 4 years ago

(oops, sorry, I had posted a comment on the wrong page, deleted)

ByteEater-pl commented 4 years ago

Actually after writing or imagining some complex selectors with named() I now think it'd be better as a pseudo-class.

SelenIT commented 4 years ago

I simply need a way for saying "display this element as part of this grid" (or eg as part of a Flexbox-list) - any way.

I completely agree with this and would be happy with any concrete syntax that will be possible to implement in shortest time. So I'd leave bikeshedding the syntax up to implementers. Does anyone know how we could draw more implementers' attention to this issue? Maybe it's worth to create the similar issue in the WICG repository?

SebastianZ commented 4 years ago

There was already the idea of generalizing it. So without thinking in terms of Grid or Flexbox, the request is to display an element as child of another element.

With @tobireif's syntax of using a selector as value this would be

.element {
  child-of: #container-element;
}

And with @SelenIT's / @ByteEater-pl's syntax of defining names for elements and using them as reference this would be

#container-element {
  name: container;
}

.element {
  child-of: container;
}

Sebastian

JoshuaLindquist commented 4 years ago

I think this idea is likely to raise major accessibility concerns. The ability to reorder content within a single grid can already cause problems. This suggestion says we should be able to take any item from any grid (or perhaps even from outside all grids) and place it into any other grid. The potential for completely destroying the usefulness of the markup seems rather high.

I also agree that this is not the same as Regions.

I have an alternative syntax to suggest, though it admittedly would not work for Flexbox. Grid already has syntax for naming lines and areas. Instead of declaring child-of, could we not just name the grid itself in a similar fashion and then target a specific grid using grid-column, grid-row, and grid-area?

For example:

#container {
     display: grid[my-grid];
}

#element {
     grid-column: [my-grid] 2 / 3;
}

If using the naming on the display property doesn't work, then perhaps using grid-area to name the grid would be better?

#container {
     display: grid;
     grid-area: my-grid; /* my-grid is now the name of the entire grid */
}

That also introduces a potential conflict if "my-grid" is already a grid item of a different grid that has a named grid area that is also called "my-grid". There would have to be a decision of which area is the true "my-grid" and which one is thrown away.