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

Backend vs frontend discrepancy using alignment (left/right) if theme.json is active #33385

Closed
onetrev opened this issue Jul 13, 2021 · 20 comments
Labels
[Feature] Themes Questions or issues with incorporating or styling blocks in a theme. General Interface Parts of the UI which don't fall neatly under other labels. [Type] Bug An existing feature does not function as intended

Comments

@onetrev
Copy link

onetrev commented Jul 13, 2021

Description

If you have a valid theme.json file and then try to use align left or align right on an image, it goes outside of the content container to the far edge of the editor. This happen in WP 5.8 RC2, regardless of whether you have the Gutenberg plugin activated. I've tested in my own base theme, but also with TT1 Blocks and Blockbase. The same thing also happens if I add a basic theme.json file to Twenty Twenty One.

Step-by-step reproduction instructions

  1. Insert an image into your content, then use the alignment functionality and align the image to the left / right.

Expected behaviour

As it was before in WP 5.7, the frontend and backend output should be the same, as detailed in the next section.

Actual behaviour

From what I can see the problem is if you have theme.json setup, then in the backend <div class="wp-block" data-align="left"> now contains float: left whereas before the float would be added to the child <figure> element in the backend. On the frontend the float is added to the child <figure> element both when you have your theme.json active and when it's not. Consequently, it's properly aligned on the frontend in all cases.

Screenshots or screen recording (optional)

Screenshot 2021-07-13 163744

WordPress information

  • WordPress version: 5.8 RC2
  • Gutenberg version: 11.0.0
  • Are all plugins except Gutenberg deactivated? Yes
  • Are you using a default theme (e.g. Twenty Twenty-One)? Yes

Device information

  • Device: Desktop
  • Operating system: Windows 10
  • Browser: Edge 91
@annezazu
Copy link
Contributor

@onetrev thanks for reporting this! I'm having a hard time following the exact problem you're describing. I just tested with WP 5.8 and the latest of Gutenberg. I can see that alignment works correctly. Can you share a video or an additional set of screenshots to clarify?

@annezazu annezazu added [Status] Needs More Info Follow-up required in order to be actionable. General Interface Parts of the UI which don't fall neatly under other labels. labels Jul 28, 2021
@onetrev
Copy link
Author

onetrev commented Jul 29, 2021

Hey @annezazu thanks for the follow up. I realise now I forgot to include a key detail. This appears as soon as you add layout -> contentSize to your theme.json. But to save you time and make sure you can see exactly what I'm experiencing, I've made a one minute video (otherwise there would be a lot of screenshots!). Hope this helps.

NOTE: in the video I'm now running WP 5.8, with no Gutenberg plugin, as since my original post WP 5.8 has been released.

@fklein-lu
Copy link
Contributor

@annezazu This is a wider issue with how Gutenberg handles alignment styles, and it's not only present in hybrid (PHP themes with theme.json), but also block-based themes.

Traditionally, themes have had a container (div or similar) wrapping the post content. Therefore floated elements did not break out of this container. This is still the case with hybrid themes, as WordPress does not output styles for the content container. If a theme's layout on the frontend was working before, it will stay that way.

If themes want to use the new way of adding controlling the block width, the related dev 5.8 note recommends this approach:

.entry-content > * {
    max-width: 800px;
    margin-left: auto !important;
    margin-right: auto !important;
}
 
.entry-content > .alignwide {
    max-width: 1000px;
}
 
.entry-content > .alignfull {
    max-width: none;
}
 
.entry-content > .alignleft {
    float: left;
    margin-right: 2em;
}
 
.entry-content > .alignright {
    float: right;
    margin-right: 2em;
}

So the content container doesn't have a fixed width. Instead it is a 100% and the blocks inside are individually restricted in width. And this approach also works. Let's look at why.

This is a floated image on the frontend.

Screen Shot 2021-08-05 at 17 11 31

This is the markup:

<div class="wp-block-image">
  <figure class="alignleft">
    <img src="http://example.com/wp-content/uploads/image-alignment-150x150.jpg" alt="Image Alignment 150x150" class="wp-image-904">
  </figure>
</div>

This image stays inside of the content width because the .wp-block-image container is restricted in width, and the .alignleft is floated inside of this container.

However in the editor, the markup is the following:

<div class="wp-block" data-align="left">
  <figure>
    <div>
      <img />
    </div>
  </figure>
</div>

So the float is on the outer container meaning the entire block is floated, and not just the figure inside the block.

Therefore the block floats left to its container, which is the editor. And therefore "sticks out" of the content area.

This is also an issue in block-based themes, as shown with TT1:

Screen Shot 2021-08-05 at 17 18 21

This bug is present in the post editor and template editor for hybrid themes, and the site editor for block-based themes. For me this is worth getting into 5.8.1.

