Repository navigation
Replace hardcoded breakpoints in front-end CSS with more modular CSS #35848
Description
What problem does this address?
Hardcoded screen width media queries like the 600px breakpoint for the core/columns block poses a not-insignificant problem for theme developers. We either have to work with that specific breakpoint, integrating it with our design system (even if we don't agree with pixel-based breakpoints #16911), completely remove core Gutenberg front-end styles, or otherwise hack around the CSS which no one enjoys doing. Some of these styles are particularly egregious to work around because they involve !important declarations to override inline styles.
What is your proposed solution?
I recently submitted a proposed solution using CSS custom properties #35808 and then immediately found out that this is not currently possible: https://bholmes.dev/blog/alternative-to-css-variable-media-queries/.
There is also no hook or other customization vector available to change the breakpoints. #19460
Regardless, I don't think that standard back-end breakpoints should cross over into front-end styles.
Instead, there are ways to write CSS for responsive layouts that do not rely on external breakpoints, but rather internal sizes. A good example is the "Switcher" layout from Every Layout. This approach, combined with some contextual CSS custom properties, would allow for easier manipulation of minimum-width of columns before they break into a single column, for example.
The challenge to overcome here is that this might not be a very backwards-compatible solution. Some themes out there in the wild are probably depending on hacky CSS workarounds to change the breakpoint of certain blocks, for example. However, I feel like this would be a more sustainable approach for future overrideability.
Here are the blocks I found that include hardcoded breakpoints:
- columns
- gallery
- latest-posts
- media-text
- navigation
- post-template
- rss
This search URL should probably find all of them: https://github.com/search?q=%24break-small+repo%3AWordPress%2Fgutenberg++path%3A%2Fpackages%2Fblock-library%2F+filename%3Astyle.scss&type=Code&ref=advsearch&l=&l=
Other issues that have attempted to start conversations similar to this:
Related PRs:
Metadata
Metadata
Assignees
Labels
Type
Projects
- StatusShow more project fieldsNo status
Activity
DeoThemes commentedon Oct 31, 2021
That's definitely an important feature. 600px is very small for mobile screens, most of the frameworks collapse at ~700-1000px. It makes navigation looks messy if there are many links, they simply don't fit.
cr0ybot commentedon Nov 5, 2021
@DeoThemes I have found in general that columns not collapsing until <600px results in some pretty extreme content squashing for more than 2 columns.
I'd like to also point out that using
pxunits in media queries is just all-around not great. Different browsers (particularly Safari) handle px value breakpoints at different sizes depending on browser zoom and user font size. See https://zellwk.com/blog/media-query-units/kraftner commentedon Nov 25, 2021
Related: #12299 including a possible workaround covered in #12299 (comment)
palmsout commentedon Dec 3, 2021
@cr0ybot I agree. There's a real need for grid layouts in the query loop block, and elsewhere, to respond at user defined breakpoints, and especially a need for columns to reduce responsively with screen size (beyond just going from, for instance, 3 columns above 600px to 1 column under 600px). Query loop block needs the option to define at least a middle ground option between say 600 & 100opx, but ideally at user defined points.
Azragh commentedon Jan 10, 2022
#16911 (comment)
cr0ybot commentedon Jan 13, 2022
Comparing the browserlist config for this project against Caniuse flexbox-gap, it looks like we should be safe swapping the margin stuff that ends up getting a little too specific to easily override withgap.It looks like this effort is already underway with the block gap feature having been merged in: #33991However, the underlying spacing in columns and other places is still being accomplished via margins instead of thegapproperty, though it seems like it's understood that this is the next step. Is there some kind of theme support proposal to opt themes into usinggapinstead of margins? Obviously changing the styles so dramatically would likely break backwards compatibility.UPDATE: The core columns block uses
gapnow! #37436The part that worries me most is that a columns block that breaks without a breakpoint would probably need to have its columns'
flex-basisbased on absolute values instead of relative percentages as they are currently done. This is a big change to how the columns block works currently. However, if column widths were based on an absolute size, they would fit side-by-side until they don't anymore, without the need for a hardcoded breakpoint.cr0ybot commentedon Jan 20, 2022
I finally got around to reading your blog post linked in that comment: https://kraftner.com/en/blog/building-your-own-wordpress-core-block-css/
Completely replacing the core block stylesheet is a workaround, but you end up in a situation that is very fragile. As WordPress/Gutenberg update with new/updated blocks, the replacement stylesheet is stuck at the old version.
If it were possible to override individual block styles, I'd feel that is a more tenable solution. It looks like the should_load_separate_core_block_assets hook might provide a possible way forward for that? We should be able to override the stylesheet enqueue via the slug, though combined stylesheets are still loaded in the editor. I'm going to mess around with this to see if it's feasible.
kraftner commentedon Jan 20, 2022
@cr0ybot I 100% agree that this is a terrible workaround which I'd love to get rid of. I see my blog post 50% as showing a workaround and 50% as an illustration of how terrible the current situation is and why it needs fixing. 😉
LukaszJaro commentedon Feb 4, 2022
Also by using grid it would reduce the amount of CSS shipped most likely, especially if media queries were eliminated. I recently ran into issue trying to override the 600px media query and had to use !Important.
I still use flexbox for items but grid is best for container type of layouts like columns.
chthonic-ds commentedon Feb 5, 2022
This is something I've experimented with since WP 5.0 was released and it's been a lot less fragile than I initially worried it would be.
I've been using something as simple as the following to achieve this:
RatzeR commentedon Jun 10, 2022
For some blocks, for example the navigation block, it would be great, if it would be possible to change the breakpoint where the block uses the mobile / desktop navigation.
And as it seems to be the goal to have everything configurable, it should be possible to change the breakpoint via the
block.jsonortheme.jsonfile.fabiankaegy commentedon Nov 9, 2022
I also think that adding a way for themes to define the breakpoints would be very useful. This setting could be exposed via
theme.jsonand even made available in some advanced settings in the site editor.Users and developers already have the ability to change the
contentWidthandwideWidthin thelayoutsection.Either these breakpoints could be set as part of the layout or as part of a new
breakpointskey.These here are the breakpoints that Gutenberg currently uses in its scss:
gutenberg/packages/base-styles/_breakpoints.scss
Lines 5 to 13 in d8a4c9c
And looking at the
block-librarystyle.css files there are only a two breakpoints that actually get used in the frontend styles:small
medium
So I think those are the only two that would need to get exposed in theme.json by default. But ideally the system could be flexible enough so themes could use this to also define their own breakpoints on top of the core ones.
aurooba commentedon Feb 4, 2023
Fully echo what @fabiankaegy said.
theme.jsonshould have the capability to override existing breakpoints and/or add more. I understand the arguments of intrinsic layouts, but that's simply not a realistic approach for everything yet.7 remaining items
colorful-tones commentedon Mar 2, 2024
I forgot CSS variables do not work in media query declarations. 🤦♂️
colorful-tones commentedon Apr 19, 2024
Here is a solution (more of a workaround).
https://gist.github.com/colorful-tones/22da9a7f6a1f5867903e5eff826567e1
It is nothing new and I think it is a derivative of @kraftner’s article https://kraftner.com/en/blog/building-your-own-wordpress-core-block-css/
I think it could be worth exploring extending ʼtheme.jsonʼ to allow for these breakpoints.
kraftner commentedon Apr 30, 2024
@colorful-tones If I read this right what you're doing is adding CSS on top. My approach is about replacing it so you do not constantly have to fight against core styles.
Having said that my blog post is quite old and dated by now. While still not great a more modern approach might be able to combine https://developer.wordpress.org/block-editor/how-to-guides/themes/theme-support/#disabling-base-layout-styles and what was proposed by @cr0ybot above.
I wish I'd have the time to write a follow up post to the one you linked with these approaches. But doesn't look like it right now.
Even if - still these are all just workarounds to the core issue: Breakpoints are hardcoded. And to change them the CSS custom property based approach for anything else from
theme.jsondoesn't work here since media queries can't use custom properties.alperta commentedon Sep 12, 2024
+1 for breakpoint setup in theme.json. Long menus look really bad at 600px (and up to 800px most of the time).
jnz31 commentedon Sep 17, 2024
+1
coreyworrell commentedon Oct 23, 2024
This feels like a critical need, as WordPress is still using pixel breakpoints, which is not responsive or accessible to the user's browser default font size. So as text size increases, pixel breakpoints happen way too early/late. And having these configurable in the theme, and even per block, would be great.
hagege commentedon Oct 23, 2024
+1 for breakpoint overrides available via theme.json.
magl88 commentedon Nov 6, 2024
I don't understand why such an important thing wasn't done right away and is being postponed.
I often come across designs with different variations of breakpoints
and more than just mobile and tablet and desktop.
And what about TV?
Sometimes I need even 5 breakpoints
OR do I need to set the sizes via the css clamp() property
vollyimnetz commentedon Jan 21, 2025
Totally agree, some more controll is needed. One way to have at least some controll for developers would be a filter in the function WP_Styles->print_inline_style
Something like the following would be totaly suitable for most cases:
In this way someone could replace the current default value of 782px with something to there own like. This is a generall purpose approach (as one can override any inline-style).
vollyimnetz commentedon Jan 28, 2025
The following code uses the existing columns inline style (from
wp-includes/blocks/columns/style.css) and changes the breakpoints to new values.Note: you may use a different style.css if you are on an rtl layout.
gabbsmo commentedon Sep 17, 2025
theme.json property is nice, but a CSS variable or PHP hook would be very useful for legacy themes as well.
kraftner commentedon Sep 17, 2025
@gabbsmo Unfortunately that is technically not possible on CSS/browser level.
gabbsmo commentedon Sep 17, 2025
Thanks. A PHP filter hook then so that legacy themes are not left out.