Gutenberg: content_width and new block widths

Created on 16 Mar 2018  路  23Comments  路  Source: WordPress/gutenberg

Issue Overview


Most themes ship with the content_width global which controls among other things the width of embedded content. With the ability to change the width of any piece of content _beyond_ what is normally considered the content width, a new best-practice has to be established, or more likely the content_width global has to be reevaluated for this new reality.

Steps to Reproduce (for bugs)


  1. Prepare to set up the content_width global for a theme.
  2. Try to figure out what width you should target: The regular content width, the full width of the content field when something is displayed full-bleed, or something else.
  3. Go to GitHub and leave a response to this ticket.

Expected Behavior



The content_width global defines the max-width of content displayed in any specified scenario.

Current Behavior



Because of the new widths enabled by Gutenberg, it is hard to figure out what width to target: If the 'regular' content width is chosen, embedded items are too small if they are displayed as wide or full. If full-bleed is chosen, embedded contents are too wide and have to be scaled down by the CSS which is not great.

Possible Solution



Solve the long-running content_width riddle in the context of Gutenberg by rethinking the approach from the ground up: What elements are affected by content_width, how can the global take into account responsive / fluid widths that don't use hard pixel values, and does the content_width global have a role at all in the Brave New World of WordPress Blocks?

Related Issues and/or PRs

1483

Backwards Compatibility Customization [Status] In Progress [Type] Task

Most helpful comment

$content_width has been discussed a few times in core and it's seen as something "legacy", as it doesn't make much sense in a responsive era. It still make sense just for embeds, maybe.

What makes this even more difficult is the fact that in a responsive era not everything is defined in pixels. Many themes use things like 65em, percentages etc.
Responsive embeds are now a reality, so even if we were to add 2 more options for wide and full, ideally we wouldn't force them to be integers.

All 23 comments

It's worth noting that it's a requirement to use $content_width when submitting a theme to .org. So if the use of this variable changes, then those guidelines will also need to change.
https://developer.wordpress.org/themes/basics/theme-functions/#content-width

Quoting from https://github.com/WordPress/gutenberg/pull/5217#issuecomment-372580089

Quick note: Please be aware of the theme variable $content_width has been discussed a few times in core and it's seen as something "legacy", as it doesn't make much sense in a responsive era. It still make sense just for embeds, maybe. Some references:
https://core.trac.wordpress.org/ticket/21256#comment:25
https://core.trac.wordpress.org/ticket/23863#comment:10
https://github.com/Automattic/_s/issues/100#issuecomment-40746610

The question still stands as embeds can be wide and full-bleed. My testing of the demo post shows these blocks do not scale properly.

My comment was meant to second your point:

rethinking the approach from the ground up

Is there a filter inside Gutenberg blocks so I can temporarily change the content_width when displaying an embed in either an alignwide or alignfull block for a theme? Or is there a better current solution for displaying embeds in wide content blocks?

So, what's the best way to fix this? :)

The content width (actually max-width) is critical for loading/displaying images "properly". Seems there should be few different widths defined and both the editor and the front-end will have to decide which one to use based on context.

That can actually be done on the front-end right now, with only one var. The content max-width is needed after the template is loaded, when outputting the HTML. The theme "knows" the max-width by that point and can set $content_width accordingly. It can also change $content_width dynamically at different places in the template (before starting to output the HTML there).

Of course it's not going to be that easy inside the editor. The solution there seems to be to set "default max-widths" for several common contexts. Then everything requiring a width inside the editor can be fluid (percent based) and the width can be decided by a "display filter" on the front-end, the same way srcset and sizes attributes are added for images. That way we can keep the editor looking as close to the front-end as possible, and at the same time not limit the theme with hard-coded widths for the different contexts.

How to do this:

  1. Add a new PHP var $wp_widths that will hold the values for several contexts, perhaps default, wide, full. These values will correspond to the default theme widths and be used as max-width guidance in the editor (for making it match the front-end look). If that var is missing, use "sensible" default values.
  2. On the front-end use a dynamic $content_width that is set according to the max-width of the template.
  3. Editor blocks that need a width (image, some embeds, etc.) will use percentage values where possible. If hard-coded width is required (like for the images sizes attribute) the width will be set dynamically on the front-end according to the contextual $content_width.

Being able set multiple widths such asdefault, wide & full, would be very useful, both on the front-end and in the editor.

...both on the front-end and in the editor.

For the editor, definitely. For the front-end that's not going to work "perfectly", but probably well enough. Ideally the widths will be contextual there. We can still have default, wide & full but they will need to be set by the current template.

It would be good to define defaults for these values:

  • default or the current $content_width is the main column (post content) max-width. If both missing: 800px. (800 as this is about as wide as practical for reading. Better to err on the wide side here so images display well.)
  • full is full viewport width, i.e. 100vw.
  • wide - empty by default, the template will have to decide. If not set, it should be equal to default.

In that terms the front-end will still work relatively well by setting only $content_width. To support the editor, the theme will have to set the new var.

BTW, this needs to be set to continue with #6177. We are at a point where we need these values for the front-end code.