Why? Because there is no workaround here.

You can fix the post editor. Assuming a content size of 520 pixels, you can use calculated margins in the editor stylesheet:

.block-editor-block-list__layout.is-root-container > [data-align="left"] {
	margin-left: calc( ( 100% - 520px ) / 2 ) !important;
}

To explain: you take the full width, subtract the content size, and divide by two. That gives the margin to fit the floated element back in.

All in all, this isn't great. However it gets worse. If you open the Template Editor, this is what you see as generated CSS:

.editor-styles-wrapper .wp-container-39 > [data-align="left"] {
    float: left;
    margin-right: 2em;
}
.editor-styles-wrapper .wp-container-39 > * {
    max-width: 520px;
    margin-left: auto !important;
    margin-right: auto !important;
}

The .wp-container-39 is dynamically generated, so no way to target all blocks. The .editor-styles-wrapper is added to all CSS styles added via add_editor_style() and 5.8 deprecated all other CSS enqueuing through enqueue_block_editor_assets.

Therefore you can't really override these styles at all currently, leaving the template editor broken.

@colorful-tones
Copy link
Member

Oh yeah, and this has been driving me nuts on a recent hybrid theme I’ve been working on.

I did not even realize you could try and target .block-editor-block-list__layout.is-root-container > [data-align="left"], which is less than ideal, but handy to know.

@skorasaurus skorasaurus removed the [Status] Needs More Info Follow-up required in order to be actionable. label Aug 6, 2021
@annezazu annezazu added the [Feature] Themes Questions or issues with incorporating or styling blocks in a theme. label Aug 10, 2021
@annezazu
Copy link
Contributor

I was out last week and am just returning to see this lovely follow up. Thank you for the detailed response!

@scruffian scruffian changed the title Backend vs frontend discrepency using alignment (left/right) if theme.json is active Backend vs frontend discrepancy using alignment (left/right) if theme.json is active Aug 13, 2021
@andersnoren
Copy link

Just want to 1+ this issue. Screenshot below running Blockbase, showing the differences in position of one alignleft and one alignright image between back-end and front-end.

blockbase-align-left-right-issue

@syllie
Copy link

syllie commented Sep 13, 2021

+1 This affects me too. Trying to work this out on a new project, which is a hybrid theme, attempt to embrace theme.json

@annezazu
Copy link
Contributor

Just tagging in @oandregal on this conversation!

@oandregal
Copy link
Member

cc @youknowriad and he knows all the things about layout/align.

@youknowriad
Copy link
Contributor

This is the intended behavior for how alignments work from now one. The reason is simple there's no other way that we could implement these alignments in all contexts in a generic way (think column block, sidebar, group block, ...) with the old behavior. That's one of the reasons the new alignments/layout is opt-in (enabled when adding theme.json).

Here's a concrete example (with contradicting goals that lead to the decision):

  • If you want to support a centered area for all blocks but allow blocks to go full width, you either have to:

1- have two wrapping divs and apply a negative margin to the "wide" and "full" aligned blocks.
2- have a single div and apply "margin-auto" and max width to blocks by default (unless they are wide or full aligned).

The option 1 doesn't work in all contexts, because there's no way to know in a generic way what negative margin to apply. you only know the "content size" and "wide size" but you don't know the size of the parent of the div where that layout is defined.

So we go with option 2.

  • If you want to align left some block but at the same time leave it in the "content area" (centered area) like the previous behavior, it means you need another intermediate div that is centered and your block should be floated inside that area. While previously some blocks had an intermediate div to solve this, it was not consistent across blocks and a lot of themes were struggling to implement alignments properly across blocks. So the solution here is to go with the generic approach: Align left and align right means align at the edge of their container, if you want to align left or right but still keep them in the "centered" area, you can just wrap them in another group block (instead of being automatic, you can do it explicitly)

@onetrev
Copy link
Author

onetrev commented Oct 26, 2021

Hey @youknowriad thanks for looking into this. The concept and rationale makes sense, but I'm still unclear though why WP adds the alignment to the parent element on the backend but to the child element on the frontend? That's what I think we're all reporting here. Thereby, it's a bit odd I have to add a group block just to make the alignment look correct in the backend when it's fine on the frontend.

Note, I didn't see this change documented anywhere in the developer notes for 5.8, maybe I missed it? But it would help others like me not waste time trying to track down why this is happening.

@youknowriad
Copy link
Contributor

@onetrev Oh sorry, I missed that part about the image block sorry, yes, this sounds like a bug and ideally should be consistent. The problem is that the class added to the inner element in the frontend was a hack used to make alignment work as expected in classic themes. In the ideal world, we'd move these back to the outer wrapper that said there might be some backward compatibility concerns in doing so.

