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

Designing a Core CSS Grid Block for Intrinsic Design #49084

Open
robglidden opened this issue Mar 15, 2023 · 10 comments
Open

Designing a Core CSS Grid Block for Intrinsic Design #49084

robglidden opened this issue Mar 15, 2023 · 10 comments
Labels
[Feature] Design Tools Tools that impact the appearance of blocks both to expand the number of tools and improve the experi Needs Design Feedback Needs general design feedback. [Type] Enhancement A suggestion for improvement.

Comments

@robglidden
Copy link

What problem does this address?

In recent releases, WordPress has increasingly embraced intrisic design as a fundamental modern styling methodology.

And since the term was coined, CSS Grid has been a central tool of intrinsic design.

The CSS Grid Layout Module offers a grid-based layout system with rows and columns, enabling an endless variety of layouts beyond its simpler cousin, Flexbox.

Nearly all modern CMSs have adopted CSS grid in some form.

Numerous Gutenberg issues have explored the topic of grids from several angles:

But a recurring challenge has been to design a user interface that copes with the versatility and complexity of the CSS grid properties.

A CSS grid block design needs to:

  • fit the needs of both WordPress users and designers
  • not over-simplify and constrain CSS grid options to the point of limited usefulness

A start-simple approach postpones the UI design issues down the road and constrains the real power of CSS grid, which is in the interplay of its 10 basic properties:

  • grid-template-columns/rows/areas
  • grid-auto-columns/rows/flow
  • row/column-gap
  • grid-column/row

A fully-functional CSS grid block needs to consider 3 potentially conflicting use flows:

  • Using: A CSS grid block should be quick and easy to use, like the row block but with more layout options, without learning CSS grid.
  • Designing: Designers need access to all the CSS grid properties, including column, row, and area templates. CSS grid design involves some level of CSS knowledge.
  • Sharing/locking: Pattern, site and theme builders need to share grid layout designs in a way that it is easy for users to select and configure, but also lockable so that pre-built designs are used as intended.

A core design question is whether it is necessary, or feasible, to design an "ultimate CSS grid user interface" that is both easy for users without CSS knowledge and flexible enough for designers to access all of CSS grid's power.

Or perhaps multiple user interfaces on top of the css grid properties might be more tailorable to particular uses.

What is your proposed solution?

Here is a proof-of-concept CSS grid block that fully implements CSS grid and addresses the use flows of using, designing, and sharing/locking.

For users, it is easy to use, like a row block with more layout options:

css-grid-block

There is a design panel for designers to make and save grid layouts for users to use:

css-grid-design-panel

Sharing/locking:

  • Designers can create, name, save, and share layouts inside a specific block instance.
  • Designers can customize the UI of a specific block to show only their pre-defined layouts, turn off standard layouts, or hide the Design panel.
  • The Design panel can be turned off when locking is set on the grid block. There is an "enableDesignMode" block property.

Note that the css grid block works with the Query Loop block -- just put a Query Loop inside it and set the flag.

The block supports per-instance custom CSS, to enable advanced uses like different template areas at breakpoints. The placeholder ".wp-grid-name-class" is auto-replaced with the actual name of the grid block instance.

Possible refinements:

  • auto-name each grid with hashing or other technique
  • provide slots to add additional UIs for grid selection and design, like a classic 12-column grid
  • Add a lock to the locking modal for grid blocks to directly disable design mode
  • add a field for free-form names in the template-areas property, beyond single letters
  • simplify the underlying CSS, particularly for the editor view, when the :has() pseudo-class is more widely deployed. This would allow removing the flag for enabling an inner Query Loop.
  • further isolate grids in a server-rendered web component, perhaps when declarative Shadow DOM is more widely deployed
  • provide an instance-specific custom Javascript field, to facilitate designing and sharing interactive grids

Hopefully, a proof of concept of a fully functional css grid block will inspire more consideration of how to extend WordPress's intrinsic design capabilities.

@Thelmachido Thelmachido added [Type] Enhancement A suggestion for improvement. Needs Design Feedback Needs general design feedback. [Feature] Design Tools Tools that impact the appearance of blocks both to expand the number of tools and improve the experi labels Mar 15, 2023
@annezazu
Copy link
Contributor

Thanks so much for opening this issue and putting so much effort into sharing a possible idea. As you noted, there are a few related issues. In particular, I want to cross connect to this issue: #42385 It would be really awesome to consolidate these if possible but I'll leave that to @WordPress/gutenberg-design to know what's best!

@jasmussen
Copy link
Contributor

jasmussen commented Mar 15, 2023

Indeed, there's a PR working on this in #49018, I shared some thoughts relevant to this issue in this comment.

Edit: I see you've already discovered that PR. My comments on that PR are still relevant. I also want to note that #47809 is another avenue on this issue, which links two further. I wonder if we should consolidate issues, so the conversation doesn't get spread across 4 issues?

@robglidden
Copy link
Author

@annezazu and @jasmussen thanks for referencing these related issues. As I understand it, these are potentially complementary but different approaches.

#47809 and #49018, if I understand correctly, are exploring a start-simple approach to grid, asking in essence:

