Skip to content

[css-grid] Allow naming grid rows and columns and allow a grid item to span named grid areas/rows/columns... #4892

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

Closed
rchrdnsh opened this issue Mar 21, 2020 · 10 comments

Comments

@rchrdnsh
Copy link

I would love to be able to place a grid item across multiple named grid areas, and to also name grid-rows and columns and place items across multiple ones of those as well.

It would be really nice to be able to name grid-areas, like so:

grid-template-areas:
"A1     A2     A3     A4     A5"
"B1     B2     B3     B4     B5"
"C1     C2     C3     C4     C5"

...then I could place an item like so:

gird-area: B2 / C4;

...and this would place the item in B2, B3, B4 and also C2, C3 and C4.

This would be amazing for building something like a musical note sequencer where one could define a midi note name and musical timing grid like so:

grid-template-areas:
"D1-1.1     D1-1.2     D1-1.3     D1-1.4     D1-2.1     D1-2.2     D1-2.3     D1-2.4"
"C#1-1.1    C#1-1.2    C#1-1.3    C#1-1.4    C#1-2.1    C#1-2.2    C#1-2.3    C#1-2.4"
"C1-1.1     C1-1.2     C1-1.3     C1-1.4     C1-2.1     C1-2.2     C1-2.3     C1-2.4"

...and then place a note across multiple named grid areas. like so:

grid-area: C1-1.2 / C1-2.1;

Or better yet, simple name rows and columns, like so:

grid-template-columns: 1fr('1.1') 1fr('1.2') 1fr('1.3') 1fr('1.4') 1fr('2.1') 1fr('2.2') 1fr('2.3') 1fr('2.4')";
grid-template-rows:
"
1fr('D#/Eb1')
1fr('D1')
1fr('C#/Db1')
1fr('C1')
"

...then one could place an item using both and spanning multiple of each one, like so:

grid-row: 'C1';
grid-column: '1.1' / '1.3';

...or something along those lines. This could be really nice for these kinds of use-cases where one wants to place an item on an intricate grid in a very precise way without having to count every line and make sure the lines are right. I could imagine a scenario where the grid has hundreds of columns and over a hundred rows...I really don't want to have to figure out where:

grid-column: 134 / 146;

...is on that grid! ahhhh!

Anyway, just dropping these questions/ideas off for now...will come back and work on them more later if the general concept is well received :-)

Thank you! XD

@Loirooriol
Copy link
Contributor

Loirooriol commented Mar 21, 2020

grid-area: B2 / C4;

...and this would place the item in B2, B3, B4 and also C2, C3 and C4.

This syntax already exists, and means something else. It expands to

grid-row: B2 / B2;
grid-column: C4 / C4;

that is, it refers to the B4 area.

Changing the meaning could break sites, and wouldn't add much benefit since you can already achieve your desired behavior with

grid-area: B2 / B2 / C4 / C4;

which means

grid-row: B2 / C4;
grid-column: B2 / C4;

@Loirooriol
Copy link
Contributor

Or better yet, simple name rows and columns

Well, that's already kind of possible, you just need to specify *-start and *-end. And the line names must be <custom-ident>.

grid-template-columns: [
  \31\.1-start] 1fr [\31\.1-end
  \31\.2-start] 1fr [\31\.2-end
  \31\.3-start] 1fr [\31\.3-end
  \31\.4-start] 1fr [\31\.4-end
  \31\.1-start] 1fr [\31\.1-end
  \32\.2-start] 1fr [\32\.2-end
  \32\.3-start] 1fr [\32\.3-end
  \32\.4-start] 1fr [\32\.4-end];
grid-template-rows: [
  D\#\/Eb1-start] 1fr [D\#\/Eb1-end
  D1-start]       1fr [D1-end
  C\#\/Db1-start] 1fr [C\#\/Db1-end
  C1-start]       1fr [C1-end];

And then

grid-row: C1;
grid-column: \31\.1 / \31\.3;

@tabatkins
Copy link
Member

Rather than escaping numbers, the obvious thing would just swap those an ident ^_^ s1_1 instead of 1.1, for example.

But yeah, between using grid-template-areas to name the cells and then using the cellnames, and naming lines with foo-start and foo-end to implicitly define a foo area, you've already got all the functionality requested here.

@rchrdnsh
Copy link
Author

I don't understand how your example works, but it seems to work for me...hard to understand for me, personally, however. I associate the / symbol with using grid-lines, but since this is for grid-area, I don't see how lines are associated conceptually.

maybe something like this for spanning multiple grid-areas?

grid-area: B2 - C4;

...as writing everything twice feels rather odd and unintuitive, at least to me. But also it makes sense that I am specifying using the / because the property is 'grid-area' so i would naturally understand that this syntax would mean from one area to another area. But since it's at least possible, then it's not as big a deal to me.

As for your second example showing how to name grid rows and columns, I must admit that I don't follow it at all. Are there any resources that explain this in more detail?

@Loirooriol
Copy link
Contributor

