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

CSS Priority Changes in Non-iframe Editor For WP 6.6 #63688

Closed
2 tasks done
shodoi opened this issue Jul 18, 2024 · 8 comments
Closed
2 tasks done

CSS Priority Changes in Non-iframe Editor For WP 6.6 #63688

shodoi opened this issue Jul 18, 2024 · 8 comments
Labels
[Type] Bug An existing feature does not function as intended

Comments

@shodoi
Copy link

shodoi commented Jul 18, 2024

Description

When specifying styles.elements.h2.spacing.margin.top in theme.json, I expected the same appearance in both iframe Editor and Non-iframe Editor, but the styles differ.

In the iframe Editor, margin-top: 5rem is applied to h2 as expected.
In the Non-iframe Editor, the value of styles.spacing.blockGap takes precedence, overriding the margin-top of h2.

{
    "styles": {
        "elements": {
            "h2": {
                "spacing": {
                    "margin": {
                        "top": "5rem"
                    }
                }
            }
        },
        "spacing": {
            "blockGap": "1.2rem"
        }
    }
}

Step-by-step reproduction instructions

  1. Add styles.elements.h2.spacing.margin.top to theme.json
  2. Create a meta box in the editor. (I activated Yoast SEO for this)
  3. Make sure the editor is not an iframe.
  4. Inspect the CSS.

Screenshots, screen recording, code snippet

iframe Editor
image

Non iframe Editor
image

Environment info

  • WordPress: 6.6
  • PHP: 8.1.23-dev
  • Server: PHP.wasm
  • Database: WP_SQLite_Translator (Server: 5.5 / Client: 3.40.1)
  • Browser: Chrome 126.0.0.0 (macOS)
  • Theme: Twenty Twenty-Four 1.2
  • MU-Plugins:
    • 0-32bit-integer-warnings.php
    • 0-allowed-redirect-hosts.php
    • 0-check-theme-availability.php
    • 0-dns-functions.php
    • 0-permalinks.php
    • 0-sqlite.php
    • 0-thumbnails.php
  • Plugins:
    • Yoast SEO 23.0

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
@shodoi shodoi added the [Type] Bug An existing feature does not function as intended label Jul 18, 2024
@aaronrobertshaw
Copy link
Contributor

Thanks for taking the time to write up this detailed issue @shodoi 👍

I can replicate the issue using WP 6.6.

Replication Screenshots
Iframed Non-iframed
Screenshot 2024-07-18 at 2 30 20 PM Screenshot 2024-07-18 at 2 30 43 PM

The root cause of the divergence between the iframed and non-iframed editors is a known bug where top-level element styles in theme.json had their specificity unintentionally increased.

This issue was fixed via #63403 and was included in yesterday's Gutenberg 18.8 release. It will be included in the WP 6.6.1 point release which should be available in the coming days. You can read more in this ticket.

With Gutenberg 18.8 active, this is what I get comparing the two editors states:

Iframed Non-iframed
Screenshot 2024-07-18 at 2 25 55 PM Screenshot 2024-07-18 at 2 26 36 PM

@shodoi
Copy link
Author

shodoi commented Jul 18, 2024

Thank you for your comment, @aaronrobertshaw

I was able to reproduce the screenshot you provided with Gutenberg 18.8.0 enabled.

I believe the theme.json in your screenshot environment looks like this:

{
    "styles": {
        "elements": {
            "h2": {
                "spacing": {
                    "margin": {
                        "top": "6.5rem"
                    }
                }
            }
        },
        "spacing": {
            "blockGap": "1.4rem"
        }
    }
}

The styles.spacing.blockGap specification is taking precedence over the styles.elements.h2.spacing.margin.top specification. Is this the correct behavior and not an issue?

Iframed

.is-layout-constrained > * {
    margin-block-start: 1.4rem;
    margin-block-end: 0;
}
h2 {
    font-size: var(--wp--preset--font-size--x-large);
    margin-top: 6.5rem; // not working
}

Non-iframe

.editor-styles-wrapper .is-layout-constrained > * {
    margin-block-start: 1.4rem;
    margin-block-end: 0;
}
.editor-style-wrapper h2 {
    font-size: var(--wp--preset--font-size--x-large);
    margin-top: 6.5rem; // not working
}

Up until WordPress 6.5.5, styles.elements.h2.spacing.margin.top took precedence over styles.spacing.blockGap:

h2 {
    font-size: var(--wp--preset--font-size--x-large);
    margin-top: 6.5rem; // working
}
:where(body .is-layout-constrained) > * {
    margin-block-start: 1.4rem;
    margin-block-end: 0;
}

WP 6.5.5 screenshot
image

@aaronrobertshaw
Copy link
Contributor

I believe the theme.json in your screenshot environment looks like this:

That is correct. I altered the values you had just to make it easier to confirm the correct values and they weren't defaults etc.

The styles.spacing.blockGap specification is taking precedence over the styles.elements.h2.spacing.margin.top specification. Is this the correct behavior and not an issue?

