Open tabatkins opened 7 years ago
The slides from the presentation I just gave are at: https://speakerdeck.com/jensimmons/proposal-to-csswg-sept-2016
And actually, the syntax above is not what I proposed. This is what I proposed:
@region #grid-container foobar {
grid: 3 / 1 / 4 / 2;
}
foobar {
background: yellow;
}
If a pseudo-element solves this use case then why not allow multiple ::before/::after instead?
#grid-container::before(1) {
grid: 3 / 1 / 4 / 2;
background: yellow;
}
#grid-container::before(2) { ... }
etc
which would be useful for all elements, not just grid.
@jensimmons The syntax Tab proposes here fits better into the CSS model, imho. Though I can see the case for wanting to have a name for the thing.
@MatsPalmgren Multiple pseudo-elements are a bit more problematic wrt cascading usability imho. It's easy to lose track of some and then have weird stuff appearing in your document or have styling pulled in from some rule that you have neglected to overrde. Tying it to grid and limiting it this way makes it easier to clear out and avoid such problems.
This seems like a merging of @apply
and CSS being able to pierce the shadow DOM. I agree that the author should be able to style area boxes, but I'm not entirely sure we should be solve this problem specifically focused on grid. I think it would be best, and I know we've tried and failed, to provide a generalized solution for styling boxes that exist but don't have an element associated with them that is targetable via general selectors.
I believe that having a grid-specific way to style grid area boxes would be useful. Grid areas differ from other virtual/dynamic CSS boxes (like line boxes, column boxes in multicolumn layout etc.) because they 1) definitely exist regardless there is any content associated with them, 2) have clear mechanism to address them (by name, line numbers etc.) and 3) clear algorithm to calculate their size. Essentially we can use the same logic as for placing a ::before
pseudo under the hood, though the syntax proposed by Tab looks less 'hacky' to me (what we usually want is to style the "virtual container" itself, not to place something there just to emulate this, which looks more like a workaround if there is no more direct way to do it). But pesonally I would be happy with multiple pseudos either.
Use case: a designer / developer / designoper is able to create a grid overlay which would act as design reference. Applying it using CSS could be as suggested in @tabatkins opening comment, a pseudo-element but with super Grid powers. This benefit of an overlay can then be gained by:
Otherwise grid alignment, and understanding the possible variations using a grid, is essentially 'by eye'. Other than being able to imagine the structure of a grid layout, or refer to a piece of paper with a grid drawn out on it whilst working, there inevitably needs to be a way to display a grid of this kind.
It would be also very cool if I could use Firefox's grid inspector to enable the view of this reference grid and allow me to use it in a way similar to how I have created my crude example here: https://interiorsystem.co.uk/ — toggle the overlay. Also if using Firefox you'll be able to see there is a difference between the grid of what is inspected and the reference, which is used to apply the design to.
Inspected grid
Note that when you inspect an implicit grid the cells fit the content.
Design reference
This example is agnostic of whether a grid is implicit or not.
This idea is not new, there are reference books which teach the use of grid layout, I haven't seen a single book that doesn't show a grid overlay as part of the process. Screen shots from a PDF on the book Grid Systems in Graphic Design written by: Josef Müller-Brockmann to demonstrate.
I have used grid on 3 websites and have need to selectively apply borders based on the row/column the item is in (e.g. border-bottom but not on items in the bottom row).
You can see an example here: https://www.nature.com/nplants/
In both cases I used overflow: hidden. It worked well but feels hacky. Any potential solution for that? e.g. ability to select elements by the column or row they are in? Using current nth-child solutions can get very complicated!
Hi @jensimmons ! I love the idea! It tackles a lot of current problems. I am currently writing a longer comment about the implications for paged media and it's relations to flexbox, grid and multicolumn-layouts. But before i can finish it, I would like to understand your proposal a little bit better.
In your presentation on slide 38 you use the grid
property to place an grid-element in its grid-container. Is this new? Or did you meant grid-area
?
Using my current grasp of grids, I would write something like this:
#grid-container{
grid: repeat(3, 1fr) / repeat(3, 1fr);
}
@region #grid-container foobar {
grid-area: 3 / 1 / 4 / 2;
}
foobar {
background: yellow;
}
@region #grid-container foobar {
grid-area: left;
}
@region #grid-container left {
grid-column: 1 2;
}
How does your proposal relate to grid-template-areas
?
It feels to me like a second mechanism to name them. With the added bonus, that this way named areas could overlap.
Would something like this work:
@region #grid-container foobar {
grid-area: 3 / 1 / 4 / 2;
}
.childelement {
grid-area: foobar
}
Though then I would suggest @area
or @template-area
for the keyword.
I am concerned about this part:
foobar {
background: yellow;
}
Simple element-selector syntax for a named grid-area seems dangerous to me.
Because changes in the HTML-Spec might introduce elements that are identically named to areas named by CSS-authors and break the page. I guess that's the reason, why we have the two dashed at the beginning of css-custom properties.
Maybe a Pseudo-Selector, At-Rule or something similar to the custom-property syntax would work better.
I like the close alignment to the @keyframes
syntax. But I am not sure about it. Keyframe Animations are quite global – a bit like custom-properties. Grid-Areas on the other hand are tightly bound to the Grid Container itself.
Can you point me to additional resources, where I can learn the formal definitions and differences between these mechanisms. Especially the formal difference between pseudo-selectors and at-rules are quite foggy to me at the moment.
Article on CSS Tricks where the author is coming up with ways to add borders between cells, adding as another example of developers needing to do this https://css-tricks.com/techniques-for-a-newspaper-layout-with-css-grid-and-border-lines-between-elements
As far as I understand it, this issue is rather about styling the the cells and areas, it's not meant for placing borders between them. Styling the grid gaps is covered in #2748.
Sebastian
Referencing the original proposal in https://github.com/w3c/csswg-drafts/issues/499#issue-177797864 here's a few details we'd want to specify:
::grid-area()
pseudo-element takes the same values as the grid-area
property, minus auto-placement values::grid-area()
arguments can also use nth-child syntax in place of <integer>
. For example, ::grid-area( 1 / 2n / 3 / span 2 )
represents any grid area spanning the first and third row lines that starts on an even column line and spans two tracks.::grid-area()
with arguments that reference the same area have the same identity::grid-area()
without arguments matches every grid-area pseudo-elementcontent
, except grid-placement propertiescontent
causes it to exist or not exist, same as ::before
grid-auto-flow
Process-wise, I think it’s OK to continue discussing all of the details above in this issue. But we should not need to resolve all of the details before deciding to take this feature up. A good outcome for this issue is to decide to start work on what we have managed to agree on here, and open new separate issues for remaining details.
Since there are use cases for both grid-areas that take up space in the placement algo and those that do not, perhaps declaring the pseudo-element would cause it to exist, and content
could trigger whether the placement algo notices it?
::grid-area() arguments can also use nth-child syntax in place of
<integer>
If we go this way, I think there should be a way to specify multiple conditions. For example, I can use :nth-child(2n+4):nth-child(-2n+18)
to select a range of children (even indices between 4 and 18, inclusive). This kind of things don't seem possible with the proposed ::grid-area
content
causes it to exist or not exist, same as ::before
So, if I get it right, ::grid-area
doesn't actually style grid areas. Instead, it creates anonymous grid items in a certain grid area with the specified content
?
What happens with things like ::grid-area(1 / 1 / 1 / 1)
? Is it no-op (empty area)? Does it create a grid item in the area 1 / 1 / 2 / 2
like in https://drafts.csswg.org/css-grid/#grid-placement-errors ?
The CSS Working Group just discussed Decorative grid-cell pseudo-elements
, and agreed to the following:
RESOLVED: jensimmons and rachelandrew to write up use cases, examples, and syntax for this proposal
@fantasai
* `::grid-area()` pseudo-element takes the same values as the `grid-area` property, minus auto-placement values
What are the reasons auto-placement is disallowed?
* `::grid-area()` arguments can also use nth-child syntax in place of `<integer>`.
n
is ambiguous since it's also a valid line name.
* `::grid-area()` with arguments that reference the same area have the same identity
That's good, but web developers have expressed a need for multiple pseudos (#6169 etc). The additional effort to implement that is negligible, so I'm sad that use case isn't addressed. E.g. something like ::grid-area(ident-1, 1 / 2n / 3 / span 2) {...}
::grid-area(ident-2, 1 / 2n / 3 / span 2) {...}
would create two separate pseudos in the same area(s).
* `::grid-area()` without arguments matches every grid-area pseudo-element
Presumably with lower specificity?
Does ::grid-area() { content:""; }
by itself create a pseudo? If so, what's its area?
* a grid-area pseudo takes up space for the purposes of the auto-placement algorithm the same as any other item
That seems like a big mistake to me. I think most use cases would be better served if decorative pseudos don't mess with the grid layout at all. I think this should be optional, and the default should be that ::grid-area
pseudos don't take up space in the grid (i.e. regular grid items are "placed on top" of the decorative items).
I think it would be useful to have a property for this, something like grid-fill: auto | none | fill
, that can be used on non-pseudo grid items too (this has already been requested by web developers). Then you can make some child elements "decorative" with grid-fill: none
and not be constrained to what can be produced with content
. (auto
would resolve to none
for grid-area pseudos, and to fill
for regular grid items).
* box order defined as a child before everything in the grid (including ::before/::marker/etc.)
That seems like an odd order to me. Is there a reason you want that order?
::marker, ::before, ::grid-area pseudos, children, ::after
seems more natural to me. They should at least come after the grid container's ::marker (note that grid containers don't support ::marker yet though).
I don't understand how this proposal can be implemented though. Specifically, the nth-child syntax when combined with "a grid-area pseudo takes up space" seems like it could easily create an infinite number of pseudos. A pseudo that takes up space may create new tracks in the grid, i.e. new grid areas, creating a circular dependency. It would be great if you could explain what stops that from happening. (I need detailed and ordered steps of when to create the pseudo in relation to, and how it interacts with, establishing the implicit grid and the grid item placement steps.)
(A pseudo that doesn't take up space doesn't have that problem since it's constrained to only match the grid tracks created by other items that does.)
@Loirooriol
So, if I get it right, ::grid-area doesn't actually style grid areas. Instead, it creates anonymous grid items in a certain grid area with the specified content?
That's exactly how I think this should be specced and implemented too. We already have specs and implementations for that, and authors already have an understanding of it, that we should leverage. It's also much more powerful than just doing some extra background painting. The only thing that's special here (IMO) is the pseudo selector and how that maps to, and interacts with the formation of, the grid. We should focus on solving that.
However, these anonymous grid items should be auto-placed independently of "natural" grid items (including those created from text nodes and ::before
/::after
), right? If auto-placement algorithm will consider grid areas with these new pseudos as "occupied" and authors will need to explicitly specify the grid area in order to overlap them, it seems to contradict the main idea of this proposal...
Right, that's why I suggest they don't make grid areas occupied by default. I think it should be decoupled from being a ::grid-area
pseudo though, with a grid-fill
property or some such, to give the author the flexibility of opting in/out from that for any item.
One way of achieving that might be to do two separate placement runs. So first we run the whole grid item placement algo with the grid-fill:fill
items to place those. Then you run it again with a new (initially empty) matrix of "occupied" bits with the grid-fill:none
items. So it's basically two independent grids as far as placement is concerned. I'd like to hear why fantasai explicitly excluded auto-placed pseudos first though...
@fantasai
::grid-area()
arguments can also use nth-child syntax in place of<integer>
.
So each n
in ::grid-area(n/n/n/n)
is an independently resolved variable?
We probably want some clamping/limits on this to avoid creating O(n^4) pseudos... ;-)
"That seems like a big mistake to me. I think most use cases would be better served if decorative pseudos don't mess with the grid layout at all. I think this should be optional, and the default should be that ::grid-area pseudos don't take up space in the grid (i.e. regular grid items are "placed on top" of the decorative items)."
Agreeing with this thought. If we think it is useful for them optionally to take up space, then that would be a nice addition, but I feel the default should be purely decorative. I think that's what people will expect.
I think the most important part of this new pseudo is to be able to conveniently address the actual grid areas in a grid layout. To do that we need a way to address the implicit grid rather than the explicit grid. I think this is crucial for decorative items, because implicit tracks (typically rows) are prevalent on the web. This suggests to me that we should probably solve #2402 before designing this feature. (Granted, the nth
syntax covers some of that need, but I think authors still need a way to address the first and last lines of the implicit grid.)
I think the ::grid-area
pseudo-element syntax feels natural to me, with the parameter for an area name or grid offsets being optional, and I agree with the others above that those pseudo-elements should be painted underneath any content in a grid.
That seems like it should allow authors to trivially create a grid and fill all its cells with placeholder fills, corner radii, hover states, etc. to allow selection of a grid cell interactively without having to manually create placeholder elements to fill each cell, with more specific styles for named areas or specific cells if so chosen.
@jensimmons proposes adding a grid-cell pseudo so you can add (responsive) decorative elements to grids without having to add empty elements to your page.
Syntax like:
Also some way of controlling whether or not that takes up auto-flow space. Might want to reserve space or not. Can we base this on 'content' or something? Or do we need a new property?