-
Notifications
You must be signed in to change notification settings - Fork 683
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] Property "grid-item-of": display any element as part of any given grid #2530
Comments
This is similar what's suggested in Eric Meyer's example: Which is linked from https://codepen.io/rachelandrew/project/full/68cc7a5da9cfbb56c6e8366d7d92e6ba/XWYGMD/ (via #2280 (comment)). |
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
plus this
would make #bar appear in the grid #foo, as grid item of grid #foo, as if the markup would have been
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. |
The example I linked, dunno why it only works if linked from @rachelandrew's codepen) is the one called Inner alignment. #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. |
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.) 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
But the syntax Is there a ticket for that other feature/syntax? We should cross-link them. |
This functionality would be a really useful addition to Grid. |
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. |
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 (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 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...) |
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. |
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_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 And yes, Regions should also get finished 😀 |
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
I hope that the new functionality will get added to Grid 😀 |
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:
|
Thanks for you input!
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
You could use any selector 😀and you could easily avoid using IDs.
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
|
@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. |
Not technically true, but at least there it's limited to ID selectors. That said, I still agree that declaring names manually is better. |
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. |
No, Chrome killed it by declaring they weren’t interested in implementing it. |
That's not an argument against it 😀 Having a selector as value looks unfamiliar, but that's not an issue.
Every CSS implementation supports CSS selectors. By the way, the quotes probably aren't necessary:
When naming a grid you're always binding it to an element, right? ... to which you point using a CSS 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
... 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. |
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.
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! |
My point here was that the same element can match different CSS selectors in different moments of time (e.g.
Mine too. That's why I'm for the syntax that would be (probably) easier and faster to implement! :) |
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?
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. |
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
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.
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! :) |
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. |
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.
|
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:
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™. |
When you'd use
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.
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.)
I think that 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 |
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 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.
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:(
Yes! 👍 |
No, you could use any type of selector, eg class names you mentioned.
When you apply the name, you're using a selector:
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.
Every CSS implementation supports selectors - they don't have to wait for Houdini.
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
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). |
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.
But not as property values (except that very limited and still mostly theoretical ID-only case of
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 |
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.
(Sorry for the repetition:) When a future feature requires naming it can (and should) require naming.
Yes, I also had considered this. Allow |
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.
True! 💯 |
I hope that |
What do the CSS WG and the editors of the Grid specs think about adding |
Perhaps |
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 Sebastian |
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.
Two aspects:
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 What happens if the value of |
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. |
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.
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 |
I hope that this ticket will get considered for the next version of CSS Grid. |
@ByteEater-pl Can you provide a (complete) code example? |
#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 */ } |
@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. |
It's similar, but there are 2 differences: display-as-grid-item-of: .my-component:focus-within named(my-grid) |
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: 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 😀 |
(oops, sorry, I had posted a comment on the wrong page, deleted) |
Actually after writing or imagining some complex selectors with |
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? |
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 |
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 For example:
If using the naming on the
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. |
I like it, @JoshuaLindquist! Assuming it doesn’t create compatibility problems with Level 1, that is. |
Note that displaying an element as part of any given grid was the initial intention of this issue.
As far as I can see, this is not much different to my more general proposal with the difference that it restricts the repositioning to grid layouts. But this approach has a big downside. It forces to use a specific display type in order to reposition the elements. This will potentially be abused by authors which will declare an element to be a grid just in order to be able to lay out an element as an item of it. So, in the end authors can achieve the same effect like in the more general idea but in a rather hacky way. Also, from your example it is not clear but from your concern about the markup I guess you meant that Sebastian |
Ah, and what I forgot to say was that Sebastian |
It would be great to get some kind of solution for displaying any element as part of any given grid. |
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:
Update: A more complete example:
The text was updated successfully, but these errors were encountered: