WordPress / gutenberg

The Block Editor project for WordPress and beyond. Plugin is available from the official repository.
https://wordpress.org/gutenberg/
Other
10.47k stars 4.18k forks source link

Columns Block: Improve readability on smaller screens #30480

Open dashkevych opened 3 years ago

dashkevych commented 3 years ago

Since the Columns block no longer provides a class with information about number of columns, I am wondering what would be a recommended way to control the Columns block with various number of columns in smaller screens.

The thing is that a grid with three, four, five or six columns might look good on large screens; however, on smaller screens the grid becomes unreadable.

Example

Here is an example of various grids on large screens:

The Columns block on large screens

If we view these Columns blocks on iPad PRO (12.9inch), we can see that some grids (with five and six, and even four columns) become unreadable due to a limited space inside the columns.

The Columns block on iPad Pro screens

If we open the same layout even on a smaller screen, for example iPad PRO (10.5inch), the layout becomes worse:

The Columns block on iPad Pro screens

Question

What is a recommended way to control the width of columns in a grid based on the number of columns in it and the screen resolution?

CreativeDive commented 3 years ago

@dashkevych this is a very good optimization request. I think that should be revised urgently, because the correct breaking of many columns does not work for smaller screens.

aristath commented 3 years ago

This is a pretty tricky topic... In the example above anything above 3 columns IMO doesn't look good. But that's a combination of too many factors! If columns didn't have a padding (or if the theme just defined a small padding) then 4 columns would probably be acceptable to me too. If the font-size was 10px, then 5 columns would be acceptable too. You could for example in your theme do something like .wp-block-column{min-width:12em}, in which case columns would have a minimum width of 12 characters and they would then collapse to a line below.

Or you could get fancier and convert columns from flex to grid with something like this:

/**
 * Filters the content of a single block.
 *
 * Takes care of the "grid-template-columns" property for columns
 * so we can properly use a css-grid layout instead of css-flexbox.
 *
 * @access public
 * @param string $block_content The block content about to be appended.
 * @param array  $block         The full block, including name and attributes.
 * @return string               Returns $block_content with our modifications.
 */
function aristath_convert_columns_to_grid( $block_content, $block ) {
    if ( 'core/columns' === $block['blockName'] ) {
        $grid_template_columns = [];

        $min_column_width = '7em';
        foreach ( $block['innerBlocks'] as $column ) {
            $column_width = "minmax({$min_column_width}, 1fr)";
            if ( isset( $column['attrs'] ) && isset( $column['attrs']['width'] ) ) {
                $column_width = "minmax({$min_column_width}, {$column['attrs']['width']})";
                if ( is_numeric( $column['attrs']['width'] ) ) {
                    $column_width = "minmax({$min_column_width}, {$column['attrs']['width']}fr)";
                }
            }
            $grid_template_columns[] = $column_width;
        }

        $style = 'grid-template-columns:' . implode( ' ', $grid_template_columns ) . ';';

        // If all columns are equal, use "repeat".
        if ( 1 === count( array_unique( $grid_template_columns ) ) ) {
            $style = "grid-template-columns: repeat(auto-fill, {$grid_template_columns[0]});";
        }

        $block_content = str_replace(
            'class="wp-block-columns',
            'style="' . $style . '" class="wp-block-columns',
            $block_content
        );
    }
    return $block_content;
}

add_filter( 'render_block', 'aristath_convert_columns_to_grid', 10, 2 );

but that would require more tweaks in the theme's styles to accommodate the new styles, remove margins and replace them with a grid-gap, add display:grid to .wp-block-columns, and lots of other styles.

At the end of the day, it all depends on your theme's styles... Gutenberg provides some sane defaults, but that's all. If a user adds 6 columns, then they are expected to add content in them that makes sense in 6 columns.

kjellr commented 3 years ago

Building on @aristath's comment, I think the most reasonable solution here is going to be to allow for some sort of minmax() values per column. Perhaps that'll be possible in tandem with the CSS grid work that is happening over in https://github.com/WordPress/gutenberg/pull/32137.

kohheepeace commented 2 years ago

Hi, I just want to share my solutions about this issues.

Background

Sometimes, UI that "scrolls horizontally on mobile" may be preferable to “stack on mobile”.

example: https://buildui.com/

2022-10-02 02 20 14

Proof of concept

Let me share my solution for using "Pricing Table".

https://wordpress.org/patterns/pattern/pricing-table/

Before

MobileTabletDesktop
Screen Shot 2022-10-02 at 2 42 42
Screen Shot 2022-10-02 at 2 40 43
 
2022-10-02 02 20 14

After

MobileTabletDesktop
2022-10-02 03 24 29
2022-10-02 03 22 37
Screen Shot 2022-10-02 at 3 20 44

Solution

  1. Set Each Column width 317px. (👈 This value will vary depending on your requirements but px is recommended.)

Screen Shot 2022-10-02 at 3 26 23

2. Add style.css

.wp-block-columns.is-not-stacked-on-mobile {
    overflow-x: auto;
}

.wp-block-columns.is-not-stacked-on-mobile>.wp-block-column {
    box-sizing: border-box; /* 👈 this is not necessary but it is easy to check width in chrome dev tools */
    flex-shrink: 0;
}

Pros of this solution


**Updated Solution I have noticed the following cases as problems with this solution ### ❌ CASE1: (each column width*3 + gap) < wide width(1000px) Screen Shot 2022-10-02 at 11 18 12 Each Column width: `250px` - Bad layout - ⚠️ Using `justify-content: center` break Tablet and Mobile layout. ### 🤔 CASE2: (each column width*3 + gap) > wide width(1000px) ![2022-10-02 11 21 36](https://user-images.githubusercontent.com/29557494/193435111-7f80af06-37d8-4ddd-89a9-24b398accc06.gif) Each Column width: `400px` - This is okay - **But scrollable in Desktop is not perfect.** ### ✅ CASE3: (each column width*3 + gap) == wide width(1000px) Screen Shot 2022-10-02 at 11 35 37 Each Column width: `320px` + gap `20px` => This is perfect without scroll in desktop. wide width(`1000px`) == each column (`320px`) *3 + gap (20px)*2 Screen Shot 2022-10-02 at 11 36 25 ## Cons of this solution - Requires some tedious calculations - Not support layouts like below image (Desktop: 3 columns * 2 rows, Mobile: Horizontal scrollable). Screen Shot 2022-10-02 at 11 50 05 This is exactly what @aristath pointed out. > If a user adds 6 columns, then they are expected to add content in them that makes sense in 6 columns. Thanks.