Open getdave opened 2 years ago
Also cc'ing @annezazu who suggested this idea.
Definitely a good challenge. I wonder if we shouldn't zoom out from the navigation block, and look at this issue in more generic terms across all buttons and links. That would put the effort in global styles and design tools territory. One of the interesting challenges to tackle there, is building some confidence on exactly how we should support pseudo states. Do we need them all, or could we start with just hover/focus?
I think controlling these states from global styles makes sense and I agree with what @jasmussen said. But we need to be very careful how this is going to happen. It does not make sense to control states for a paragraph but maybe for the button block, it does? How do we specify which blocks this makes sense? I guess a block.json support? I guess for the link element it also makes sense so for some elements we are going to have states. We would need to have a design exploration on how we can expose this UI in an easy-to-use way covering both states for blocks and for elements like but not taking much space so the global styles UI is still clean.
Thanks @jorgefilipecosta. I agree it needs to be carefully thought through. Block supports sounds like a good way to indicate whether a given block is suitable for interactive state design tools.
I wonder whether UX wise this could behave in a similar way to the how Devtools handles these states:
@jasmussen are there any designers working (or planning to work) on this that you know of?
block supports sounds like a good way to indicate whether a given block is suitable for interactive state design tools.
Just adding a +1 that this would be both a very cool feature, and it will also need to be thought through carefully, both in the UI design, and how we wish to store the styling state. Over in #38167 there is a project underway (the style engine) to explore how we might improve our saving/rendering of block styles (this come out of the discussion in https://github.com/WordPress/gutenberg/discussions/37495). There's an initial PR for how the style engine might work in #37978.
Aside from the UI, how might hover, focus, active states be represented in the style object, both at the block level and in global styles? Do we need the style object to support nested values, scoped by a list of states, or something like that? How do we ensure we reduce duplication of data so we're not storing too many sets of the same values across multiple states (e.g. if we want the hover, focus, and active states to all be the same colours).
If it's first explored as an individual block support, it'd be good to also get an idea of how it could be centralised in the style engine (and / or made easy to change after the fact).
I think it makes sense to add this control to the theme.json before we build a UI for it. That gives us a chance to focus on the data structure and functionality and get that right without needing to think about the UI.
are there any designers working (or planning to work) on this that you know of?
I responded partially in Slack then forgot to copy it here. Here's an expansion:
It's likely necessary to start with a combination of visuals and pseudo code to figure out a structure that works, and is able to grow if we find the need for a bespoke :active
state after all.
The following a "rough" sketch made with Affinity Photo associated with the Button block settings and one for Global Styles. Meant to inspire. Example using Default, Hover and Visited states. Inspired by the Colors panel and the toggle between Solid and Gradient colors.
I removed the Links which is currently in the Elements section.
- Consider that each state isn’t just a single property change. A focus state is usually underlined, but it could also be a border with a radius, bold text, or a combination.
I want to emphasis this as it's important.
@paaljoachim Thank you for the exploration!
Since this ticket is about the pseudo states which we need for menu items, buttons, and links, should we rename this ticket to reflect that? It can still be labelled for Navigation and be on that tracking issue, but it seems important to not design a nav-block only UI for this.
Since this ticket is about the pseudo states which we need for menu items, buttons, and links, should we rename this ticket to reflect that? It can still be labelled for Navigation and be on that tracking issue, but it seems important to not design a nav-block only UI for this.
@jasmussen I think that's why we have https://github.com/WordPress/gutenberg/issues/27075. This Issue [i.e. 38277] specifically tracks this for the Nav block.
Ah, gotcha. Just wanted to make sure that it's built in a reusable standardized way!
I've updated the description with a note that we should implement as an editor wide feature and not specific to the Nav block.
I think it's better to add the option for the hover state effect to the inspector controls. As it will allow users to make it more personalized.
After some thinking, the approach that @paaljoachim proposed makes a lot of sense to me. I'd like to suggest some tweaks to that idea though:
Instead of using segment controls, I think we should go for a different interface. We use segments (or dropdowns, another possibility I explored), to set values… a tabbed list, on the other hand, immediately implies that the elements below belong to the highlighted tab.
I also think we shouldn't show that interface by default, but allow users to enable it through the ellipsis menu:
Another reason to avoid using segment controls is that they will limit the number of states we can show (due to internationalization). On the other hand, a tabbed list could be easily modified to indicate that it contains extra states (for example, using small chevrons).
One difficulty when it comes to stylizing links and blocks inside the Global Style interface is that Global Styles split the management of colors and typography into two different places.
In the typography section, we could have a new module under the basic settings to customize specific properties.
Limiting the number of properties users can customize will help keep uniformity and good design practices throughout the design (although it'll reduce the expressiveness of the websites users can create).
Alternatively, we could show those settings in this way instead:
And there are several possibilities to give color styles to links and other blocks, but the one that I think is more simple is to implement the tabbed list after the user select “Links” from the list of elements.
That said, in my opinion, using popovers to change colors would be the ideal solution because it would remove the need to navigate through several stacks.
Here's the Figma file where I explored these ideas. Props to @jasmussen to help me with some good feedback.
@javierarce I've added this to the agenda for this week's Core Editor chat.
@getdave great, thanks!
It was discussed in Core Editor chat here.
One thing that I think we should be cautious of with the "Show states" toggle is, that it adds a lot of additional clicks to your workflow if you want to modify the hover state of multiple blocks. Instead of a local component state, I would recommend that this toggle is a more persistent setting that a user may be able to activate.
I'm not sure what the mechanism should be but just calling this out as a concern :)
Besides that, I think these are great designs for this interaction and I am excited about this being worked on 🚀
Thanks to everyone involved!
I wonder should we drop :visited
as I"m not sure if that's possible to style due to security concerns.
I was thinking :focus
would be better as that's important for a11y.
Also I'd like to see what folks thinking about potential data structure for this in Theme JSON. Perhaps @jorgefilipecosta would have a view?
I wonder if these states will end up showing in many places? depending on the block, they may affect very different properties. If we are talking links I expect to be able to control text color, text decoration, outline?. If it's a button or, in the future, an input, I may need to control borders and border colors or styles. I can think of cases where I may want to change the padding on hover for example if I want to get creative.
I wonder if these states will end up showing in many places? depending on the block, they may affect very different properties. If we are talking links I expect to be able to control text color, text decoration, outline?. If it's a button or, in the future, an input, I may need to control borders and border colors or styles. I can think of cases where I may want to change the padding on hover for example if I want to get creative.
That's something I considered and mentioned in the Figma file:
Limiting the number of properties users can customize will allow keeping uniformity and good design practices (although it'll reduce the expressiveness of the designs users can create).
With this exploration I tried to follow a pattern I've seen here for other design tools and features: offer functionalities that give as much control as possible but make it difficult to produce "bad" design.
With this exploration I tried to follow a pattern I've seen here for other design tools and features: offer functionalities that give as much control as possible but make it difficult to produce "bad" design.
I see what you mean... I wonder though if we could leave more options to theme developers to control if we decide we don't want to surface all possibilities. Text decoration is a good example of a case where it's not common for all blocks to want to surface that control but it's very obvious that theme will want to set a default for. It's a case I've actually had to write CSS for in the last... maybe 5 block themes I've worked on. Maybe the UI is more restrictive but theme.json will let you cover more cases?
Ah so the UI would only offer a subset but you could control a lot more via Theme JSON? At that point what are the benefits over standard CSS? I guess so the information can be parsed and consumed by non-web clients?
This is going to be tricky. If we open up the idea of controlling interactivity states via the UI, it's inevitable folks will ask for more control via the UI for other things (even things that might be "bad" for design).
An alternative way to reveal the state selection interface:
https://user-images.githubusercontent.com/4933/169264058-d296d65d-bc72-4585-b1d6-318c0610bd29.mov
I like this last way of revealing the different states, I think it has promise. One addition to consider is surfacing modified values better in the default collapsed state. We had this stacking presentation in the global styles mockups that can be repurposed.
In this case, "Links" has both a default color and a hover color, and both are expressed as a stack.
One addition to consider is surfacing modified values better in the default collapsed state. We had this stacking presentation in the global styles mockups that can be repurposed.
Oh, good idea, I'll incorporate it into the design.
@javierarce Both myself and @draganescu are actively exploring this route in code. It's early days but just so you know we're intending to advance this in a generic way in order that it is applicable to all blocks.
Ironically, it's likely that the Nav block will be the last block to gain the enhancement, as it - necessarily - uses a custom implementation of the color controls so it won't automatically gain the new interaction support if/when it lands unless we refactor that aspect.
I've added a new prototype to the Figma file to showcase how this solution to display the properties could work inside Global Styles:
https://user-images.githubusercontent.com/4933/176466008-a38e139e-abfe-4449-a119-a18547c835d7.mov
Using descriptions to explain each property could be nice if we found a succinct way to describe each of them. Otherwise, we could maintain the original order:
We've iterated on this in https://github.com/WordPress/gutenberg/pull/41786 and I'm currently working on https://github.com/WordPress/gutenberg/pull/41976.
I have a video overview of this if folks want a quick review.
After merged of https://github.com/WordPress/gutenberg/pull/41976, the next steps are:
:hover
on link
elements within **blocks** in Global Styles UI (currently only top level is supported).:focus
and :active
states in the Global Styles UI for link
.@javierarce what do you think about reusing the three dots interface to show/hide the hover state controls? This is how it looks for typography:
@scruffian I think it's a good idea (I suggested it here but I forgot to add the other existing options inside the menu). I can imagine two possibilities: as a toggle for the feature, or as a list of properties that users can turn on and off.
The second option has the nice benefit that users can see which properties are enabled… but I wonder if the list will be too long in some cases.
Were you thinking of one of those solutions in particular?
The only thing I don't like is when we then go to Global Styles: we end up having three ellipses in this weird configuration (although maybe it's a good opportunity to remove the one in the middle and find a better location for the item inside).
Is there anything preventing adding button hover/focus/active to theme.json without the UI?
No. I believe @MaggieCabrera is working on that right now.
I think this comment is within the scope of this issue, but if not please let me know and I can make a new post.
For keyboard accessibility, we're using focus-within
to add an outline to links and buttons, like so:
The trouble I'm running into is providing an appropriate color to buttons based on the background color. For links and outlined buttons it's easy - just use outline-color: currentColor;
and call it a day.
For regular buttons, there isn't really a great way to access the background color. The best way I've been able to come up with that continues to leverage the style engine and avoid redefining my full color palette in my theme's CSS is the following:
Iterate through the color palette and define a CSS custom property for each background color selector, then output that CSS at the same time as global-styles
:
/**
* Iterate through color palette defined in theme.json and output additional styles for theme
*/
function global_styles_supplemental_colors() {
$global_styles = wp_get_global_settings();
$color_palette = $global_styles['color']['palette']['theme'];
$supplemental_css = "";
foreach( $color_palette as $color ) {
$slug = $color['slug'];
$supplemental_css .= ".has-$slug-background-color{--bg-color:var(--wp--preset--color--$slug) !important}";
}
wp_add_inline_style( 'global-styles', $supplemental_css );
}
add_action( 'wp_enqueue_scripts', 'global_styles_supplemental_colors', 100 );
Then in my theme's CSS, add:
:where( :not( .is-style-outline ) ) > .wp-block-button__link {
outline-color: var( --bg-color );
}
This doesn't really feel great though, especially the fact that I'm having to re-output the .has-$slug-background-color
selector.
Perhaps there is a better way to hook into the style engine to add this directly to the .has-$slug-background-color
selector and add what I want there, but I have searched around quite a bit and not found any documentation that points me in the right direction.
@eric-michel I do something similar with custom properties on my non-theme.json themes, which also easily allows for default text/link colors to be associated with each background color. This anecdote might be worth dropping into https://github.com/WordPress/gutenberg/issues/39372.
@cbirdsong
I do something similar with custom properties on my non-theme.json themes, which also easily allows for default text/link colors to be associated with each background color.
Funny you mention that, because I just finished doing adding same thing to our theme 😁. I'm glad someone else is using similar methods. I'm always worried I'm missing an obviously better way of handling these things.
Hello everyone.
It would be great to get some movement in this issue. Links states came up in two comments. Linking to the second comment. https://github.com/WordPress/gutenberg/issues/4543#issuecomment-1493752657
One thing I'm curious about is how to represent the cascade as you manage different states.
If we just duplicate the default state then it becomes quite tricky for the user to understand which controls / values are inherited, and which are specific to the state they're editing.
For example, in the mockup below it takes a lot of scanning to work out the differences, and this is with both panels visible at the same time. Obviously it'll be much more tedious when you have to click back and forth.
Having per-panel state management helps with this, but convolutes the Inspector quite a bit when more than one panel entertains different states.
I just want to add in here that there is a parallell discussion going on here: Add Button Hover Color options on Button Block https://github.com/WordPress/gutenberg/issues/4543#issuecomment-1494554414
I've been looking at an interface for interaction states. I think it's important that we design an interface that allows for multiple states, like both hover and active states. I also think it's important we design an interface that supports not only interaction states, but also content (or data) states, like loading, error, or empty.
https://user-images.githubusercontent.com/191598/230945034-e30379bd-fb29-418b-a5ca-ebc9c468dc70.mp4
That looks really good Shaun @shaunandrews I do wonder if Link States should be in it's own panel component.
This has to be a must have option for blocks especially navigation block. As even if we add hover using code its not easy for users to manage / change it using editor which is a really downside. Please if this could be taken as a priority would be really great, Thanks 🙂
Hi @nathanrodrigues2111 Nathan. I believe this issue has not moved forward as there are still some design considerations that needs to be done. Perhaps it is time to relook at this issue in relation to design. To see what kind of user interface would be natural to focus more on for this unique feature as well as using something similar for other more complex features. After the beta for WordPress 6.3 has been released there will be more time to be able to focus on this issue.
@paaljoachim Thanks for the prompt reply looking forward for the for this feature in the future 🙂
@paaljoachim any update on this one? Would love to see this getting pushed further.
If I remember correctly I believe @getdave and @MaggieCabrera have been looking into this feature and that there is something that needs to be done first before focus can get to this.
From what I recall, the foundation of this feature is available in Theme JSON. What's needed now is someone to continue to implement a UI to expose this for all blocks that need it.
I won't be working on this during the 6.5 cycle as I am unavoidably focused elsewhere.
@getdave is there documentation or clue on how to add a new tab (for hover) to the color picker? I tried to find it with no success. I may be able to help with that.
What problem does this address?
Currently it's not possible to modify the visual styles when the block items are in a given state (hover, focus, etc).
States (#57719) was designed as a solution that could work for this use case, including the hidden complexity that isn't immediately obvious. Consider a navigation menu, you'd want to be able to change colors of menu items in their neutral, hover, focused states. But most likely, you'd also want to be able to change their border, background, perhaps font-weight or text-decoration in those states.
Secondly there is the need to combine properties into new states. Consider the same navigation menu, menu items can have current states. E.g. when you navigate to
/about
, the "About" menu item should be highlighted as the current menu item. This state cannot inherit the hover and focus states from default menu items, you might have a blue hover color which wouldn't work if you added a black background:In other words, the state proposal suggests that "Hover" is one property that can make a state. "Current" and "Hover" properties together, make a new state.
The state design can solve both those complexities:
Here are mockups that extrapolate on Saxon's work to test it for both a Button state, and a navigation "current menu item" state:
This could work as a starting point, and as the states concept gains features, it can be expanded upon.
Figma.
Issue updated May 7th.
Past version of this issue
Examples include: - hovered - focused - active ## Update We've iterated on this in #1786 and #41976. [A video overview](https://www.youtube.com/watch?v=XikXzLLojhk) is available. After #41976, the next steps are: - [x] Fix https://github.com/WordPress/gutenberg/issues/42055 - [ ] support `:hover` on `link` elements _within **blocks_** in Global Styles UI (currently only top level is supported). - [ ] implement the "disclosure" pattern from @javierarce's designs from https://github.com/WordPress/gutenberg/pull/41976#issuecomment-1170067066. - [ ] add support for `:focus` and `:active` states in the Global Styles UI for `link`. - [ ] Add color swatches for the first two "states" in the Global Styles element overview item (see https://github.com/WordPress/gutenberg/pull/41976#issuecomment-1170078408) - [ ] Enable setting Navigation block link color from global styles. Requires https://github.com/WordPress/gutenberg/pull/42092 to be resolved as [Global Styles checks supports to decide whether to enable the panel](https://github.com/WordPress/gutenberg/blob/b5de5fc1af8acbd83495d045f7d86aa902c9ae2f/packages/edit-site/src/components/global-styles/hooks.js#L173). ## What is your proposed solution? Provide design tools that allow setting visual presentation for those states. Likely these will be [implemented as an editor-wide feature](https://github.com/WordPress/gutenberg/issues/27075) rather than something that's specific to the Nav block. I will defer to @jasmussen and @javierarce for their thoughts on how this might happen. Also pinging @jorgefilipecosta who may have some insight onto whether Global Styles intends to handle this in future.