CSS Specificity for WordPress 6.6 #61810
Replies: 8 comments 24 replies
-
I believe the latter approach (Option 2) using the
|
Beta Was this translation helpful? Give feedback.
-
Thank you for this write up. It certainly isn't an easy or straightforward decision. One of the main issues I keep running into when using block specific Stylesheets that are loaded via I have just gone through the exercise of running 6 very different client projects through testing with the Gutenberg Plugin Version 18.3 activated to see whether I could find any regressions. The only one that came up in two small cases was not related to the lowered specificity, but instead the change of where custom properties are defined (the fact that they are now on :root instead of body (which I'm very happy about)). The sites I tested ranged from hybrid themes that were built about 2 years ago to block based themes in development now. Based on my testing at least I would be in favor of option 1 because the long term benefits of this approach outweigh the downsides for me. |
Beta Was this translation helpful? Give feedback.
-
Why is that a con? What's the benefit of reducing it all the way to 0-0-0?
I'd say we'll anyway need documentation for
Reverting is a big word. It does not really require reverting anything, I just added
Could you give an example? How can they add override styles? |
Beta Was this translation helpful? Give feedback.
-
I definitely have concerns about the potential breakage that might happen with the zero specificity styles, it might just a small subset of styles, but even then to ship knowing there's an issue with resets seems risky. The stability of the public part of a user's site is to me the most important thing to uphold. Maybe resets are an outdated way of doing things, but the reality is that WordPress can't just disregard all those existing themes. If there are ways to mitigate any breakage, it should be considered IMO, even if it's not the perfect system. The discovery about zero specificity styles not working with resets not working also makes me wonder if zero specificity really is the ideal system. It seems to me that themes should probably be able to define styles that our both lower and higher specificity for total flexibility, so is a consistent specificity level instead the most important thing? |
Beta Was this translation helpful? Give feedback.
-
Thanks for this deep discussion and the alternative proposals above. It seems to me, that Option 1 has a higher potential of a breaking changes and we probably don't have enough time before 6.6 in order to be able to judge the impact of the changes properly. Now looking at the cons of Option 2:
For me, that's not really a con. Reducing specificity to "0-1-0" or "zero" for core styles is kind of a random choice. The important thing is that everyone (core developers, themers, plugin authors) are aware of the level of specificity core uses and that it's "hopefully" consistent as much as we can. Also, If I'm reading things properly, 6.5 might not use the exact same selectors but the level of specificity there is almost equivalent.
Yes, but so is the purpose of For me, it seems that the second approach at this point is clearly a winner here in order to be able to move forward with the section styling feature. (Almost no breaking changes, and some light changes to core styles). In the future, it's clear that CSS layers are exactly what we need here. Hopefully, we can try to see how to introduce them iteratively for the future (maybe when the possibility to assign a layer to style elements is added) |
Beta Was this translation helpful? Give feedback.
-
May I suggest a temporary "polyfill" that would unlock CSS Cascade Layers today? Not familiar with the PHP code involved, but I suspect the temporary solution could look something like this (simplified pseudo-code): function wp_enqueue_style {
- echo style
+ echo "@layer name {" . style . "}"
} I actually did something similar for a past project (part of a PostCSS plugin). Worked quite well. Ref: https://github.com/Create-Inc/archetype/tree/main/packages/archetype/scope#layering Code is quite simple too: https://github.com/Create-Inc/archetype/blob/main/packages/archetype/src/postcss-scope-plugin/utils/apply-layer.ts |
Beta Was this translation helpful? Give feedback.
-
I feel that Option 1 in the given timeframe of the 6.6 release is a no-go, considering the potential breaking of many sites if shipped with 6.6. But even with Option 2 I'm not sure if this should be shipped with 6.6 immediately, but I'd prefer this over Option 1. Both options need good documentation, which should not only be "we did that, do it this way" but also explain the technical aspects of using I think what also should be documented at some point is what @fabiankaegy wrote in this comment about the nuanced layers of styles that we have. I don't always find it super clear from where which styles are coming and I'm pretty sure many developers, who not have a close eye on core development, struggle with this too. |
Beta Was this translation helpful? Give feedback.
-
How can one opt out of these styles? WordPress 6.6 broke hundreds of our agency's websites, by underlining all links and by left aligning all centred images. All these changes are done via highly-specific They do not belong in core, they belong in themes:
Why are these in core?! |
Beta Was this translation helpful? Give feedback.
-
Background
As implementation of the section styling feature for WP 6.6 has progressed, one of its key use cases, nested section styles, has presented an interesting challenge. Nested section styles require uniform or “level” specificity in style selectors so the style load order can be leveraged.
Initially, this was seen as an opportunity to completely lower our core style specificity to
0-0-0
, making overriding these styles predictable and trivial for theme authors. The reduction to zero-specificity has already commenced within Gutenberg but does come with some caveats.This discussion is to propose an alternative to zero-specificity and document a decision on a path forward for WP6.6.
Goals
Why not CSS layers?
There's currently no easy way to enforce all styles to be contained within a layer. Any "unlayered" styles take precedence over all "layered" styles. This scenario is much like core styles being set to zero-specificity but 3rd party stylesheets accidentally overriding them.
There is a current proposal aimed at adding support for a
layer
attribute to HTML<link>
tags. Once implemented, that would open the door for functions likewp_enqueue_style
etc. to support specification or enforcement of layers.It's important to note that while CSS layers might not be viable soon, there is nothing stopping either of the options detailed below from being stepping stones to leveraging CSS layers in the future. When that time comes, a shift to zero-specificity within any given layer becomes much easier.
Available Options
Option 1 - Zero Specificity using
:where(...)
Historically, there have been several requests to lower the specificity for core styles. A few going as far as suggesting these styles should have zero specificity. The main desire here was to make overriding core styles as easy as possible.
Core styles have been reduced to zero specificity in Gutenberg already, primarily via the following PRs.
:where(body)
instead of just … #61602This reduction to zero specificity has caused a few regressions such as Global Styles failing to take effect on some blocks, common reset styles bleeding into block styles etc. Some fixes have landed while others are still open.
Issues reflecting these regressions include:
Related issues from external repos:
The above lists are not comprehensive however they do illustrate some of the downside if we stick with zero-specificity styles, or switch to another approach, when early adopters may have already been through the process of adjusting their styles.
The majority of the zero-specificity changes have been in the Gutenberg plugin since 18.1, early in the WP 6.6 release cycle.
WordPress commits to maintaining backward compatibility, so the breakage to global styles and requiring themes to update selectors for common reset styles or their custom blocks goes against this commitment.
The upside of zero-specificity for core styles is that it fulfills broader requests from the community, namely, that CSS specificity is lowered as much as possible to make it trivial to override any core style.
It's entirely possible the community might decide the minor style issues and updates are worth the benefits and flexibility gained from zero-specificity styles.
Pros:
Cons:
Option 2 - Reduce Specificity to
0-1-0
using:root :where(...)
This option revolves around reducing our core style specificity using
:where()
but prefixing it with:root
. The result is selectors with0-1-0
specificity.An in-progress PR implementing this approach is also available.
This is a compromise between reducing specificity all the way to zero and maintaining backward compatibility.
It achieves the following:
ul,ol { margin: 0 }
overriding default and global styles for the social links block)It is still possible that this approach may require a tweak or two to some more complex blocks' styles however any blocks that use the default class selectors, e.g.
.wp-block-*
, should remain largely unaffected.As nice as zero-specificity styles across the board would be. Recent testing and explorations have highlighted an increased potential for breaking themes, global styles etc.
Pros:
Cons:
:root
prefix is not immediately obvious and requires documentationQuestions
I’d love to hear any thoughts from @WordPress/gutenberg-core & @WordPress/block-themers to unblock section styling in time for WP6.6.
Beta Was this translation helpful? Give feedback.
All reactions