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

Row block + Column block (Columns block overhaul/replacement idea) #6461

Closed
ZebulanStanphill opened this issue Apr 27, 2018 · 5 comments
Closed

Comments

@ZebulanStanphill
Copy link
Member

ZebulanStanphill commented Apr 27, 2018

Issue Overview

The current Columns block is pretty limited, lacking many options you would expect for making complex layouts. Additionally, there is no way to make each individual column have its own size and style.

I propose that the Columns block be overhauled to work like so:

There are 2 blocks: Row, and Column. These replace the existing Columns block.

The Row block could have background and padding options as well, but its main feature lies in how blocks are inserted into it. Notably, the Row block inserts blocks in a left-to-right-with-wrap style. The direction of child blocks will be left-to-right, wrapping (like words in a paragraph) when the total width of the Column blocks exceeds the width of the Row block.

The Row block would only allow 1 block type to be inserted: the Column block (which could not be inserted anywhere else).

The Column block is a block that represents a single column. Minor features may include its own background and padding options.

However, the main feature of this block is the ability to change its width, either directly using drag handles, a number input and slider, or some preset options for common sizes like 1/4 and 1/3. These width options are done Bootstrap style, meaning you can set multiple widths for different breakpoints, with values applying to the specified minimum breakpoint and wider, up until the next specified breakpoint width (if defined).

If I set the width of the column to 75% at a "small" breakpoint and 25% at the "extra large" breakpoint, the width will be 75% at not only the "small" breakpoint but also the "medium" and "large" breakpoints. Breakpoints below the smallest one set, like for an "extra small" breakpoint, would default to being whatever width they would be by default in a flexbox container... because the Row block would be a flexbox container. In most cases, this default width will simply be the same width as other Column blocks in the same Row whose width are not specified. (Note that the breakpoint names here are just examples and there could be a different number of standard breakpoints defined.)

Users could also be able to set a custom breakpoint width for a Column. Note that all breakpoint widths, both standard and custom, are based on the viewport width in pixels. It should also be noted that Column blocks could be given default values to optimize them for responsive design, e.g. making Column blocks be 100% width at the smallest breakpoint by default since that is almost always desired in responsive design.

Columns would default to using percentage-based widths, but users could set px-based widths for one or all of the breakpoints for a Column if they wanted to.

The columns system would work such that if the combined width of adjacent Column blocks is wider than the width of the Row they are in (e.g. 50% + 60% or 200px + 600px in a Row that is currently 500px at the current viewport width ), then the overflowing Column blocks will simply wrap by moving below the other Column blocks in the Row, pretty much just like words in a pararaph. Column blocks can not be wider than the content width of the Row they are in, since their maximum width would be 100% of the content width of the Row.

The Column block would allow any kind of blocks to be inserted into it, including Section and Row blocks, allowing for more advanced nested column structures. Blocks would be inserted vertically just like the standard behavior (unlike the horizontal-with-wrapping layout of the Row block).

The use of blocks for each Column makes handling individual column widths a lot more intuitive and easy to separate from the settings that apply to the containing Row. This system should allow for almost every row-columns layout to be possible using core Gutenberg blocks, being as powerful (or more) than the column/row/section systems of the various page builder plugins.

For ease-of-use, the Row block could use a placeholder UI that allows for quickly inserting common templates of Column combinations with preset breakpoint widths that fit the majority of responsive design situations, with an option to start with a blank template (AKA no template) and instead just insert the Column blocks manually one-by-one for more control.

I would like to note that this Row and Column block idea would fit alongside the proposed Section block in #4900. I imagine the Section block as featuring background options (preferably not just single colors but also gradients and also images), padding options, and width options to make the section be the standard content width or full-width. There would actually be 2 width options: block/background width, and block content width. This is because making the Section block itself be full-width but having the content width (AKA the maximum width that can be taken up by nested Row blocks) be the normal width is often the desired effect for layouts.

The Section block could contain any block, and could be used for grouping Row blocks (which would often have differing column widths in them, like a Row containing 1/3 Column blocks and a Row containing 1/4 Column blocks) together under a single background color or image, or for nesting Paragraph blocks and other basic blocks directly in cases where a background is desired for multiple blocks but no column layouts are required.