I'm reopening the issue so we can give it a try at least.

@youknowriad youknowriad reopened this Oct 27, 2021
@youknowriad youknowriad added the [Type] Bug An existing feature does not function as intended label Oct 27, 2021
@andrewstaffell
Copy link

andrewstaffell commented Jan 12, 2022

While experiencing the same behaviour we noticed that Gallery blocks and Cover blocks are not affected by the discrepancy, so that their layout renders identically in editor and front end, because the align is on the top-level element eg. <div class="wp-block-gallery alignright">

This makes it tempting to use the hack/workaround of converting an image to a gallery just to have it float correctly but it would be great if for consistency (between editor/front and between block types) the alignright class could be moved back to the outer <div class="wp-block-image"> element too.

@chadbush
Copy link

chadbush commented Jun 7, 2022

Now with WordPress 6, the div that was wrapped around the figure has been removed and all of the workarounds described here (and elsewhere as far as I can see) no longer work. Does anyone have a temporary solution that works with WP 6 to force left and right aligned images into the content area in the editor? I haven't been able to devise one.

Also, does this change the direction this thread is heading, now that the markup has been refactored for these elements?

@fklein-lu
Copy link
Contributor

@chadbush WordPress 6.0 resolved an inconsistency between the block markup on the frontend, and in the backend.

You pointed out that the div wrapper around the figure is now gone. So that part of my previous comment as no longer valid.

Both the frontend and the backend now use this structure:

<figure class="wp-block-image alignleft size-thumbnail">
    <img />
</figure>

So going back to my previous example, the editor styles now can use the direct .align* selectors.

Meaning this snippet...

.block-editor-block-list__layout.is-root-container > [data-align="left"] {
	margin-left: calc( ( 100% - 520px ) / 2 ) !important;
}

...now has become this in WordPress 6.0:

.alignleft {
	margin-left: calc( ( 100% - 520px ) / 2 ) !important;
}

I fixed up one of my themes with this, so it should work well for your themes too. Just let me know if this isn't working for you.

@chadbush
Copy link

chadbush commented Jun 8, 2022

@fklein-lu I tried your updated workaround and it works perfectly. Thank you so much!

I do appreciate that it's a good thing the extraneous and inconsistent div has been removed from around the figure.

I'll update my themes accordingly with this simple and elegant fix.

@jg314
Copy link
Contributor

jg314 commented Jun 10, 2022

Thanks a ton for the suggestions @fklein-lu. That CSS was incredibly helpful for making this look right in the backend editor. A few more items that came up for me:

  • Media queries were needed to only adjust the left and right margins at certain minimum widths. Without those, the blocks were cut off on the sides when using smaller devices.
  • Different media queries were required when using and not using fullscreen editing mode.

In case it's helpful for anyone, you can see the compiled CSS I used below. You likely need to adjust the min-width and 840px numbers. The 840px number should match your contentSize inside of theme.json.

@media screen and (min-width: 1137px) {
    body.is-fullscreen-mode .editor-styles-wrapper .alignleft {
        margin-left: calc((100% - 840px)/2) !important;
    }
    body.is-fullscreen-mode .editor-styles-wrapper .alignright {
        margin-right: calc((100% - 840px)/2) !important;
    }
}
@media screen and (min-width: 1297px) {
    .editor-styles-wrapper .alignleft{
        margin-left: calc((100% - 840px)/2) !important;
    }
    .editor-styles-wrapper .alignright {
        margin-right: calc((100% - 840px)/2) !important;
    }
}

@tellthemachines
Copy link
Contributor

Is there anything still actionable here? From the comments above it seems the behaviour of elements floating to the edge of the screen is a deliberate design decision, and the discrepancy between front end and editor markup has now been fixed. Are we good to close this issue?

@onetrev
Copy link
Author

onetrev commented May 8, 2023

I think so based on the two points you made @tellthemachines -- so since I created this issues, I'll go ahead and do that now...

@lozeone
Copy link

lozeone commented Mar 29, 2024

Unless there was a fix to this that I'm overlooking since this discussion was happening, I believe you can just add this to your editor-style.css file. without needing to use media queries or hardcode a width value.

.is-root-container > .alignleft {
  margin-left: max(0px, calc((100% - var(--wp--style--global--content-size)) / 2)) !important;
}

.is-root-container > .alignright {
  margin-right: max(0px, calc((100% - var(--wp--style--global--content-size)) / 2)) !important;
}

This will use the contentSize value from the theme.json file. Is there a reason that Guttenberg isn't adding this by default?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
[Feature] Themes Questions or issues with incorporating or styling blocks in a theme. General Interface Parts of the UI which don't fall neatly under other labels. [Type] Bug An existing feature does not function as intended
Projects
None yet
Development

No branches or pull requests