If / confuses you then you can expand all the way to the longhands:

grid-area: B2 / C4;
/* equivalent to */
grid-row-start: B2;
grid-row-end: B2;
grid-column-start: C4;
grid-column-end: C4;
grid-area: B2 / B2 / C4 / C4;
/* equivalent to */
grid-row-start: B2;
grid-row-end: C4;
grid-column-start: B2;
grid-column-end: C4;

as writing everything twice feels rather odd and unintuitive

You need to write it twice because there are 2 axes.

Are there any resources that explain this in more detail?

These are the relevant sections in the spec:

@rchrdnsh
Copy link
Author

trying to read through the doc, but I'm having a hard time understanding this:

\31\.1-start] 1fr [\31\.1-end

what is the \ for? What does that do? also, why is there a 3 on every line? What is that for? And there are no square brackets at the beginning and end of each column definition?

Could I write it like this?

grid-template-columns:
  [1_1-start] 1fr [1_1-end]
  [1_2-start] 1fr [1_2-end]
;

...for each line? Is there anything about that that wouldn't work?

@Loirooriol
Copy link
Contributor

what is the \ for? What does that do?

It escapes the value so that it becomes a valid <custom-ident>. See https://drafts.csswg.org/css-syntax-3/#escaping

why is there a 3 on every line?

Because the character 0 is U+0030, 1 is U+0031, and so on.

And there are no square brackets at the beginning and end of each column definition?

The brackets are there. I just inserted a newline inside <line-names> in order to align a *-start with its matching *-end in each line. Looked better to me.

Could I write it like this?

No, a <custom-ident> cannot start with a digit, https://drafts.csswg.org/css-syntax-3/#ident-token-diagram
And no, you can't have two contiguous <line-names>, you should merge them together.

But you could do this:

grid-template-columns: [_1_1-start] 1fr [_1_1-end _1_2-start] 1fr [_1_2-end];

@rchrdnsh
Copy link
Author

rchrdnsh commented Apr 7, 2020

hmmm...but what is U+0030 and what does it mean? Like, why does it even exist? Is it because I cannot start the name of a grid line with a number? And why not? Or....I dunno...some other reason...? Trying to wrap my head around these railroad diagrams but I am admittedly waaaaay in over my head here...

sooo...maybe I'm starting to get the idea of how this naming system works, albeit very bizarre and convoluted, at least to me...so maybe like this?:

grid-template-columns:
  [
  _1_1-start] 1fr [_1_1-end
  _1_2-start] 1fr [_1_2-end
  _1_3-start] 1fr [_1_3-end
  .........moar uv dem.........
  _2_4-start] 1fr [_2_4-end
  ];

grid-template-rows: [
  D\#\/Eb1-start] 1fr [D\#\/Eb1-end
  D1-start]       1fr [D1-end
  C\#\/Db1-start] 1fr [C\#\/Db1-end
  C1-start]       1fr [C1-end];

...but ideally, I would want the API of a note definition to look like this for the end user of the component:

<Note name='C#1' start='1.2' length='1/4' velocity='95' offset='+24' />

...so how could I go about transforming this monstrosity: D\#\/Eb1-start into this: D#1 so that the end user or the API would never have to write or see something so strange and unnatural (honestly, only being slightly cheeky here...this has been making my head spin for a minute)...

@Loirooriol
Copy link
Contributor

what is U+0030

That's the code that represents the digit zero in Unicode, https://unicode.org/cldr/utility/character.jsp?a=0030

how could I go about transforming this monstrosity: D\#\/Eb1-start into this: D#1

You don't. You transform your API-exposed D#1 into the desired internal value instead. In JS you have CSS.escape.

Though it would be easier to use C-sharp-1 instead. Or if you liked Unicode, C♯1, with a proper U+266F music sharp sign instead of a U+0023 number sign #. Unicode beyond ASCII looks neater but it's more difficult to type and more likely to break if some program messes with the encoding.

Also, it seems that with C#/Db1 you want to match both C#1 and Db1. You should actually separate that into two lines:

grid-template-rows: [C♯1-start D♭1-start] 1fr [C♯1-end D♭1-end]

@tabatkins
Copy link
Member

Oriol was using the exact names you used, and had to use escapes to write them; in reality you'd just change the way you write them so that they're a valid ident to start with, as I did in my previous comment (s1_1 instead of 1.1).

The line names have to be CSS idents, which have some basic rules about how they can be written; the big one is that they must start with a letter, underscore, or dash (or a non-ASCII character); in particularly, if a value starts with an ASCII digit, it's instead parsed as a CSS number or dimension.

If you do, for whatever reason, need to start an ident with a digit or other disallowed character, you can do so by escaping it, as Oriol did, by giving its unicode codepoint in hexadecimal. As he said, the digit "0" has codepoint U+0030, so you can write it in CSS as \30. But that's advanced and weird usage that has no place being in a normal stylesheet, so don't worry about it. ^_^

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants