 So today's session is, the topic is styling blocks. So we have two presentations by Michael Burridge and Justin Tedlock. And if you have questions, drop them in the chat or you can use the hand raise icon. And I'm not sure Michael and Justin, if you want people to wait or maybe just at the beginning of your session, just let us know if you would prefer people to wait till the end or just ask questions as things go. So I will introduce our speaker today. First one up is Michael. Michael, why don't you tell us a bit about yourself? Yeah, I'm Michael. I'm based in the UK. I work in developer relations. You know, web developer, well, actually I started working with web development back in the 90s when the web was still in its early years but I've taken breaks and had done other careers in between and then came back to web development about 10 years ago which is when I discovered WordPress. And yeah, and then made the move into DevRel or developer relations. Awesome. And our other speaker today is Justin Tedlock. Justin, would you like to introduce yourself a little bit? Yeah, sure. So I'm Justin. I'm based in Alabama in the United States. I've been in the WordPress space since around 2005. That's when I was in college. I've worked as a theme developer, plugin developer, business person, writer, a little bit of everything. And so now I'm in developer relations alongside both Michael and Ryan. So that's how hopefully we'll get a bit of DevRel done today. Awesome, thank you, Justin. Okay, so just before we get in, I'll do a couple of quick announcements. So WordPress 6.3 is in active development. I think they just released a release candidate. So if you're interested in getting involved in that, I just dropped a link in the chat. WordCamp US is the next major flagship, August 24th to the 26th. And there will be a community summit that precedes that. The next WordCamp Asia has now been scheduled March 7th to the 9th, 2024. Here's a link to that. And if there's lots of local WordCamps starting to be scheduled post-pandemic. So if you're interested, there is a link to wordcampcentral.workcamp.org where you can see the full list of upcoming WordCamps. Without further ado, I'm gonna stop rambling and hand the presentation over to Michael. Just one more announcement. Gutenberg 16.3 was just released about an hour ago, a couple of hours ago, so that's now available. Okay, thanks, Ryan. Let me just share my screen with me a second. Okay, you can all see the slide, yeah? Okay, so I'm gonna talk about blocks that have complex markup. And then I'm gonna demonstrate a way in which you can give users control over how to style child elements of blocks with complex markup. So block supports is great. Block supports allows you to easily add common styling options to your block, like color and spacing properties such as margin and padding. When you add these supports properties to your block.json file, your users get control in the setting, controls in the setting sidebar so that they can select, for example, text and background colors or the padding that gets applied to the block. But these only work at the root level of the block, which is fine for simple blocks such as a paragraph block or a heading block. But what do you do if your block has much more complex markup? Block supports only targets the wrapping element of the block, so the outer div here. All the internal elements will inherit the colors that the user selected and the margin and padding that they've defined will only be applied to the outer div. But what if you want to give your users options to change the styling of the header element, for example, or even just change the color of the H2? Or perhaps you would like to give your users the ability to style the summary element separately from the details element. Or indeed, do all of this. If your block has complex markup like this, it's not immediately obvious how you can enable users to style the inner elements. But there is a way. And that is by leveraging CSS custom properties, which are also known as CSS variables. CSS custom properties are defined by prefixing the name with two dashes and then assigning a value to it. Then once defined, they can be used anywhere in your CSS style sheet by using the var keyword and referencing the name of the CSS custom property that you'd previously defined. So here the H2 element will have the color midnight blue as that is the value of the CSS custom property that's being assigned to the text color, namely dash dash primary color. They're often called CSS variables rather than by their proper name of CSS custom properties because they work like variables in other languages in that they store a value. So this is the equivalent of writing this, but by defining values in CSS custom properties, you can reuse them across your style sheet to ensure consistency across your site. For example, if you have to conform to a design system. Also, if you need to make a change to a value, you only need to do it once in the custom property. You don't have to search through the entire style sheet to find every instance of the value you want to change. Now, I'm sure you're all familiar with all of this. I'm sure you've all used custom properties. You know, all about custom properties and have used them, but you're probably used to defining them at the root of the style sheet like this and then using them elsewhere in the style sheet, but you don't need to define your CSS custom properties in the root element. You can define them in any element and they're then available to any child element of that element. So, going back to our complex block markup, we can do something like this in our CSS. Notice that we're defining our CSS custom properties at the level of the wrapping div element rather than at the root level as shown a couple of slides ago. So, the div here has a hard coded background color which happens to be dark blue and a text color of white. Whereas the header, our child element has a background which is lighter blue and a text color of yellow, which it gets from the CSS custom properties defined at the top of the CSS there, which gives us a block that looks like this. Excuse me. But this is still isn't very useful as everything is still hard coded into the CSS and it's still not user configurable, but it does lead to another thought. If we can define our CSS custom properties at the level of the wrapping element in the CSS, does that mean we could actually inline them in our markup? Well, actually, yes it does. So, rather than having the CSS custom variables in the style sheet file like this, we can instead put them in the markup like this. So, here we've removed the CSS custom properties from the CSS file and instead we've put them inline in a style attribute in the div tag, but we're still referencing the CSS custom properties from the style sheet file. Yes, it all still works exactly the same. Now, we know that the block editor inline styles when you use the block supports properties that we looked at a bit earlier. As you can see in the screenshot of the rendered markup from a block and we now know that we can inline CSS custom properties and still reference them from the style sheet file. So, the combination of these gives us the idea for a strategy to enable styling of inner elements by users. What we need to do is get the values of block attributes and inline them into the block wrapper element as the values for CSS custom properties. And for this, we can use the use block props hook. So, let's see how we can do that. For this example, let's assume that you want to give the user the option to change the header background color and also the text color of the H2. In this example, I am focusing on colors, but the principles that I'm demonstrating here can be used for any CSS property, borders, so the color width radius of a border, spacing properties such as margin and padding or even transforms like rotate and scale, any CSS property you can think of, these principles will apply too, but I'm just focusing on colors just to keep it simple. So, we're gonna need some attributes. We need to define a couple of attributes in block.json, the one for the header background color and another for the H2 that's inside the header. So, I'm calling this header background color and header heading color. If you wish, you can opt to give the attribute some default values so that some styling is initially applied even before the user starts changing things and that's always a good idea to provide default values. Then over in our edit function, though actually edit is technically not a function, it's a component. So, in our edit component, we need to get the attributes by destructuring them from the object pass to the edit component. Then we define a styles const which takes as its value an object. In that object, we define names for the object properties that are the names of the CSS custom properties we want to use. You can see that they have the double dash prefix that distinguishes them as CSS custom properties. And then for the values, we assign the corresponding attributes and now for the magic bit. We pass an object to the use block props hook. This object has a style property which takes as its value the styles object that we created above. Then just as use block props spreads classes and block supports props onto the wrapping element, use block props will also spread the contents of the object pass to it when the block is rendered. So, in this case, the wrapping div will get a style attribute with inline styles and the inline styles that form the contents of that attribute will be the two CSS custom properties with the values received from the block attributes which you can see if we inspect the element and you can see that use block props has added a class and also turned the object that we created with the CSS custom properties and attribute values into a style attribute on the div. So we've achieved exactly what we set out to do. We've inlined our CSS custom properties with the values from the block attributes. Then if we look at the style sheet, we just make sure that we target the relevant child elements in the style sheet and then reference the CSS custom properties that we defined in the object in the edit component. And then bam, it all works. Now, that's working in the editor, but not in the front end. To make it work in the front end, we do exactly the same in the save function. We destructure the attributes, create the styles object with the CSS custom properties and the attribute values. Notice that both here and in the edit component I explicitly referenced attributes.attribute names. So here attributes.header background color and attributes.header heading color. But you could of course destructure that the attributes first if you wanted to and that would make the code there a little bit cleaner. And we pass the styles object to the use block props hook. So all exactly the same as in the edit component except in the case of the save function, it's use block props.save. When the block is rendered in the front end it uses the same style sheet as the editor. And so since the CSS variables are referenced there, it all works nicely in the front end too. So that's all well and good, except that all the examples I've shown you so far have been JavaScript and offer a static block. For a dynamic block, it's kind of the same but also a bit different. So let's take a look at that. There's a couple of ways to create a dynamic block. You could define a render callback function and pass the attributes to it is one way. The other way is the more modern way and that's the method I'm gonna use here. That is to define a render file in the render property of your blocks block.json file and then create the PHP that will do the server side rendering. An advantage of doing it this way is that the render file receives the attributes automatically. So you can just reference the attribute subject. In fact, because it's PHP, attributes isn't actually an object in the way that it is with JavaScript. In PHP it's actually an associative array so the syntax is slightly different. What's different for here with dynamic blocks is that when we define styles it stores a string rather than an object. So if you recall when we previously passed an object to the use block procs hook in JavaScript in the edit and save functions that we passed an object, what we need to do here is pass a string. So we need to literally build the string that's gonna be passed to the style attribute of the wrapping div. So one thing to notice here because we're literally building the string that will populate the style attribute on the div we need to put the semicolon that separates each of the CSS variables explicitly into the string. Also notice that we're concatenating the two lines into a single string. And then having built the string just as we passed the styles object, sorry, just as we pass style to a style property and the object passed to the use block props hook in the edit and save components. Here we pass styles, the styles string to a style property in an associative array which in turn is passed to the get block wrapper attributes and get block wrapper attributes in the PHP performs a similar function to use block props hook in JavaScript in that it will echo the CSS custom properties as inline styles onto the div when the block is rendered. Then the block which this time is a dynamic block so remember that it's been server-side rendered will look exactly the same when rendered in the front end because it's using exactly the same style sheet with exactly the same CSS properties. And that's it. All that then remains is to add some controls to the inspector control sidebar and some on change functions to allow the user to the use block. To allow the user to then update the attributes and then those child elements or the internal elements of our complex block can be styled by the end user. And that's me done. So thank you, Michael. Does anyone have any questions for Michael? Oh, Jose Guerrero has raised their hand. Do I unmute and chat? Oh, clapping. I'm sorry, I thought it was a raised hand. I don't know how to use Zoom, I guess. Thank you, Jose. Yes. So if there's any questions, feel free to raise your hand and unmute or drop it in chat and I can ask the question. Otherwise, I didn't see any come through in chat. We do have a prepared question, Michael, if you'd like to start there. So I'll start there. So can you do inline styles as a text string in JS the way that you do in PHP? Yes, you can. I wouldn't recommend it. You can do it, but what you need to do, you could build up the string in JavaScript, but you can't pass it to the use block props hook. You'd have to, when you define your block, you could add a style attribute to the wrapper element. But that needs to come after the use block props hook because the use block props hook will put a style element on regardless. And if you have your style attribute on your wrapping element before the use block props hook, it'll get overwritten. So you need to put your elements, say your wrapper element, say a div, then spread the use block props on it and then put your style attribute with the string that you've created. But it's clunky, I wouldn't recommend it. I would recommend using the way I showed, put your styles into an object, pass that object to a style property on the object that gets passed to the use block props hook. So yes, it's possible, but I wouldn't recommend it. I don't see any more questions. I haven't, I don't think anyone's raised a hand. So maybe I'll just wait another minute or two or maybe we've got about 37 minutes left. So maybe we'll just hand it over to Justin. If anyone does have questions about Michael's presentation, drop them in chat and we can ask them at the end. So. I'll be here for the whole hour, so. So without further ado, Justin. So there'll be plenty of time also for to ask Michael after what I do, but so I'm going to take, I'm going to take a different approach to what we're doing today than what Michael did. So I'm gonna, we're gonna do some, like a little bit of live coding today. Actually, I'm gonna share my screen and just closing a couple of things. So as a primarily a theme author, I get angry with the block developer sometimes because as Michael showed, you know, he used CSS custom properties to do some really neat things within his own blogs, but as a theme author, there's no easy way for me to control that from like a theme JSON file. And that's why I get angry with the plugin developers and block developers sometimes is because they're not, not because they're doing bad things, that sometimes they're not thinking through the use cases of how can I really make this easier on a theme author to like it, stand my block, like set up some defaults and, you know, make it like integrated with their theme in a better way. And this is particularly true for like complex blocks. So I'm pulling up a, this is a plugin that I've created a sort of complex with the markup and so on, so progress bar block. And I'll share that in the chat if after I get through. But so we're gonna just show, use it here really quick. And I do need to move, let me move. I have video controls in my way, there we go, all right. So this is just a simple progress bar. Let's add a few values, I don't wanna add a goal. Let's say, I don't know what's a good goal, say writing streak or something by writing streak. And let's say we're wanna make this, this is kind of a fun block, seven writing for 10 days. I actually have to show units and they, all right. All right, so we got a writing streak of 10 days. That's pretty neat. All right, there's a few things here in this block that are kind of styled by the plugin. There's some defaults like say the height, the background color and the foreground color, the progress bar. And there's no easy way for like me as a plugin, like on the plugin side to figure out how, like how do I get the right colors? And like what are the defaults? And that's really a design decision that should happen like for the theme author. All right, so in my style.css for my plugin and you can also integrate this directly into like your block edits as Michael showed. But I'm going to work just from the style sheet file, just for simplicity. So there are several, actually I have several like custom properties that can be overwritten by a theme. But there are certain ways like you have to name your CSS custom properties a certain way to make these work. All right, so like for example, here's the gap property is actually controls the gap between these, like the label and the actual progress bar. And I thought like a 0.5 RM, that's a really standard but what if a theme author wants to change this? Like they want it a little wider, a little narrower. That's up to them. And the important part, and I'm sorry for the lots of dashes here, but we'll get to that. So let's hop over to like my themes theme.json file. And it's, there is a settings and then under these settings, there's a custom. And this is a really fun thing to play around with. So I've created, like my plugin is going to integrate with, see, I'm going to type this out. Like I can set custom properties or custom values for my plugin. So the gap was the one, so let's just make a really big gap for demonstration and hopefully this works and we'll get to an explanation. All right, so save that. All right, so this is just my screen's taking a while to reload. All right, so there's a huge gap there now between the elements. Not exactly pretty, but it allows the theme author just to set like some really basic defaults. And these, by the way, can also be overwritten in this specific plugin. Yeah, like there's a block spacing and you can set that. The user can also set it. The goal here is primarily to make sure that there's a way for theme authors to set defaults. And if you've never used the custom key in a theme JSON, this is a great way to like integrate it with plugins because not in theme JSON, it only supports, for example, if I want to have a ton of stuff. And here, let's say I wanted to like just style a block and only support certain things like color, border, spacing and so on. But if you have custom things, there's no way, no standard way except for to add them under the settings.custom key. All right, so some of the other things we have, let's just update this. Some of the other things we have here are like a foreground color and a background color for, I didn't say my theme JSON. But let's just test this out. Foreground, foreground color. And so I want this to match my theme. And I already have some presets for this. Save trying to think of the names of them. Foreground colors, let's say primary, subsoil. And I can't type when I'm talking apparently around. And just bear with me one second, contrast. And hopefully this actually works. So we're gonna save that theme JSON and we're going to, oh, I had the wrong reset refresh button. But all right, this should be back to normal now. All right, I think I actually have some caching saved, but we can't change those colors. The goal though is to utilize these custom CSS properties in your blocks and make, like if you just said the dash dash wp dash dash custom, and then you can use like your namespace and mine's a little weird. And then your block name and then a property name which would match. All right, so namespace and block. And that can also be written as that with a dash if you wanted. But this all like trickles down to your block and it can be overwritten if you want. And like you wanna have an option for users overwrite it, but hopefully like I'm just giving you some inspiration for helping theme authors integrate with what you're doing. But that's like the big presentation, so I'll just stop sharing there, but as I see someone asked, could you share your GitHub code with us? Absolutely, and I will link this in the chats if I can remember the URL. But feel free to bring any questions in about doing this. Thank you, Justin. That's good. It's great. It's a great presentation. I didn't see any questions coming through chat, but yeah. Yeah, someone was asked for the GitHub code and I just linked it. What is the best way to pull in a theme color palette as options in a block? Wow, they're coming up with the big questions. So we've seen color settings in a custom block. All right, that is a topic, a huge topic actually, but I don't know. I may have some example code. I'm going to look because that's, yeah, it's actually like it's something we probably wouldn't be able to walk through completely just in this presentation. There are a couple of functions that are, yeah, so there's block editor settings, get block editor settings function and PHP that's also something in the data store that you can get. But yeah, to your point. Yeah, I'm looking for some example code because I'm pretty sure I have some. I'm just trying to remember where it's at. Okay, bringing in custom colors. Yeah, feel free to bring other questions there while I'm looking through this. I might actually have an example in this plugin. I was just looking at, like edit block. All right, so yeah. That is not the best example either. Suppose that we have better reusable component that uses color paddock on it along with the use selects. Yeah, I think for me, I've been using a use setting and like targeting color palettes.custom for a few things. Can somebody pull up the use, a link to use setting? Let me see. I can get it. All right. The hook? Yeah, should be. Yeah, use setting. Yeah, under block editor. Yeah, I got it here. Just drop it in the chat. Yeah, you can pull up like use setting color. And then you can, like settings are weird. Like you can go like target color dot palettes defaults, which would be like the core, then color dot pallet dot theme or color dot pallet dot custom. It gets like user defined colors. There may be easier ways to like if the gradients, there's also a gradient drop down. I think it's still, it's maybe still experimental or use more origin colors and gradients which is a long quote name. It's experimental at the moment. And, but I've been using it anyway. Yeah, it depends on the specific use case. I'm bringing any questions don't have to be related to like what we presented either. Like we're here to talk blocks and or anything related to it. Or maybe somebody else has a way of doing the same thing in a different way. You know, I presented one solution to a problem. There's undoubtedly another way to do it. So if anybody knows of different ways to do things. But yeah, as Justin says, you know, we can, if you've got questions outside the scope of what we've been covering, feel free. Well, you guys, these are perfect presentations. No one has any questions. Yeah. Everything perfectly and clearly. So well done. Well done. Yeah. I'm still looking for like a color example over here on the on the on the my laptops. And I know I have some somewhere to block it or get it. Thanks Tobias. All right. I have one but it's using use select and it's very similar to what Anthony I'm trying to say linked. There we go. That's the words I'm trying to say. You can get all of the settings this way. I don't know what this is gonna look like in the thing, but you can get all of the settings for the block editor by doing that. But that is my understanding of use select of use use settings is that this would be doing that under the hood. So I'd recommend using the hook version rather than this, this, the select version. All right. I'm actually gonna go back into like a sharing mode here. So as I finally pulled up something. All right. Yeah. So here is, I'm actually doing this from a theme, by the way, which you can totally use WordPress scripts from a theme. And okay. So this is actually grabbing the entire color palette right here. Use setting. So just import it from the block editor. Use setting. What is, this is actually a custom hook, but this, I'll actually, while we're at it, I'll show you this feature. Say group, not a, I'm gonna hit group. And let's just type a little paragraph. So what this feature is actually doing for my theme is creating like a color selection thing. So you can like change to whatever colors you want. Like really quickly. I've got more work to do on it. But like how I get the colors is entirely like just literally just one line of code. And of course I have to, you know, turn it in like a form that I need for elsewhere and they plug in. But actually I have pretty simple just to grab all the colors at once. Hopefully that helps, I think it was Anthony's question. And I'll be, I'm happy to share like more code that also if you want to get, need to ping me or anything later. It's left here. So anyone has questions about anything and everything? Yeah, sorry. Yeah, burning questions on your mind. Anything Gutenberg WordPress related. Also in the meantime, we do have one coming in, but in the meantime, I encourage everyone to read the developer blog. All three of us have written articles on there and we're in, I'm linking in the chat room, but we're also looking for other developers and designers to like share their own knowledge there. So click the contribution page on there if you're interested and you'll get in touch. All right. What do you have a new question coming in? Not sure if it is a good question for this moment. Have a task to set different default font sizes for different templates or post types. It's a different, okay, you could probably do that with a filter. Nick has, Nick Diego has some, a couple of articles and presentations on doing that. I'm sure you could do it by post type or maybe even template. Are you talking? Are you talking about, let me go back to the question. Set different defaults. Yes, setting different defaults though. Yeah, this would be like a theme JSON thing, right? You want, like I said, talking about the headings block. Yeah, I think you could, there's a couple of filters. You could probably do it on the editor side and you can do it on the, there's a PHP filter I think too. Look, I'm almost positive. Nick wrote an article on the developer block that covers this theme. Yeah, server side filters. Yeah, here we go. I don't know that there's a specific example to, to post type or templates, but I'm pretty sure I'm linking in the chats and hopefully this will be helpful. But yeah, there are filters that where you can change the theme JSON data, which, so if you're style and say the heading block with, like you're saying you set the default font size of, you know, 20 pixels or something for, like the H1 block, you should be able to filter that and change it on the fly. I don't know if it's possible to do that on a per post type basis or template basis at the moment, but that would probably be the place to start. He's added another comment to the chat. So there's a theme, yeah, there's a theme JSON PHP filter, but not sure if it's possible to alter the font size, for example, H1. Yeah, I'm trying to think, yeah, I mean, that was what I wasn't sure on if it was possible to do that. But yeah, if you try that filter, I mean, let me see. You have access to, I mean, you have access to PHP. You can check for users logged in. I guess it would just be a matter if you have access to, like, the post type that you're wanting to do that on. Either of you know, like, if that's available, like globally in the edit, like the edit screen, like the post type name, for example. Let's see here. Getting more tricky. I mean, I guess it depends on if you're trying to control whether it's an H1, H2, H3, 4, 5, 6, whatever. That's completely configurable in the template, but if you're trying to control the font size associated with an H1 for a post type, you might, I'm not sure, you might be able to override some of the defaults. I don't know, this is the theoretical, like you used the approach that Michael did, where you wrap your template and override some of the CSS custom properties. I'm not sure about specificity there. If, like, if something's defined on the root and then the same name is defined inside an element, if it becomes, it overrides a class that uses it. Yeah, I kind of like, or semi-related to this, is I want to encourage us to start, like as designers, to stop thinking about design in these, like, huge, like I want to change it for a post type, or I want to change it for a template, like on these, like, let's start thinking about, like design in terms of like components, like smaller bits, like, and I know sometimes you have to change things per post type, per template or so, sometimes you can't get around that. But when I'm designing now, I approach things much differently than, say, at that, like, top level. I'm looking at it from more of a smaller level. There may be times where, like, for example, I may add, like, a custom block style for a group or something, if I want to style a section, and that might set all the default, like, font sizes and so on, for, like, this one section. I think, like, in terms of, like, the block header, we have to think, like, when we're designing, we don't know where that block's going to end up. So we want to, like, for styling at this top level, sometimes it's not, like, the ideal experience there. I would design, I'm starting at the block level for everything. That's a little, that's a different approach than, like, you know, 20 years ago when I first started learning web development, you kind of designed everything, like, this top down and now it's more atomic. This is another word for it. And that's, like, kind of getting way off topic because sometimes you just need to, to what you're asking, change things for one, for one specific scenario. But maybe it helps, like, you rethink your approach, like, just kind of go back to the drawing board a bit. If, like, you don't find, if we don't find a solution for this or you don't. But I will, I'll actually look into, like, do some, like, real-world testing with this. If you don't mind pinging me on Slack or Twitter or anywhere, I will be happy to dive into that a bit. All right, so we're under the 10-minute mark. You guys working on anything fun you want to share? Yeah, we'll give about nine minutes left. Just a quick reminder that if you, to save the chat for the meeting, you have nine minutes, you have plenty of time, but just, if you want to save the links and everything in the chat, just make sure to save it. Yeah, I don't know. Should we just leave it open for the next nine minutes and see if anyone, if any questions pop up or give people nine minutes back? Yeah, sure, hit us with your questions. Yeah, we can cut it early too, if we can give it up a minute or two. Sure. Yeah, sure, if there's nothing else, I guess we can give people back eight minutes of their day. Yeah, just a quick reminder that WordPress is open source and if you're interested in contributing, you can figure out how to do that in whatever way suits you. If you don't have to be a developer, you can do, you don't have to write code, you can, it's lots of ways. So just hit up make.wordpress.org and all are welcome and yeah, great. Yeah, thanks for coming everyone. Yeah, and thank you to Justin and Michael for putting these great presentations together and sharing all the good info is with us today. Thank you for hosting, Ryan. Oh, anytime.