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

Differing CSS specificity between Non-Iframed Editor and Front end #63925

Closed
2 tasks done
wongjn opened this issue Jul 25, 2024 · 9 comments · Fixed by #64534
Closed
2 tasks done

Differing CSS specificity between Non-Iframed Editor and Front end #63925

wongjn opened this issue Jul 25, 2024 · 9 comments · Fixed by #64534
Assignees
Labels
Global Styles Anything related to the broader Global Styles efforts, including Styles Engine and theme.json [Status] In Progress Tracking issues with work in progress [Type] Bug An existing feature does not function as intended [Type] Regression Related to a regression in the latest release

Comments

@wongjn
Copy link

wongjn commented Jul 25, 2024

Description

With non-iframed block editor, specificity of top-level element selectors are different relative to other selectors. I believe this is due to the .editor-style-wrapper prefix.

Step-by-step reproduction instructions

  1. Create theme using code snippets below.
  2. Activate the created theme.
  3. Edit a page or post.
  4. Add a Heading block, with default attributes and any text content.
  5. Save.
  6. Observe the font size.
  7. Top right 3-dots menu → Preferences → Enable "Custom Fields".
  8. Hit Show and Reload Page button (to enable the non-iframe editor).
  9. Observe the heading block size is different to step 5.
  10. On the front end, observe the heading block size is the same as 5.

Screenshots, screen recording, code snippet

Theme

theme.json
{
  "$schema": "https://schemas.wp.org/wp/6.6/theme.json",
  "version": 3,
  "styles": {
    "blocks": {
      "core/heading": {
        "typography": {
          "fontSize": "var(--wp--preset--font-size--large)"
        }
      }
    },
    "elements": {
      "heading": {
        "typography": {
          "fontSize": "inherit"
        }
      }
    }
  }
}
style.css
/*
Theme Name: Test
*/
templates/index.html
<!-- wp:post-content /-->

Observed behavior

  Front end Iframe editor Non-iframe editor
Screenshot

image

image

image

CSS
:root :where(.wp-block-heading) {
  font-size: var(--wp--preset--font-size--large);
}
h1, h2, h3, h4, h5, h6 {
  font-size: inherit;
}
:root :where(.wp-block-heading) {
  font-size: var(--wp--preset--font-size--large);
}
h1, h2, h3, h4, h5, h6 {
  font-size: inherit;
}
.editor-styles-wrapper h1,
.editor-styles-wrapper h2,
.editor-styles-wrapper h3
.editor-styles-wrapper h4,
.editor-styles-wrapper h5,
.editor-styles-wrapper h6 {
  font-size: inherit;
}
.editor-styles-wrapper :where(.wp-block-heading) {
  font-size: var(--wp--preset--font-size--large);
}
Analysis

core/heading block styles override top-level element heading styles.

core/heading block styles override top-level element heading styles.

❌ Top-level element heading styles override core/heading block styles. Element heading styles have specificity (0, 1, 1) whereas core/heading block styles have (0, 1, 0).

Environment info

  • WordPress 6.6.1
  • Custom theme (see code snippets)

Please confirm that you have searched existing issues in the repo.

  • Yes

Please confirm that you have tested with all plugins deactivated except Gutenberg.

  • Yes
@wongjn wongjn added the [Type] Bug An existing feature does not function as intended label Jul 25, 2024
@talldan
Copy link
Contributor

talldan commented Jul 25, 2024

Thanks for reporting this. I think it's a similar issue to the one mentioned here: #53468 (comment)

Though the selectors you mention are different.

Something to note is that the iframe is there for a reason, it prevents outside styles leaking in and the inside styles leaking out. Without it some extra specificity may naturally be required and the editor-styles-wrapper is needed to scope the canvas styles.

That said, it shouldn't change from WordPress release to release unless there's a good reason, so we can investigate if there's been a change, and if so try to fix things in another WordPress minor release.

I also wonder if it's worth looking at making the .editor-styles-wrapper part of the selector :where(.editor-styles-wrapper) so that it doesn't bump specificity so much.

@ktmn
Copy link

ktmn commented Jul 25, 2024

Something to note is that the iframe is there for a reason, it prevents outside styles leaking in and the inside styles leaking out.

But why is the non-iframed editor there? By default I have the iframed editor, but when I install a plugin that adds metaboxes it switches to non-iframed. But then when I switch to Tablet/Mobile preview it's iframed again and works perfectly. So why doesn't the editor just switch to an iframed "Desktop" preview right off the bat so I never have to even think about the non-iframed editor?

@talldan
Copy link
Contributor

talldan commented Jul 26, 2024

But then when I switch to Tablet/Mobile preview it's iframed again and works perfectly.

It's a good point! I was curious about it too. I had a look through some past issues and the discussion here outlines the reasoning - #48286 (comment)

TLDR: There are no big metabox compatibility issues, it's more about finding a UI that isn't clunky as the default experience.

A solution has been attempted in #59242, but there's a lot of discussion there and a blocking review.

When using third party blocks you may also have some that are using an apiVersion: 1 or apiVersion: 2 that force the editor to be non-iframed, and I believe the reason is that those blocks may have compatibility issues with the way they load assets.

@talldan
Copy link
Contributor

talldan commented Aug 7, 2024

I've tested this on WordPress 6.5 and it's showing the same behavior as 6.6, so it doesn't seem like this is a recent regression, but it is still a bug.

Ignore that - I accidentally test with the Gutenberg plugin active on my 6.5 environment. I can confirm it was a regression in 6.6, so hopefully it's something we can put a fix out for in a minor WordPress release (6.6.2 or 6.6.3).

FWIW, it seems like there's more momentum on solving the custom fields issue - #64247.

@talldan talldan added the Global Styles Anything related to the broader Global Styles efforts, including Styles Engine and theme.json label Aug 7, 2024
@talldan
Copy link
Contributor

talldan commented Aug 7, 2024

#64266 is also reporting the same issue, but with the Post Title block. I've closed that one as a duplicate.

@mrleemon
Copy link
Contributor

mrleemon commented Aug 7, 2024

Is this issue going to be fixed in 6.6.2, or is it scheduled for 6.7?

@apmeyer
Copy link

apmeyer commented Aug 9, 2024

I am hoping this is addressed before 6.7. As noted, enabling plugins that add meta boxes (such ACF or Yoast) disables the iFramed editor for hybrid themes and puts us back into the situation where new CSS specificity is applying block spacing margins to things it should not be.

@talldan
Copy link
Contributor

talldan commented Aug 13, 2024

Is this issue going to be fixed in 6.6.2, or is it scheduled for 6.7?

It's unclear as of yet, the first thing is that a fix still needs to be worked on for the issue. It's one of the next things on my list unless someone is able to pick it up before me. 🙏

@talldan
Copy link
Contributor

talldan commented Aug 14, 2024

Here's a breakdown of the problem and some possible fixes. Sorry for the long comment, but hopefully it makes it clear exactly what has happened and provides some options:

6.5

The theme.json block styles previously output a very simple selector like this (specificity 0,1,0):

.wp-block-heading

This beat element styles. Those would be output like this when in an iframe (0,0,1):

h1, h2, h3, h4, h5, h6

When non-iframed, the selectors are prefixed (using postcss-prefixwrap) to scope the styles. This increased the specificity of the theme.json block styles (0,2,0):

.editor-visual-styles .wp-block-heading

It still beats the similarly prefixed element styles when there's no iframe (0,1,1):

.editor-visual-styles h1,
.editor-visual-styles h2,
.editor-visual-styles h3,
.editor-visual-styles h4,
.editor-visual-styles h5,
.editor-visual-styles h6

6.6

In 6.6 iframed editor the block style has changed to this, the same specificity (0,1,0):

:root :where(.wp-block-heading)

In the non-iframed editor, problems start to happen. The CSS prefixer behaves differently for selectors prefixed with :root, body, or html (the prefixer calls this 'root prefixing'), it instead replaces that part of the classname instead of prepending to avoid an invalid selector:

.editor-visual-styles :where(.wp-block-heading)

Now it stays at 0,1,0. Element styles are prefixed in the same way they were in 6.5 (0,1,1) so the non-iframed element styles now beat the block styles in terms of specificity.

Possible fixes

Change how root prefixing works

The main problem to me appears to be how the prefixing works. For some root prefixed selectors it keeps the specificity the same, but for others it increases the specificity and that causes inconsistencies in how styles are applied.

We could look at changing how the prefixing works, but that would be quite a big change, and would require a lot of testing. Possibly too big in scope for 6.6.2.

If we go this route, an option is to consider changing how root prefixing works so that it also results in a specificity bump (in this example, perhaps generating a selector like :root .editor-visual-styles :where(.wp-block-heading) with a specificity of 0,2,0 like in 6.5).

Make the prefixing result in no specificity bump

Similar to the above, another option is to try making the .editor-visual-styles prefix have no specificity bump by instead changing the prefix to :where(.editor-visual-styles). In the situation we're discussing above though, it results in a selector like :where(.editor-visual-styles) :where(.wp-block-heading), which has zero specificity, so it'd still require changes to how root prefixing works.

A risk is that styles that aren't supposed to apply to the editor canvas start to take precedence over block/theme styles.

Try adjusting the element style selectors like #64076 did

It might be possible to try a similar fix like in #64076. If the element selectors are changed to something like html :where(h1), they'd still have the same specificity when iframed. When non-iframed, the selector becomes .editor-visual-styles :where(h1), which is a modest reduction in specificity from (0,1,1) to (0,1,0). The element selectors have the same specificity as the block selectors so ordering has to be relied upon. A worry is that this might cause some other knock-on effects, so it'd require a lot of testing, but is smaller in scope. It feels a little hacky.

Would love to hear if anyone has more ideas on fixing this.

@github-actions github-actions bot added the [Status] In Progress Tracking issues with work in progress label Aug 15, 2024
@hellofromtonya hellofromtonya added the [Type] Regression Related to a regression in the latest release label Aug 22, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Global Styles Anything related to the broader Global Styles efforts, including Styles Engine and theme.json [Status] In Progress Tracking issues with work in progress [Type] Bug An existing feature does not function as intended [Type] Regression Related to a regression in the latest release
Projects
None yet
Development

Successfully merging a pull request may close this issue.

6 participants