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] grid area as element #4416

Open
chvndb opened this issue Oct 12, 2019 · 11 comments
Open

[css-grid] grid area as element #4416

chvndb opened this issue Oct 12, 2019 · 11 comments
Labels
css-grid-3 Masonry Layout

Comments

@chvndb
Copy link

chvndb commented Oct 12, 2019

I love the idea of grid areas to place items. They reduce the need for layout wrapper elements that have no semantic meaning. However, I still require wrapper elements for nested layouts, e.g. a dynamic flex layout inside a grid cell.

I would love to be able to target a grid area and use and style it just like a wrapper element. I don't know if this is feasible at all, but this would (in most cases) completely eliminate the need for any layout wrapper elements.

As an example markup:

<div class="grid">
  <div class="header">...</div>
  <div class="menu">...</div>
  <div class="footer">...</div>
  <div class="content">...</div>
  <div class="content">...</div>
  <div class="content">...</div>
  <div class="content">...</div>
</div>

The css:

.grid {
  display: grid;
  grid-template-columns: auto 1fr;
  grid-template-rows: auto 1fr auto;
  grid-template-areas:
    'header  content'
    'menu    content'
    'footer  content';
}

.grid:grid-area(content) {
  display: flex;
  flex-wrap: wrap;
  outline: 1px solid black;
}

.header {
  grid-area: header;
}

.menu {
  grid-area: menu;
}

.content {
  grid-area: content;
}

.footer {
  grid-area: footer;
}

As a result, the DOM structure is completely flattened and only contains actual content. The css completely controls the layout, including the nested dynamic flow of the .content items.

Using the (suggested) accessor :grid-area, the items within this area are placed using a flex flow and wrapped when needed. It would then also be possible to style the area even further as shown with the black border.

Again, I do not know if this is even technically possible with the current implementation of grid, but, to me, this looks like the missing link to combine the power of grid and flexbox.

[edit: updated css suggested selector to :grid-area]

@WebMechanic
Copy link

WebMechanic commented Oct 12, 2019

Love it :)

@chvndb Again, I do not know if this even technically possible [...]

Being able to also use decoration properties such as backgrounds and borders for virtual grid area (elements) should be interesting and would also reduce wrapper polution.

My guess is it could be "technically possible" to insert a virtual "grid area element" just like display:table-cell implicitely creates a virtual table element to contain it that also appears in the accessibility tree and display:contents doing the opposite.
However, this virtual table element is not stylable as well (afaik), i.e. there's no parent element selector (yet) or some :table() pseudo-class to travel up the (shadow?) tree.

Your proposed syntax using .grid[area='content'] is already taken by the attribute selector and would match any "physical" element such as <foo area="content">.

[EDIT: updated code examples to use gird-area() instead initial misnomer grid-item() ]
Off the top of my head I'd suggest some variation of :grid-item() gird-area()

/* a.) any [implicit] grid area in any grid ~  beggars' "grid inspector" */
:grid-area() { outline:1px solid purple }
/* b.) grid-area "ads" in a .sidebar */
.sidebar:grid-area(ads) { border:.5ex solid gray }
/* c.) area spanning the specified tracks: row-start / row-end / col-start / col-end  */
.mygrid:grid-area( 1 / span 2 / content-start / -1) { box-shadow:0 0 4px 2px darkgray}

Using <integer>, <custom-ident> and span would be in line with grid-area, grid-row and grid-column. If combined with other pseudo-classes magic things could happen.

.board {display:grid; align-items:center }
/* checkerboard pattern on implicit grid areas */
.board:grid-area():nth-child(even) { background:white }
.board:grid-area():nth-child(odd) { background:black }
:grid-area():last-child { /* target the "-1" of the implicit grid? */ }

Dealing with gaps/gutters might be challenging as well as defining inheritance to and from these areas or formatting contexts, directionality ... dragons!

Maybe something along box-sizing:gutter-box|track-box|item-box could help determine whether to span or skip over the gaps to draw backgrounds or borders and to compute the size of the specified area for sth. like display:flex.

my 2.5ct

[edit: updated code examples to use gird-area() instead initial misnomer grid-item()]

@chvndb
Copy link
Author

chvndb commented Oct 14, 2019

As your suggestions only allow to target the items within a grid or grid area, I would then also add selectors to target the areas themselves:

/* d.) any grid area */
:grid-area() { ... }
/* e.) specific grid area */
:grid-area(areaname) { ... }

@Loirooriol
Copy link
Contributor

Grid areas only form the containing block in which grid items are sized. But it doesn't establish a formatting context nor anything, the grid items still participate in the grid formatting context established by the grid container.