What's the simplest yet useful first version UI of a grid that could be later extended?

They only consider grid-template-columns and not areas and other grid properties, and purposely postpone the UI design issues of a full CSS grid implementation and constrain the full power of CSS grid.

This issue takes a different enable-the-power-of-grid approach:

Assuming the full power of CSS grid as the starting point rather than an eventual destination (that is, all the basic CSS grid properties), what UI(s) on top would best enable user, designer, and sharing/locking use flows?

There are several reasons to fully examine the UI implications of a full-powered CSS grid at the onset rather than down the road:

  • In some simple forms, a CSS grid is a lot like the existing row and column blocks, which already do their jobs well. Focusing on what grid can do fundamentally better and differently requires looking beyond that use case.
  • A simple css grid design can seem a lot like CSS flexbox, but the usefulness and power of grid only show up in more sophisticated grid layouts.
  • Designing a grid and using a grid may not be best achieved in the same user interface.
  • A narrowly envisioned grid use case may be compelling for a particular design, but the point of CSS grid is to enable a very wide range of possible designs. The Web standards process has already deeply considered this in specifying and rolling out CSS grid, so why not leverage that platform-level capability.
  • Template areas are a compelling tool for building patterns and sites.
  • Sharing and locking grids raises issues beyond those of a group block.

In essence, the modern Web has given us the powerful design tool of CSS grid. Let's use it!

#42385 and the follow on #48070 as I understand it are about bringing consistency to layout, like the dimensions panel, which applies to grid too and is included in the proof of concept block.

@annezazu
Copy link
Contributor

Tagging in @tellthemachines who has thought a lot about this from a developer perspective as more food for thought!

@jasmussen
Copy link
Contributor

Sorry I meant to link #47809 (comment), which summarizes my reasoning for why it's best to start simple. That's mainly my opinion, of course, and is mainly a thought on how we approach it, not something that precludes additional properties and UIs.

@robglidden
Copy link
Author

@jasmussen, I found that #47809 (comment) extremely insightful. I returned to it several times in building the poc block.

The key to me is "start with the smallest feasible step that can be useful on its own". "step", not "UI".

I framed this: what is the minimum viable solid foundation which would support all future grid layouts and UIs? Even if there were no UI at all?

In implementation terms, what block attributes implement the Grid Module spec and would always reliably underly any grid layout or UI?

Removing short-hand properties, the full Grid Module spec is 10 basic properties:

grid-template-columns/rows/areas
grid-auto-columns/rows/flow
row/column-gap
grid-column/row

These 10 properties work together, not separately, and have defaults. How to express as block attributes?

  • 5 are text attributes (the 3 templates and auto-columns/rows)
  • 1, grid-auto-flow, is an enum
  • 2, row/column-gap, are like gap for which block UI is well-understood

That leaves grid-column/row, technically properties on children of the grid, like flexbox also has child properties.

The poc adopts the single alphabetical letter naming convention. It is versatile, adequate, and maps intuitively to the WordPress inner block architecture. A possible refinement would be a list of free-form names or values, which some grid layout designs may favor.

By aligning to the Grid Module, we have a solid foundation on which grid work can reliably move forward, while being forwardly compatible with upcoming enhancements like masonry and subgrid.

The "minimumColumnWidth" attribute used in PR #49018 is not a Grid Module spec, and not a foundation for further grid work, although it may be a useful configuration value for a very particular grid variant (in that case grid-template-columns: repeat(auto-fill, minmax(20rem, 1fr));).

I note that Chris Coyer of CSS Tricks in 2019 discussed this same "most famous line of code to have come out of CSS grid so far" and recommended the refinement grid-template-columns: repeat(auto-fill, minmax(min(10rem, 100%), 1fr));

The next step on a solid foundation is to consider the use flows of use, design, and sharing/locking, which the poc block then explores.

@jasmussen
Copy link
Contributor

Thanks for all that context. I've had some busy days and have been unable to go very deep on this lately. And this particular effort definitely needs going deep, as it's clear you know.

The poc adopts the single alphabetical letter naming convention. It is versatile, adequate, and maps intuitively to the WordPress inner block architecture. A possible refinement would be a list of free-form names or values, which some grid layout designs may favor.

That all sounds good to me, honestly. On top of the challenge it is to fully understand the inner workings of CSS grid, the two that concern me the most are:

  • How can we strike a balance between surfacing grid-spec options for power-users, while ensuring it's intuitive enough that anyone could pick it up by just tinkering with properties in the inspector?
  • How can we roll that out in a way that can slowly prove itself, while not painting ourselves into a corner by either going too deep on the spec, or too far from the spec?

Some technical debt is likely impossible to avoid as we figure things out, but ultimately it boils down to finding a way to grow, while starting with the properties we have the highest confidence in.

The "minimumColumnWidth" attribute used in PR #49018 is not a Grid Module spec, and not a foundation for further grid work, although it may be a useful configuration value for a very particular grid variant (in that case grid-template-columns: repeat(auto-fill, minmax(20rem, 1fr));).

That sounds like it'd be good feedback on the PR.

@robglidden
Copy link
Author

Great questions.