This Row and Column block idea (alongside the proposed Section block of #4900, but I will get to that later) is designed to tackle basically every thing that page builder plugins can do with their sections, rows, and modules (or whatever they are called in each builder), but with the strengths of the Gutenberg block system.

Currently, Gutenberg seems to be leaning towards a system like what Divi currently has. Divi uses "sections", "rows" (with columns built-in), and "modules". These translate directly to the proposed Section block in #4900, the current Columns block, and individual blocks respectively. What I am proposing is an enhanced system that is a bit more like Beaver Builder, where individual columns exist as their own thing independent of rows.

In the system I am proposing, the layout hierarchy is usually Row->Column->Block, but can also be Section->Row->Column->Block (for layouts with multiple rows of columns that should be separate, but still inside the same background) or Section->Block (for simple layouts with no sense of columns). The advantage of having separate Column blocks that exist as actual blocks themselves and not a property of Row blocks is that they can be easily moved from one Row to another, and their settings are cleanly separated from those of the Row, so editing is more intuitive as you are not trying to modify multiple columns from a single block. I think this fits with the concept of Gutenberg blocks a lot better than the current Columns block.

However, what this proposal does not try to do is provide an advanced non-column-based CSS Grid layout builder block, like the one proposed in this comment: #5351 (comment)

That kind of layout block is a very cool idea and should definitely be pursued in the future, but I think it belongs as a separate block unrelated to my proposed Row and Column blocks, as its method of layouts is quite different and would involve much different settings.

Well, that was long and complicated. I hope I explained my suggestion clearly enough. What do you think? 😃

Related Issues and/or PRs

#4900
#4902
#5351
#5540
#5935
#6048

@ZebulanStanphill ZebulanStanphill changed the title Section block + Column block (Columns block overhaul/replacement idea) Row block + Column block (Columns block overhaul/replacement idea) Apr 27, 2018
@karmatosed
Copy link
Member

Thanks for this, there are a lot of ideas here so let me go one by one through and try and give you some feedback.

The current Columns block is pretty limited, lacking many options you would expect for making complex layouts. Additionally, there is no way to make each individual column have its own size and style.

This is where layout comes in and I feel is where section is also going to help as a block, over creating rows and columns.

However, the main feature of this block is the ability to change its width, either directly using drag handles, a number input and slider, or some preset options for common sizes like 1/4 and 1/3. These width options are done Bootstrap style, meaning you can set multiple widths for different breakpoints, with values applying to the specified minimum breakpoint and wider, up until the next specified breakpoint width (if defined).

This feels a really complex way. What if we had CSS grid and things just could go any where you put them? Isn't that a simpler method? All of what you mention seems super complex for an end user to work out, I have to admit I spent quite some time pondering myself.

I would like to note that this Row and Column block idea would fit alongside the proposed Section block

I am not sure it does if we stop thinking of section as a single row. With nesting we have that option.

I will leave this issue open so we get some discussion, but this really also needs to go in phase two as this fits with the focus of Customization and layout, over the editor. To that point I am going to cc a few people in to give some insights for you.

@melchoyce, @matias, @jasmussen, would love your feedback here - along with anyone else.

@ZebulanStanphill
Copy link
Member Author

@karmatosed I imagined the breakpoint-specific width working a bit like how the "Responsive Editing Controls work in Divi. See the GIF from this old blog post:
https://www.elegantthemes.com/blog/theme-releases/divi-2-6

The way column drag-handle resizing would work would be kind of like how Beaver Builder works. Try playing around with the demo here: http://demo.wpbeaverbuilder.com/

Notice how there are only rows and columns in Beaver Builder, with the ability to have stacked sets of columns in a single row. In a way, it is like there are multiple virtual rows within the actual thing called a "row". You can also drag an entire column to another spot in the "row". It is really kind of hard to explain. I was not sure how that could be done in the context of Gutenberg, hence the need for a dedicated Row block in my idea, which kind of makes my proposed system into a bit of a combination of how Divi handles layouts and how Beaver Builder handles them with some unique stuff thrown in there.

I would like to note that this Row and Column block idea would fit alongside the proposed Section block

I am not sure it does if we stop thinking of section as a single row. With nesting we have that option.

I initially though just nesting Sections would allow them to function as both rows and the containers of those rows, but my idea for a block where insertion goes from left-to-right and wraps conflicts with that idea, because multiple nested Section blocks would be next to each other horizontally if they were nested in a parent Section block, hence why I went with having a dedicated Row block that would handle the horizontal insertion, and could be nested inside a Section or just put anywhere like in a Column.

Of course, if the columns-as-individual-blocks idea is not used, then there is no need for a block with horizontal-with-wrapping insertion, and therefore no need for a Row block as the Section block would be able to do its job.

However, the main feature of this block is the ability to change its width, either directly using drag handles, a number input and slider, or some preset options for common sizes like 1/4 and 1/3. These width options are done Bootstrap style, meaning you can set multiple widths for different breakpoints, with values applying to the specified minimum breakpoint and wider, up until the next specified breakpoint width (if defined).

This feels a really complex way. What if we had CSS grid and things just could go any where you put them? Isn't that a simpler method? All of what you mention seems super complex for an end user to work out, I have to admit I spent quite some time pondering myself.

So, assuming I understand what you are saying, you are suggesting to just have a Layout block similar to the one proposed by mor10 here? Now that I think about it, that is a pretty good idea. I initially thought that it would be more complex than a row->column system, but thinking about it some more, it could probably actually be a lot simpler and it has the potential to be far more flexible as well.

I also assumed that having the core way of defining layouts would not be based on CSS Grid since IE11 is still being supported and that browser uses an incomplete/old version of CSS Grid, but by the time the layout phase (or whatever its called) is completed, I guess IE11 usage will have dropped down far enough to allow WordPress to stop supporting it. (Seriously, why would anyone willingly use it when Chrome and Firefox both available, and even Edge if you're on Windows 10?)

One important things that would need to be considered with the CSS Grid/Layout block idea, however, is how it works responsively. The standard practice of just making columns go underneath each other by default at mobile breakpoints does not work in the context of CSS Grid due to the more complicated layouts that can be done, where grid locations can be in completely different spots and locations at different breakpoints. If you design a CSS Grid layout for the desktop breakpoint, what happens when you shrink to mobile? Do you design multiple layouts with the same named areas for different breakpoints?

In hindsight, the Grid layout idea, if executed properly, would remove the need for a Row or Column block, and also do something different from every page builder plugin I have tried, but with the ability to do everything that they do and actually far more as well.

I realize now that my idea only works in the context of doing things the traditional way with sections, rows, and columns, but if you go the CSS Grid route it becomes redundant and possibly more complex by comparison I initially thought the CSS Grid idea would be the more complicated one to interact with, but having thought about it some more, it could actually be a lot simpler, especially if good use is made of default template layouts that can be inserted to fulfill common layouts.

Of course, it seems unlikely that the Layout block will make it into 5.0. But the current Columns block is far from satisfactory, and as I stated in #6048, I think Gutenberg should at least have a usable columns system when it is merged into WordPress core. So then the question is, if the Layout idea is the proper approach in the long-term, what should be done in the short-term before the 5.0 release?

Thanks for the feedback, karmatosed. It made me think a bit more about the whole CSS Grid vs traditional rows & columns situation, and I now realize that my idea is far less useful than I thought it was, and that the Layout block idea is probably a better approach. (And the Section block would basically just be the same as what is being proposed right now... a simple container block that could have Layout blocks nested inside of it or be itself nested inside a Layout block or another Section block.)

@ZebulanStanphill
Copy link
Member Author

Thinking about it some more: if a Layout block using CSS Grid is added, would a Columns block even be needed? If the Columns block is not necessary, should it even be included in the merge proposal version of Gutenberg? Right now the Columns block is too limited to be useful, but adding functionality like responsive and uneven-width columns would be kind of pointless in the long run if the block was just going to get removed, and trying to replace it with a CSS Grid-based Layout block would would require a lot of conversions from the old Columns block. It would probably be simpler to just not add a Columns block in the first place in the WordPress 5.0 update.

(Of course, keeping the Columns block during the development phase is useful for testing block nesting, though the Quote and Cover Image blocks are also getting nesting soon, and the Section block would have nesting as well.)

What do you think, @karmatosed?

@chrisvanpatten
Copy link
Member

chrisvanpatten commented May 4, 2018

The current columns block already uses CSS grid and presumably could be iterated to accomplish more use-cases.

(My main issue with the Columns block is that the approach it uses, where each element is placed into a grid-location via a class, is just too fragile and introduces a lot of complexity for fallbacks to old browsers. A simple fix to that would be wrapping each column (or technically each grid location) in a <div>, as proposed in #5935. That's kind of a moot point though and a minor implementation detail, and I think if Columns were a more integral part of the merge proposal those things would be solved… but since it's not, it hasn't gotten a ton of movement. Which is totally fair!)

Thinking into the future…

My concern with columns, especially as it relates to responsiveness, is that there is no one-size fits all approach. I think as Gutenberg shifts toward the Customization focus in the months ahead, that's going to be the fundamental source of tension: what level of control does Gutenberg land on, in the spectrum between decisions and options?

Every site has different needs for breakpoints, every site has different needs for grid structures, etc. Some people may want to use flexbox over CSS grid. Some people may want to restrict clients from being able to control layouts.

I don't necessarily have answers to those questions. I just think it's important to keep in mind that there are as many different use-cases as there are WordPress sites… and simultaneously, building a one-size-fits-all interface, and especially one that isn't overly technical, is hard as h*ck.

@ZebulanStanphill
Copy link
Member Author

Having considered it for a while, I think my original Row block + Column block idea is not the right way to go. A Layout block like the kind shown in #5351 (comment) and/or extending the Columns block is a better solution. The Layout block concept in particular has the potential to be far more flexible while simultaneously being a lot less confusing than my idea, and often involving less block nesting.

Therefore, I am closing this issue, as I no longer consider the original idea worth pursuing compared to the other options available. There is definitely a lot of discussion that should be made over the Layout block concept and/or extending the Columns block, but it probably belongs in other issues.

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

No branches or pull requests

3 participants