It seems you want the items to participate in both the grid formatting context of the grid container, and in the flex formatting context of an anonymous flex container. This seems potentially conflictive.

Wouldn't it be easier to just use the following?

<div class="grid">
  <div class="header">...</div>
  <div class="menu">...</div>
  <div class="footer">...</div>
  <div class="content">
    <div>...</div>
    <div>...</div>
    <div>...</div>
    <div>...</div>
  </div>
</div>
.content {
  grid-area: content;
  display: flex;
}

Regarding things like :grid-item() or :flex-item(), they are not possible because they would introduce circularities, see #4097.

@fantasai
Copy link
Collaborator

I think this is a duplicate of #499

@fantasai fantasai added css-grid-3 Masonry Layout and removed css-grid-1 labels Oct 14, 2019
@WebMechanic
Copy link

WebMechanic commented Oct 19, 2019

@chvndb you're right and that's what I originally had in mind but I totally mixed up the terms "grid items" and "grid areas" :)
The thrown-in :flex-items() in the context of styling "areas" of a flexbox wouldn't apply for there's no such thing as an area -- yet, see below.

FWIW, I'd be happy to target grid areas to apply decorative styles like bg-colors, backdrops and borders. This would then indeed be similar to what @jensimmons proposed and @tabatkins then suggested in #499 as kindly referred to by @fantasai.
I don't have an opinion on Jen's variation using/reviving @region, although this could be "extended" to include other layout methods.
https://speakerdeck.com/jensimmons/proposal-to-csswg-sept-2016 (slides 26+)

[EDIT] removed flexbox related examples :flex-[inline|block]-area() and 'horizontal column-rule'.

@SebastianZ
Copy link
Contributor

simulate some sort of horizontal column-rule.

A proper way to create rules inside the gaps is discussed in #2748.

Sebastian

@chvndb
Copy link
Author

chvndb commented Oct 20, 2019

@fantasai indeed that does seem very similar as long as it also addresses the flow of items in the area. I missed that topic when looking through the issues.

@WebMechanic maybe you are diverging too much from the original question I posted. My suggestion implies a clear distinction between the parent grid flow and the grid-area flow. It would then be possible to have a different flow within an area that is "disconnected" from the parent grid. My example used a flex layout, but this could as easily been an absolute positioning (top, left, right, bottom) of items within the grid area. This is very different from you suggestion:

One could think of the "areas" we get from flexbox are the additional rows/colums created when using flex-wrap: wrap.

How I understand your suggestion is that you are trying to look at the flow within the area as a continuation of the flow of the parent grid. That makes it much more complicated and creates many ambiguities in how to interpret what should happen or what to expect.

@Loirooriol That is exactly what I am trying to avoid as using wrapper elements restricts us when dealing with many different styling and layouting scenario's. As an example I could say that I only want the first three content items to appear in a more prominent place on top of my layout (e.g. a main-content grid area) when having less screen real estate and have the remaining content items appear in a secondary and smaller place at the bottom right next to other footer content that requires more scrolling to go through (e.g. a secondary-content grid area). The main content area could simple be a sub-grid while the secondary content area a flex layout.

This becomes very difficult (or even impossible) when using wrapper elements as all content items are bound together by markup instead of semantics.

@WebMechanic
Copy link

@chvndb I didn't mean to highjack this. I got your initial point and was just suggesting additional decorative abilities that'd become available if grid areas, named or defined numerically, would become "tangible". After all the browser knows where they are and how big they are, so why not throw some color at it? :)
Throwing flexbox into the mix was probably a tad too much/abstract. I removed the example code regarding flexbox and the rows OR columns we get from it, which had nothing to do with "the flow of the parent grid".

@ByteEater-pl
Copy link

ByteEater-pl commented Feb 19, 2020

I remember a length unit in some old draft which equals 1 for each subsequent track and gap with partial overlap counted proportionally to the track's or gap's dimension. If I'm not mistaken, it wasn't progressed due to circularity concerns. Now that those are better understood, as well as use cases, and there's a solid foundation of already specced stuff, perhaps it's time to pick that up and define where it can be used?

@SebastianZ
Copy link
Contributor

This may also be a duplicate of #1183. And in that issue there are other issues linked which cover the same use case.

Sebastian

@chvndb
Copy link
Author

chvndb commented Jun 12, 2024

@SebastianZ The original question in the issue is not the same imho, but the answer from @benface (#1183 (comment)) is indeed more in line with what I proposed.

Off course, it should not be limited to being able to specify the flow in a grid area, but also be able to style it as any other element, e.g. to give it a border or a shadow.

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

6 participants