How can we strike a balance between surfacing grid-spec options for power-users, while ensuring it's intuitive enough that anyone could pick it up by just tinkering with properties in the inspector?

A few ways the poc block takes:

  • separate the user interfaces of "use mode" from "design mode". Power-user features are separated into a design panel, which can be turned off in the block settings menu
  • simple click-the-icon grid layouts for users to pick, and that can be extended and changed over time without block-attribute level technical debt
  • a "show grid" setting that shows the grid areas and names in the editor
  • Slotfills for UI extensions - PluginGridUserPanel and PluginGridDesignerPanel
  • For tinkering and learning, make it easy to just click a grid layout, then look at the generated css in the Design panel.
  • Make it low-risk to toggle between grid layouts, since you can always go back to the previous layout by clicking it again.
  • Make it easy and low risk to create a new layout -- click a preset layout, tinker with it in the design panel, give a name and save it.

How can we roll that out in a way that can slowly prove itself, while not painting ourselves into a corner by either going too deep on the spec, or too far from the spec?

A couple of ways the poc block takes:

  • Start with a strong foundation: the CSS Grid Module spec as the block attributes
  • Make the block usable even without any UI at all, like in a theme pattern or template, with a solid, complete set of block attributes from the start.

Some technical debt is likely impossible to avoid as we figure things out, but ultimately it boils down to finding a way to grow, while starting with the properties we have the highest confidence in.

  • high confidence attributes would be those that map most directly to the Grid Module spec -- they will be stable over time
  • low confidence -- those that are UI-oriented or tied to a particular grid layout use case

So keep preset layouts, preferred variants, first-pass and UI settings out of the block attributes, and only write the generated css properties to the block attributes. Then new presets, new UIs, and new slotfills can be introduced and old ones removed without the block attribute level technical debt.

@tellthemachines
Copy link
Contributor

Thanks for all your work on this @robglidden !

The approach that makes the most sense given the existing layout architecture in Core is to add "grid" as another layout type. Apart from API consistency, there's the emerging need for a grid layout type that can be used to solve layout problems in existing blocks, such as Post Template (see #44557) and possibly Columns, if it can be leveraged to improve the block's current responsive behaviour.

As a consequence, my work in #49018 attempts to lay the groundwork for this approach, adding "grid" as a new layout type and defining a minimal API that can be gradually built upon with further features. The API deliberately doesn't reflect the CSS grid spec; it is an abstraction that exposes functionality in a hopefully intuitive way. Its implementation shouldn't matter to consumers; it should hypothetically be possible to switch grid out with a completely different system that produces the same result, if it becomes necessary to do so at some point in the future.

@robglidden
Copy link
Author

Thanks @tellthemachines for distilling the complementary nature of these topics. Hope to early-adopt is-layout-grid or whatever makes sense.

To help folks get up to speed and not lose the thread though already touched from multiple angles here and in #47809:

The approach that makes the most sense given the existing layout architecture in Core is to add "grid" as another layout type.

Yes, a well-designed grid layout type would be welcome for many existing and future blocks. Columns, Post Template, grid-ish variants of the Row, Stack or Group blocks to name a few, as well as a grid block.

It may help folks following this to explicitly state, a "grid layout type" and a "grid block" are two different things. Think a new .is-layout-grid CSS class, which many block types in addition to a grid block would hopefully use. A particular block's block attributes are also different, which is why multiple blocks can use the simpler .is-layout-flex class, even though it is "a limited subset of what is possible with Flexbox".

In the meantime, you may have noticed the poc grid block uses a workaround -- obviously a grid layout type isn't yet available -- but also:

Any specific thoughts on early adoption of an .is-layout-grid to a full-featured grid block given these constraints would be quite helpful.

Apart from API consistency, there's the emerging need for a grid layout type that can be used to solve layout problems in existing blocks, such as Post Template (see #44557) and possibly Columns, if it can be leveraged to improve the block's current responsive behaviour.

Yes. And CSS grid works great with media queries as mentioned before. Intrinsic and responsive design paradigms are complements not competitors.

As a consequence, my work in #49018 attempts to lay the groundwork for this approach, adding "grid" as a new layout type and defining a minimal API that can be gradually built upon with further features.

The minimal API and its relation to a full-featured block is noted in this comment to #49018.

BTW Chris Coyer's "most famous line of code to have come out of CSS grid so far" was also implemented in the poc grid block as one of the click-the-icon switchable grid layouts, to avoid block attribute technical debt. Could also inform a slotfill in the UI.

The API deliberately doesn't reflect the CSS grid spec; it is an abstraction that exposes functionality in a hopefully intuitive way.

Yes, I hope it is clear the different use flows of a full-featured grid block.

Its implementation shouldn't matter to consumers; it should hypothetically be possible to switch grid out with a completely different system that produces the same result, if it becomes necessary to do so at some point in the future.

Yes, as applicable to multiple block types.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
[Feature] Design Tools Tools that impact the appearance of blocks both to expand the number of tools and improve the experi Needs Design Feedback Needs general design feedback. [Type] Enhancement A suggestion for improvement.
Projects
None yet
Development

No branches or pull requests

5 participants