To my understanding, yes, it is the correct behaviour.

The general thinking I have is that:

  1. Element styles are supposed to be super generic almost like a reset stylesheet
  2. Layout and block gap styles need to be a layer above that to ensure proper layout
  3. Global block type styles (e.g. the heading block, not the heading element), are more specific than a general layout style such as block gap and should win out
  4. Block instance styles should override all the others

I've also discussed this with @andrewserong, who did a lot of the hard work in developing the block gap feature initially (🙇) and I think we're on the same page. Certainly happy to hear any alternative opinions of course.

Up until WordPress 6.5.5, styles.elements.h2.spacing.margin.top took precedence over styles.spacing.blockGap:

:where(body .is-layout-constrained) > * {
    margin-block-start: 1.4rem;
    margin-block-end: 0;
}

There was a point in the Gutenberg plugin where the layout styles were temporarily reduced to zero-specificity i.e. being wrapped in :where(). Can you confirm whether what you were seeing was with a particular version of Gutenberg active?

@shodoi
Copy link
Author

shodoi commented Jul 18, 2024

There was a point in the Gutenberg plugin where the layout styles were temporarily reduced to zero-specificity i.e. being wrapped in :where().

WordPress 6.5.5 By default :where() wraps, but that was not the correct behavior.

Up until WordPress 6.5.5, styles.elements.h2.spacing.margin.top took precedence over styles.spacing.blockGap:

:where(body .is-layout-constrained) > * {
    margin-block-start: 1.4rem;
    margin-block-end: 0;
}

There was a point in the Gutenberg plugin where the layout styles were temporarily reduced to zero-specificity i.e. being wrapped in :where(). Can you confirm whether what you were seeing was with a particular version of Gutenberg active?

The above CSS is WordPress 6.5.5 default only, Gutenberg is inactive.

If you enable WordPress 6.5.5 and Gutenberg 18.8.0, it will look like the screenshot.

.is-layout-constrained > * {
    margin-block-start: 1.2rem;
    margin-block-end: 0;
}
h2 {
    font-size: var(--wp--preset--font-size--x-large);
    margin-top: 6.5rem;
}

image

@aaronrobertshaw
Copy link
Contributor

Thanks for helping to work through this issue @shodoi, I appreciate it 👍

I can confirm what you reported in terms of selectors for 6.5. They were also consistent across iframed/non-iframed editors and the frontend.

When it comes to the expected behaviour, the more I've looked at this the more I lean toward what was outlined above:

The general thinking I have is that:

  1. Element styles are supposed to be super generic almost like a reset stylesheet
  2. Layout and block gap styles need to be a layer above that to ensure proper layout
  3. Global block type styles (e.g. the heading block, not the heading element), are more specific than a general layout style > such as block gap and should win out
  4. Block instance styles should override all the others

I'm happy to hear the thoughts of others but I'm leaning towards not making any further changes to these selectors. The current state in GB 18.8, and in 6.6.1 (when it is released), will be consistent across the editors and frontend as well as match the correct behaviour.

Let's leave this issue open for a while longer to allow others the opportunity to weigh in.

@andrewserong
Copy link
Contributor

the more I've looked at this the more I lean toward what was outlined above:

I agree with the above outline, I think it makes good conceptual sense for how these different pieces fit together 👍

@shodoi
Copy link
Author

shodoi commented Jul 19, 2024

Thank you for your response, @aaronrobertshaw @andrewserong .

I understand that the behavior in WordPress 6.6 and Gutenberg 18.8 is correct.
The style I wanted to achieve can likely be resolved with one of the following methods, so I will close this Issue after a while.

a. Specifying null for settings.spacing.blockGap

{
    "settings": {
        "spacing": {
            "blockGap": null
        }
     }
}

b. Specifying margin for the heading block (not the heading element)

{
    "settings": {
        "spacing": {
            "blockGap": true
        }
    },
    "styles": {
        "blocks": {
            "core/heading": {
                "spacing": {
                    "margin": {
                        "top": "6.5rem"
                    }
                }
            }
        }
    }
}

I was expecting the following to work, but it seems it's not being applied...

{
    "settings": {
        "spacing": {
            "blockGap": true
        }
    },
    "styles": {
        "blocks": {
            "core/heading": {
                "elements": {
                    "h2": {
                        "spacing": {
                            "margin": {
                                "top": "6.5rem"
                            }
                        }
                    }
                }
            },
        }
    }
}

@aaronrobertshaw
Copy link
Contributor

I was expecting the following to work, but it seems it's not being applied...

I believe the reason this doesn't work is; that theme.json config would target a nested, or inner, h2 element e.g. via .wp-block-heading h2. The core/heading block is itself the h2.

Given you shouldn't nest heading elements, I'd recommend using either of the other options you listed, most likely option B.

@shodoi shodoi closed this as completed Jul 21, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
[Type] Bug An existing feature does not function as intended
Projects
None yet
Development

No branches or pull requests

3 participants