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-template-width and grid-template-height #9182

Open
oscarotero opened this issue Aug 11, 2023 · 4 comments
Open

[css-grid] grid-template-width and grid-template-height #9182

oscarotero opened this issue Aug 11, 2023 · 4 comments
Labels
css-grid-3 Masonry Layout

Comments

@oscarotero
Copy link

oscarotero commented Aug 11, 2023

The total size of the grid template depends on different things. For example, if all columns have fixed sizes, the template grid is the sum of all columns:

.grid {
  display: grid;
  grid-template-columns: 250px 250px; /* This creates a template 500px wide */
}

If some columns use fr units, the grid will take all available space, so the total width is the same as the element width:

.grid {
  display: grid;
  width: 500px;
  grid-template-columns: repeat(2, 1fr); /* This creates a template with the same width as the .grid element (500px) */
}

Sometimes we want to create a flexible grid, using fr values, but without taking all available space. Let's see the following example:

imaxe

This is a website where the content takes a maximum width of 1400px. To create this grid, we need two elements, one for the green background and other to distribute the elements:

<style>
.background {
  background-color: #00BD79;
}
.grid {
  max-width: 1400px;
  margin: auto;
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(400px, 1fr));
  gap: 20px;
}
</style>

<div class="background">
  <div class="grid">
    <!-- grid elements here -->
  </div>
</div>

It would be great if this could be done with only one element using the new property grid-template-width to limit the total width of the grid:

<style>
.grid {
  background-color: #00BD79;
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(400px, 1fr));
  grid-template-width: min(100%, 1400px); /* Limit the grid total width */
  justify-content: center;  /* To center the grid in the element */
  gap: 20px;
}
</style>

<div class="grid">
    <!-- grid elements here -->
</div>

The grid-template-height property would have the same behavior but applied to the height of the grid.
This new property will be ignored if there's a conflict with the values of grid-template-columns, or grid-template-rows. For example:

.grid {
  display: grid;
  grid-template-columns: 500px 500px; /* The template width is 1000px */
  grid-template-width: 800px /* The template width remains 1000px because it's not possible to shrink the two 500px wide columns */
}
@fantasai fantasai added the css-grid-3 Masonry Layout label Aug 11, 2023
@fantasai fantasai changed the title [feature-request] grid-template-width and grid-template-height [css-grid] grid-template-width and grid-template-height Aug 11, 2023
@Loirooriol
Copy link
Contributor

#9325 allows clamping the number of repetitions, but it wouldn't help here since 1fr would still resolve using the entire element.

I don't like your proposal because it's grid-specific, but a similar thing could be wanted in e.g. flex or block.

Also, the "will be ignored if there's a conflict with the values of grid-template-columns/rows" isn't much well defined, e.g. grid-template-columns: 1fr would typically grow to fill the provided grid-template-width and avoid conflicts, but there could be an item that forces the track to become bigger.

I think the right solution is #2406:

<style>
.grid {
  background-color: #00BD79;
}
.grid::contents {
  max-width: 1400px;
  margin: auto;
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(400px, 1fr));
  gap: 20px;
}
</style>
<div class="grid">
    <!-- grid elements here -->
</div>

@oscarotero
Copy link
Author

oscarotero commented Mar 25, 2024

::contents pseudo element looks great but there are some overlaping features like margin:auto and justify-content.

grid-template-columns: 1fr would typically grow to fill the provided grid-template-width and avoid conflicts, but there could be an item that forces the track to become bigger.

I can see this problem with ::contents too, because you can define a width or max-width conflicting with the template width (or the element width itself). For example:

.element {
  width: 300px;
}
.element::contents {
  display: block;
  width: 400px;
}

I think a new single property with a good definition and narrow scope is better than creating a new element with limitless combinations.

I don't like your proposal because it's grid-specific, but a similar thing could be wanted in e.g. flex or block.

That's fair. Maybe changing the name to be more generic? For example content-width or content-auto-width (to indicate that this width has only effects to elements when elements with auto widths are present ( like flex-grow, fr, etc).

@Loirooriol
Copy link
Contributor

I can see this problem with ::contents too

Sure, but it's not a problem, because it's an entirely independent (pseudo-)element, so everything is well defined it allows controlling the behavior separately. The problem with grid-template-width being different than the sum of the columns is that then it's not clear if e.g. justify-content: center will align the grid-template-width within the element, or the columns within the grid-template-width.

I think a new single property with a good definition and narrow scope is better than creating a new element with limitless combinations.

On the opposite, I think that a property that would probably require duplicating lots of the existing ones (like having a variant of justify-content that aligns the grid-template-width, and another variant that aligns the columns) isn't actually simpler after all.

@oscarotero
Copy link
Author

The problem with grid-template-width being different than the sum of the columns is that then it's not clear if e.g. justify-content: center will align the grid-template-width within the element, or the columns within the grid-template-width.

This is not a problem because grid-template-width is not an element that can be aligned. It's just a property to indicate how much fr/flex items should grow.

For example:

.item {
  display: grid;
  grid-template-columns: 300px;
  justify-content: center;
}

is exactly like:

.item {
  display: grid;
  grid-template-columns: 1fr;
  grid-template-width: 300px;
  justify-content: center;
}

In both cases, justify-content has the same behavior, because grid-template-width doesn't change the Node tree inserting new elements. It just affects to the final widths of fr columns in the grid template.

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

No branches or pull requests

3 participants