When I reviewed this issue, my mind went to the Customization focus and block-based page layouts. I could be off here due to low WP experience, but it seems like the approach we choose should be flexible enough to express different widths for different parts of a page layout (e.g., header, footer, content, sidebar). I'm not suggesting we need to handle that now, just mentioning in case it affects our solution in the near term.

but it seems like the approach we choose should be flexible enough to express different widths for different parts of a page layout

Exactly, that's what I was thinking too. More thoughts: https://github.com/WordPress/gutenberg/issues/6177#issuecomment-409843388

I also think that content_width is barely enough for properly expressing the sizes attribute, there are much more things that influence this, especially on complex, responsive layouts.

$content_width has been discussed a few times in core and it's seen as something "legacy", as it doesn't make much sense in a responsive era. It still make sense just for embeds, maybe.

What makes this even more difficult is the fact that in a responsive era not everything is defined in pixels. Many themes use things like 65em, percentages etc.
Responsive embeds are now a reality, so even if we were to add 2 more options for wide and full, ideally we wouldn't force them to be integers.

It seems to me that the place to define content widths (and their use by both the editor and PHP) is in the theme and/or template header blocks. Those definitions should allow the values to be any "legal" CSS value, as mentioned above:

/*
Template Name: My Fancy Template
Content Width: 100%
Full Width: 100vw
Wide Width: calc(100% + 40rem)
*/

Template values would override the same values set in the theme header, but the theme values would be used when a template doesn't specifically override them. Wordpress would itself have a set of default values used when the theme provides no context.

This should allow WP to automatically adjust $content_width to be contextually correct based on the template chosen, both in the editor and the front-end, if it is considered necessary to calculate it at all.

Without disappearing down a rabbit-hole, Gutenberg could opt to define the content column where the editor lives as (arbitrary value warning) 70% of the available horizontal space (allowing for the difference between wide [say 80%] and full [100%] to be shown when a template isn't yet chosen or the template lacks size information), but to use the defined values when available.

Reviewing the documentation, the editor does not seem to have a method or methods to pass in environment information from the theme or template? Trying to style the Gutenberg editor to be template-contextual does not even seem possible with CSS at the moment. Inspecting a page being edited shows no "template" class in the admin HTML (ie, page-template-my-fancy-template on the body or wrapper), making it impossible to contextually-reference it by CSS without adding a JS "hack" to discern the value of the template selector and add a class that way.

(As an aside, my clients--almost to an organization--view "pages" as the meat of their site, and any blog-style activities as a sideline. Page templates often have quite different presentation for the "same" HTML elements. One of the hardest things to explain to clients has always been "well, the visual editor _sort of_ lays things out visually, but not _really_"...being able to use CSS to easily style the editor, based on environment, would go a long way to making Gutenberg a huge step up.)

This isn't really a problem; you said it yourself : "The content_width global defines the max-width of content".
The theme defines what that max width is on the front end. The editor should define what that max is on the editor page. (The editor _is the theme_ during content creation, as it controls the display of the page.)

@joyously The main problem outlined here is specifically about how we handle widths on the front end.

Yes, and it doesn't seem like it is a problem, because the content_width _is_ the max width of the content area. The theme should know what that is on any page, regardless of whether there is an element or two that are wanting to be full width. By defining it, the elements that depend on it can then be styled correctly (or not, because it really shouldn't play into any styles since it's for embeds mostly).

As described in https://github.com/WordPress/gutenberg/issues/9534 we need a much more ergonomic mechanism for handling different widths across different layouts and nested contexts. However, I think we could use $content_width, if available, as a baseline for the post_content block root area, so I'm marking this as a task.

I think this also relates to #9302, which is pulling in a hard-coded 580px max-width for images, even if CSS has defined a larger container width.

As I mentioned above this is needed for #6177. It is implemented as a PHP global in #11377 (mostly to test) but thinking we can do better. This should probably be a filter and have a helper function that runs it and normalizes the values?

The proposed format is an array with three values:

$block_width = array(
     'default' => 640,
     'wide'    => 800,
     'full'    => 1024,
 );

where default is the same as the current $content_width.

That array can be (should be?) set contextually for each block container. For example: in the main content column the default width will be something like 640(px), but for a sidebar it would be something like 250.

I know theme authors would love to be able to set these widths in vw but unfortunately that's not practical (for now). These values act mostly "max-width", and the full value limits the width of the image that the visitors will download every time. As image widths are in pixels, we would need a (max-width) value in pixels for there.

Locked with #11973.

Also the content width from theme has to be used by other blocks, notably columns block to adjust the media queries.

Any news?

Any news?

The current idea is to move these to the theme.json files in full-site-editing. Still under consideration and there is no concrete plan, but it looks like the most probable scenario.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

franz-josef-kaiser picture franz-josef-kaiser  路  3Comments

jasmussen picture jasmussen  路  3Comments

wpalchemist picture wpalchemist  路  3Comments

jasmussen picture jasmussen  路  3Comments

spocke picture spocke  路  3Comments