-
Notifications
You must be signed in to change notification settings - Fork 4.2k
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
Resizable editor experiment #19082
Resizable editor experiment #19082
Conversation
cc @jorgefilipecosta who worked on this in #17946.
|
Thank you for working on this. Overall it seems like a promising path forward. A responsive editing canvas can show an instant effect of any responsive-specific changes you mean to make to each block. As a proof of concept, this PR is a great way to surface the challenges we must tackle, UI-wise:
These questions would be great for us to think about as we have to overcome them in order to truly fix #13203. GIF: Techwise this drops the iframe and adds something else. It would be good to sync up with Jorge as suggested above, as he's thought a lot about this; can the efforts be combined? There are some toolbar issues, the responsive behavior of the Media & Text block changes after toggling one of the size buttons, and there isn't room for the buttons on smaller screens (where they might not be necessary?) — and also isn't top toolbar compatible. The UI problems we need to solve together, so I'm adding a label to add some reinforcements. A dropdown is one idea, are there others? |
@jasmussen you've posed some very good questions, and I will answer with some more questions 😄
I assume you're thinking about this kind of situation?
I think we could change settings over silently if we have a specific setting for each breakpoint, such as the paddings and margins in @getdave 's PR. But what happens to controls like the Media & Text's
If we handle arbitrary ones, we'll need some sort of "resize" handle to drag the canvas borders around. What would that look like? And would it be instead of, or in addition to, the current size buttons? How much value will this bring over having just the buttons, given that most themes only define 2-3 breakpoints anyway?
Ugh, that's because it has a Random thought: if we could use CSS variables, we'd be able to lose half these pesky media queries 😂 😭 |
Awesome thoughts, thank you. I'm working through this in my head as we discuss, so it's very helpful.
Yes exactly. It's definitely a UI challenge. There should be some indication in context of a block setting whether it applies to all breakpoints, or just one, probably defaulting to all.
It would definitely be the easiest if we specified breakpoints for where change happened to how blocks behave, sort of like how Bootstrap (not a fan) has specific preset breakpoints. It would make for a simpler and more predictable UI, including for the reasons you mention. The question here, and there's probably an FSE discussion here too, what role does the theme play, if any? Do the responsive breakpoints need to sync up with breakpoints defined by the theme? Perhaps the simplest path forward is to define just phone, tablet and desktop breakpoints for now, and attach block settings to those three. Then potentially we could look at letting themes customize those three, not necessarily add additional ones. CC: @epiqueras and @jffng regarding the FSE aspect.
I think there's an aspect of progressive enhancement here that we could explore. I personally feel that it would be acceptable to not show this UI to IE11 at all, thereby enabling us to use CSS variables. CC: @youknowriad in case you have thoughts. But the cost of making this work with IE11 should not be so high it makes us write worse software. So, this is a big effort, but it's important we cut it up into small pieces on a road-map. Let's zoom out and discuss a hypothetical. The goal (not just of this single PR but of the effort) is:
Let's see if we can reduce scope:
Things that can be explored in the future:
The above hypothetical suggests the following tasks:
3 is perhaps/probably a separate PR, but it is something to think about. |
709e363
to
86b78bd
Compare
Thanks for this @jasmussen ! I have integrated @jorgefilipecosta 's work into this PR; the Media & Text block is now rendering correctly for all breakpoints. However, there are still issues wherever inline styles are used: in the post title, or on column blocks with custom widths. It is in this kind of situation that I think CSS variables could be really helpful, but using them means that anyone on IE won't be able to preview their custom column widths. Does this fit our definition of progressive enhancement? I'm more than happy to have a play with some of the blocks (on separate PRs, for clarity) and see how much code we can remove/optimise by using a mix of CSS variables and grid 😁 Regarding the scope of the current PR, I think it makes sense to limit it to getting a simulation of 3 breakpoints working correctly, so I guess that leaves the question of where best to put the Desktop/Tablet/Mobile buttons. (I haven't touched them yet so they're still looking as broken as before.) |
This seems to be working pretty well! Impressive.
This is my personal opinion, and it could use a sanity check from folks such as @youknowriad or @mtias. But my thinking is that by keeping the current preview button for IE11, users will have a functional if not as convenient editor, while allowing us to write better and more maintainable software for modern browsers.
I am working on an updated mockup to accomplish this, but it is in the vein of the previously shown preview dropdown. It feels worth testing, given that it does not break the "Top Toolbar" functionality. Question here: could we make it so only themes that register an editor-style get this dropdown menu? The point here would be that for a theme that does not, the preview is inaccurate anyway and they might as well get the classic preview button, whereas themes that do opt in, are likely to be closer to the WYSIWYG necessary for the in-editor preview to make sense.
Michael's solution is clever in that it allows a person on a phone to edit/preview their desktop site. However I would also agree it's something to explore separately, and even subsequently, to the inital preview work. One of our biggest challenges here is to ensure uncomplicated UI, and it would be good to ensure the baseline featureset is in a good place first. This will also likely inform the final look and feel of the phone/desktop preview feature (which I agree that would be cool, btw.) Bringing responsiveness to the editing canvas, including phone and tablet, is a mammoth achievement unto its own, worth celebrating. 🎉 |
As a proof of concept, I think we can rely on CSS variables. That said, it feels like a good solution from a technical perspective and not a theming or user perspective. It is a concept the persone creating a theme would have to know about ahead of time when building a Gutenberg theme rather than something that just works as expected.
Yesss! Happy to help with that. I also wonder if the height of the preview should more reflect a phone/tablet size.
We could for now. In the future, I hope that 'editor-style' will be deprecated in favor of a single canonical stylesheet (or a single set of stylesheets). This is probably a good topic for discussion in another issue.
+1 I wouldn't attempt what is in my mockup until we have this first step of a responsive preview complete. |
and
Help me understand the nuance in case I'm missing something. To my understanding the usage of CSS variables will be purely a "behind the scenes" thing to help orchestrate the responsiveness of the editor style, and not something any WordPress theme developer should ever need to worry about, is that correct? |
Ah! If that's the case, I misunderstood. Carry on! |
It's good to clarify! |
Based on @ellatrix 's comment in my previous PR I gather that theme editor-styles will become unnecessary in the (near?) future, so I'm not sure it would make sense to do that at this point. I wonder if we should touch the preview button at this point, or if it would be better to have the resizing controls somewhere else (or even next to the preview button?), to make it clear that they apply to the editing canvas. Users know that preview is a separate page, so adding same-page-related controls to it might be confusing?
That was my idea! Using variables will help us avoid using inline styles. That will improve the canvas resizing experience and it has the added benefit of making it easier for themes to override these styles 🙂 |
Update: for this PR, two major issues remain:
For the second issue, we need to bear in mind that while the Gutenberg plugin has a separate stylesheet for each package, in Core they are all bundled together with wp-admin styles. |
I'm working hard to get you designs and hope to have something we can work with before my break next week!
Can you elaborate on this? Are you referring to editor styles? Or editor styles made responsive by the system? I have a vague idea the answer, for now, might be to inline them in |
@tellthemachines Alright I have some mockups to share. The visual style is inspired by the UI explored in #18667, but the principle should work for the UI we have today: By combining the controls into a single dropdown, we are implying that what you are seeing in the editor is a preview, and grouping with that the options to emulate Tablet and Phone dimensions: To me, that's the V1:
I have some ideas for how we can integrate saving properties for each breakpoint as well, and I hope to share that separately. |
Thanks for the mockups @jasmussen ! I'll start building that dropdown 😄
To make the editing canvas "responsive" we're grabbing all the stylesheets that are relevant to its content, and enabling/disabling media queries depending on the selected breakpoint. (This is why it doesn't work with inline styles.) |
Thank you! I think it will be helpful to test out in actual practice to see how such a popover feels. Is there a better term for "Preview externally"? As noted, this menu item would absorb the functionality of the existing Preview button, which it to say it opens the theme preview in a new tab. Would "Preview in new window" or "Preview in new tab" be a better label? CC @pablohoneyhoney in case you have thoughts. |
:keanu-whoah: I am failing to grasp the full extent, but it does sound like a use case, potentially, for CSS variables. |
@aduth the perf tests show there's a slight drop from the previous commit to this one.
After merge:
I'll see if I can get this to work without running on page load. The resize listener should only really be needed after |
@aduth update on this: The other thing to consider is that Desktop is only a default until we figure out how to make this work on mobile, so we don't want to use it as a condition to not run the function. (Not sure if that was what you meant.) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hey folks, I know I'm quite late to the party so I hope that this late review is an OK place to leave some feedback on this PR. I've been working on integrating a similar feature into a client's site and I have some feedback on this implementation.
Before that though, I want to say that this is a really clever solution - the stylesheet rewriting works surprisingly well and I used it for the bones of my work. Having this starting point was really helpful!
I am happy to take these comments to an Issue if that's more useful. i just figured that being able to leave feedback on the particular lines would make it easiest to parse.
*/ | ||
export default function useSimulatedMediaQuery( marker, width ) { | ||
useEffect( () => { | ||
const styleSheets = getStyleSheetsThatMatchHostname(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
As far as I can tell, we're pulling stylesheets anew every single time this runs which is unnecessary. I think this could be wrapped in useMemo
to prevent it from constantly re-loading.
|
||
if ( | ||
relevantSection && | ||
!! rule.cssText.match( new RegExp( `#end-${ marker }` ) ) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This logic is moderately useful for Gutenberg-written stylesheets but untenable for theme and plugin stylesheets. As an example, I'm currently working on porting a client over to Gutenberg and they have 200+ individual SCSS files that are used in the theme. Adding this rule that makes no sense in any other context to a stylesheet is polluting and doesn't make sense for the other 10 teams working on the site.
I would propose that a better rule would be to look for any rules with .editor-styles-wrapper
or .wp-block
classes in the cssText. This would allow us to not pollute stylesheets with invalid and nonsense rules.
( styleSheet ) => { | ||
return ( | ||
styleSheet.href && | ||
styleSheet.href.includes( window.location.hostname ) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There's a couple of issues with this simplistic of logic:
- I believe this excludes any styles passed in via
add_editor_style
as they're added in an inline style element. - We should additionally be excluding any print stylesheets as they're not useful to this logic.
- We should also be excluding most plugin stylesheets from this list as they don't have any block-list related styles. This probably seems like a micro-optimization, but adding just ACF & Yoast can add 20-30 stylesheets to the editor view which is a lot more rules to be parsing. This would be really difficult to do on a granular basis, but I believe my next point would be able to help with this.
- To reduce the number of rules to parse when triggering a change, we could check for valid rules in a stylesheet and only push through those stylesheets which have parsable rules. On the site I'm integrating this into this change + culling out plugins stylesheets cut the stylesheets being passed here from 60+ to 15. This dramatically sped up the rule parsing when triggering the viewport change.
const { setPreviewDeviceType } = useDispatch( 'core/block-editor' ); | ||
|
||
const deviceType = useSelect( ( select ) => { | ||
return select( 'core/block-editor' ).getPreviewDeviceType(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Could we have a filter to be able to set the default view that authors see when loading the page? Several clients I know of would like to have a mobile-first experience, while other would like desktop view to be the default.
|
||
switch ( device ) { | ||
case 'Tablet': | ||
deviceWidth = 780; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Could have a filter or setting to be able to modify these values? They will change per theme and per client as different designs require different breakpoints.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@mikeselander I just noticed your comments. I definitely recommend creating an issue.
I just happened to be looking at this PR while triaging #21235, which seems relevant to your comments.
I want to call a function in my block when the user edits the resizable preview. Is that possible yeT? |
@niklasp what do you mean by "when the user edits the resizable preview" ? |
A suggestion: Not sure if this is the right place for it, but can we get CSS class names added to the editor-styles-wrapper when the preview canvas sizes are changed? I see the inline styling changing the margins, which makes for the preview container, but some plugins, like ours, use full-width container grids, and they now extend beyond the width of the preview. https://recordit.co/rT2hnNKYzT With simple classnames -has-mobile-preview or -has-tablet-preview added to the editor-styles-wrapper, theme authors would be able to easily change their block max widths when the preview is change from desktop to mobile and tablet previews respectively. There's no way for those block CSS to be changed currently cause the container has no indication the widths have changed at all. |
This seems reasonable! Ideally as a theme developer you should not have to write special CSS just to work in the editor, you should be able to simply write the very same media queries you would for the theme itself (perhaps even use the same stylesheet). Something like #21102 could very possibly enable that. But it does seem like such generic utility classes, in the mean time, would be useful to have. @draganescu do you have any insights or thoughts here? Is there a different API to use until such a day as media queries would work in an editor style? |
We do have a ton of media queries in the backend to get our outer grid containers working on posts and pages that are contained already. They even work when you open the admin up on a phone--but they don't work if the browser window is still 1500px wide while the editor-styles-wrapper has been set to mobile at 375px and our media queries are based on widths. Simple classes would allow me to just add more declarations to the existing CSS I have and set our alignwide alignfull and all of our row/container classes from bootstrap to be sized appropriately during previewing, and it'd follow similar patterns as the color selectors and such has-background-color has-color, etc. |
That sounds painful. I hope that with an iframe potentially being an option, that we can simplify some of those queries. It seems like in the mean time those utility classes could provide a bridge. Would you be willing to open a new ticket suggesting this? A lot of the developers who would work on this are currently busy releasing WordPress 5.5, but if you tag me in your ticket I'll ping some folks on it. |
You have no idea how much I am looking forward to iFrame or something that gets delineated with classes. Our CSS on our grid containers the past year and a half have been set to things like:
This is going to make it so much better. New issue/feature request ticket is here #24488 |
I can imagine it! That's why every effort from simpler editor markup, to this PR we're commenting on, have been small steps on the way there. It remains difficult, and it's dangerous to promise that it works, but the problems it will solve are clearly outlined. Thanks for opening a ticket! |
On the above note, what should theme developers be doing in the meantime? I also write carefully crafted editor styles to make sure my themes look beautiful in the editor. But now that these new preview buttons are so prominent, and the old method of preview made substantially harder, people will be clicking on the mobile/tablet previews regularly and finding they're all broken due to media queries not being applied. Could themes opt to disable the new preview buttons until they're usable with editor styles (or another solution is found)? I see there was originally a mention above of only making the preview dropdown appear for themes which register an editor-style; perhaps it should be the opposite, and allow themes to opt out of the dropdown until it's ready to be used. |
I think before thinking about the iframe solution which is a bit unclear right now because of the backward compatibility implications, we should try to make the style rewriting work for editor styles loaded through the official editor styles mechanism. I have trouble understanding why this can't be solved? |
Have just finished another custom site for a client and am having to go through the process of 'sorry, I know those preview buttons are really prominent, but they're currently completely broken'. Can we pretty please get someone to look at this ASAP? I would really love it if we could go back to the old preview behavior unless the theme opts in to displaying them, given they are totally broken for custom themes. |
Hey @smerriman A better place to add the comment would likely be in a new issue. |
Here's a workaround I'm using until then--its a little ugly, but it'll get the job done for targeting the editor when the width has been changed with inline styles. The CSS below targets the editor-styles-wrapper when it has the mobile width applied.
We have another one for the tablet on some of our block declarations like so:
Our .c9-grids are always set to 100vw, so the code above allows us to change that when the tablet preview is selected. Looking forward to the iFrame and/or at least the classnames as it'll make the CSS a little more easy to read, and ideally if the preview window sizes ever change, this code would break. |
Description
This PR addresses the wish for a resizable editing canvas expressed in #13203.
** UPDATE **
This is ready for proper reviewing now!
Here's what it does:
When a breakpoint button is clicked, it
How has this been tested?
Tested on all major browsers including IE. Unit and e2e tests have been updated.
Screenshots
Types of changes
New feature (non-breaking change which adds functionality)
Checklist: