premium training

LJSK: Welcome Bubble 02

This is a premium training for Inner Circle members only.

More about this video

In this video:

  • Fixing button focus styling.
  • Switch the if/then to “toggleAttribute()” for better efficiency.
  • Add aria stuff for accessibility (popup, labelledby, etc.)
  • Make pop-up close with an accessible close icon.
  • Make pop-up close with escape key (accessibility)
  • Automatically focus on first focusable element (accessibility)
  • When pop-up closes, return focus to trigger (accessibility)

Still to come: Need to figure out how to trap focus in the popup.

Video Transcript

Hey everybody, welcome back. This is round two of the welcome greeter pop-up bubble thingy. And we’re just going to review real quick what we did or what we’ve gotten to so far and then we’re going to get started with a lot more stuff that we have to do. And it’s crazy, it’s crazy that like, okay, this is what we’ve gotten to is like you click on this and it puts a little welcome message. I mean, it seems like such a cute little simple thing, but it is the kind of thing that just kind of gives you nightmares, and you’re gonna see why.

You’re gonna see all the things that you have to kind of account for to really do this the right way. And so basically we’ve got the bubble, the floating bubble. We’ve got the message. It appears when we click. Right now we have no way. We can click the thing again.

We can click the bubble again and close it, but there’s no way to close it from inside, which means this isn’t really accessible. We need to make a close icon in here to close it. We have to focus on the first focusable element. We have a lot of stuff to do. Let’s go ahead and start tackling it. I’m going to go into Edit with Bricks.

I’m going to open this up. Remember that we put everything in a code block. So all of the stuff that’s happening so far is happening within this code block. And the first thing that we wanna tackle is just to try to make what we did a little bit more efficient. So we used an if else statement to basically say,

and I’ll just kind of read this code for you, reiterate what’s going on here. We have a variable called greeter button, which selects our button. That’s this floating thing right here. And so what we’re doing is we’re adding an event listener to that, listening for a click. And if there is a click on that button, we’re saying if the style is display none, we’re going to set it to flex. And we’re using inline styles.

This is putting inline styles on our greeter message element, which is this box right here. So we’re saying if it’s none, set the display to flex, else, set the display to none. So if it’s anything other than none, set the display to none. And that effectively shows and hides that message. Now we can remove this if else, this is the first thing that we’re gonna do. And we’re gonna take a look at doing this a different way.

The other thing I’m gonna do is go to my greeter message right here and I’m going to go to attributes you’re going to see that by default the style was set to display none. We’re going to remove that. We’re going to go back to our code over here and we are going to so we remove the display none by default. We remove the if else changing the display to something else yada yada yada and we are going to experiment with using a data attribute to do this instead. I’m going to use the same event listener click function and then I’m just gonna check my notes over here and go down. There’s a lot to cover in this episode so rather than trying to do all this off top of my

head I’m not there yet right this is learn JavaScript with Kevin not learn JavaScript from Kevin. So I’m gonna go ahead and just refer to messages. We’re gonna take our greeter message. So remember, when the button is clicked, we’re gonna take our greeter message and we’re gonna toggle an attribute. Now this is something somebody had recommended in the comments of the first video.

And I went to chat GPT and I even asked if this was a possibility and it said no, it was fucking wrong, like usual, okay. Then I did some more digging and yeah, you can use the toggle attribute in this way. So we’re gonna create our own attributes, gonna be called data pop-up open. We’re not gonna give this thing a value,

you don’t even need a value, because remember with CSS, you can essentially style an element if it has a data attribute or not. It doesn’t matter if the data attribute even has a value, you can just check for the presence of the data attribute essentially. Okay, so we’re gonna say greeter message,

toggle attribute data pop-up open. This is gonna be, you see how this became more efficient. We got rid of an if else, we got rid of a bunch of lines of code, we replaced it with just this thing that’s gonna toggle this attribute data pop-up open. Now, do we expect anything to happen on the front end? No, so what we need, as you can see,

we can already see the message when this page loads. But what we want to do, number one, we want to check our console, make sure there’s no errors. Then we want to find this message, right? Okay. And when we click on the button, we want to see if anything is added to the message. And as you can see, absolutely nothing is happening. So we’re going to go back and we are going to, let me get our sidebar open here

so we can easily go back and forth. Oh, it’s, so obviously this new workflow with the signing code and all of that stuff, you gotta remember every time, every time you touch this code block, you gotta sign the code again. It’s really annoying. Just don’t forget,

because your shit will not work, okay? Look what happens when I click data pop up open. I click it again. No data pop up open. All right, let’s see that again. I click there’s data pop up open. I click again. There’s no data pop up open.

So we’ve effectively made our code more efficient. Now what we have to do is go into CSS land and say, okay, when this thing has data pop up open, or when it doesn’t have data pop up open, we need to do something to it, right? So I’m gonna go to the message, greeter message right here, and I’m gonna say root, and I’m gonna say not,

and then we’re gonna say data pop up open. When you’re styling data attributes, you use the square brackets, okay? So root not data pop up open. So if it doesn’t have data pop-up open, I want it to be displayed none. Now that you can see that because it doesn’t have the data pop-up open, obviously, it went away. The problem here is we’re working in a page but we need to be able to see the thing in the page builder to be able to do things to it, right?

So we need a way to exclude the builder and if you inspect in the builder, we don’t really have to do it right now. It’s annoying to get to it. But if you dig down in the DOM inside the builder, what you’re gonna find is that almost everything in Bricks has this class BricksDraggable. And so if we exclude BricksDraggable,

so it’s not data pop-up open, and it’s not BricksDraggable, then set the display to none, which is essentially excluding anything with BricksDraggable, which only exists in the builder interface. This does not exist on the front end. So if I save this here and we go back to the front end,

we’re not gonna see our message, right? Now I click this and it appears and I click it and it goes away. Like that is all that was required, right? Because what’s the opposite of the not? Well, it was displaying by default. It’s there and you can see it by default, just like any element you add to a page.

So we’re only hiding it, right? If it doesn’t have data pop-up open. If it does have data pop-up open, then we’re hiding it. But if it doesn’t have it, it’s just gonna go back to its normal statement. So very, very, very efficient from a CSS standpoint and fairly efficient, it seems, from a JavaScript standpoint as well.

So I’m gonna go back to our code. That was the first thing that we wanted to check off of our list. The next thing that I wanna check off of the list is the button styling, focus styling. So if you notice when I tab to it, it has a box shadow because that’s the styling of focus elements that I use with Automatic CSS

on most websites. You can use an outline focus style or you can use a box shadow focus style. Well, if you remember back to episode one, let me get focus off of there, we’re already using an outline, right? And we animated the outline on hover. And so when we focus, we definitely don’t need a box shadow on focus. Okay? So we’re going to remove that first. So I’m going to go to my avatar button right here, and we’re going to say, root focus visible.

All right.

So when when the focus is visible, we’re going to say the box shadow is none. And I’m going to make sure we just importantize this. Never allow a box shadow on this thing when we are focusing on it. Right. So now I will go back to the front end, we’ll refresh. And now I focus on it.

Now nothing is happening, right? Because I just removed the default focus style. Now we’re getting nothing. All right. So we’ve got to fix that. What we want is when we focus on the button, that avatar, and this is a little challenging,

the avatar inside the button is actually what has the outline and all of that stuff going on. Okay, I’ll show you that right here. And this is actually wrong. We did this wrong in the first one, right? Because we’re not really concerned with hovering and focusing the avatar, we’re concerned with hovering and focusing the button, which is like the

wrapper of the avatar. So I’m actually going to remove this, all right? And it outline offset six pixels is what we want to have happen. Okay, I’m going to go to the button, we need to target the avatar inside. This is kind of sucks because we have to write that class statically, so greeter avatar. I don’t know if we have to maybe greeter avatar, we would have to maybe refactor a little bit to make this be dynamic somehow and not have to statically reference

this. But I’m essentially saying when we hover the button or when we focus visible the button, we’re going to change the outline offset of the greeter avatar to let’s say five pixels. And you can see that it’s still working right there. But the difference is we should, also happen, there you go, on keyboard focus. Okay, so that is an improvement. Now I’m also going to say outline width. Let’s go to two pixels there. And I probably should variabilize these things as well, tokenize these things, but maybe maybe that’ll be at a later date. That’ll be in the official version. But now it gets thicker when I focus and it would also get thicker when I hover as well. So it kind

of helps show the focus state there a little bit better. Okay, so we fixed the button focus styling. We switched to the more efficient toggle attribute. The next thing we need to do is some stuff for accessibility with ARIA. This is considered a pop-up. Okay, it’s not considered a modal, it’s considered a pop-up. So we need to add ARIA has pop-up dialogue to the trigger. Okay, so what we need to tell assistive technology, here’s the button right here, this is the trigger for everything that’s happening, right? We need to go to attributes and we’re gonna say ARIA has pop-up and then the value is a dialogue because what you’re essentially saying is hey by the way

if you can’t see what’s going on here assistive technology uh this button is going to trigger a pop-up it has a pop-up attached to it essentially and then you’re telling it what kind of pop-ups there’s multiple kinds of pop-ups like a menu is a is a pop-up okay there’s one called a dialogue we’re going to be using dialogue so aria has pop-up of dialogue. And then what you’re gonna do is you’re gonna go to the message and identify that, hey, this is the dialogue here. This right here is the dialogue,

and we have to essentially name it, okay? There’s a lot to accessibility. I’m sorry if you’re new to accessibility, this is probably a lot to digest. But we need to add role equals dialogue to this message. This is effectively the dialogue box, okay? So we’re gonna add an attribute and we’re gonna say role is dialogue. So we the button says hey, you’re about to pop up something called a dialogue and then we’re identifying that

Hey, this thing right here is the dialogue and then we need to say aria-labeledby And aria-labeledby is a way to label the dialogue using an element that’s already in the dialogue, using like the, typically the heading, right? And so we’re going to say the value is, it’s going to be the ID of this heading right here, which we can call the message, let’s call it the greeter heading, okay? So the greeter, we’ll just say yeah, greeter heading like that. Remember that IDs have to be unique.

So greeter heading obviously doesn’t exist right now. What I need to do is click this heading right here, and we need to edit the ID and say you are greeter heading. Okay, so now that has the ID of greeter heading. And the message is labeled by the greeter heading. So it’s giving it, let’s make sure you don’t miss anything, which I don’t know if that’s the best. I don’t know if that’s the best

because it doesn’t really describe what’s going on. And so we need to maybe think about cleaning that up a little bit, but this is the practice of how you create the dialogue and then use ARIA labeled by on the actual dialogue. Okay, so we check those boxes. They may not be perfect, but at least we checked them for right now.

We need to make the pop-up close with a close icon, okay? And we need to make that close icon accessible as well. So the first thing we need to do, we can’t make it close with a close icon if we don’t even have a close icon. So the first thing I’m going to do is add a close icon. This is already position absolute, this message, so it’ll trap any other absolutely positioned elements. So I’m just going to add a div.

That div, as you probably know, is going to become the button. We’re going to call that close button right there. I’m going to add an icon inside of that, okay? And we are going to use an SVG always. I try to avoid things, font, like libraries, icon libraries, like the plague. I just use individual icons. These are usually called crosses. There’s one right there, okay?

And we are going to download the SVG we will go in and we will upload the SVG where did it go okay let’s go to downloads let’s go here okay perfect let’s go insert that very very very very nice okay this is going to be we’re gonna hit an accessibility text let’s go text okay this is going to be the hidden accessibility text. Great, fantastic. This is going to say close dialogue and what we want to do is we want to use the automatic CSS class hidden accessible to hide that. Our close button needs a class now so this is greeter and we’re gonna say close, greet or close like that. Perfect, all right, let’s go to flex

and I just want those things to be side by side. Let’s go to position this absolute, position absolute and top, we’re gonna go like 10 pixels and then right, we’ll go 10 pixels from the right as well. Now this is gonna look different because the A is not gonna be there on the front end. That’s just a back-end thing alerting me

to the presence of accessibility text. Let’s go look at this on the front end and see what we’ve got. We have a close button. Let’s make sure that we made it an actual button. I don’t remember doing that, but maybe I did. There’s a lot going on. No, I didn’t. See, this needs to be custom button just like that. Then what I can do is go because it

gives it a default background color. The browser does this. I’m gonna say transparent. And now if I go back to the front end, that should be an actual button that is focusable and selectable and clickable and all of that. Okay, so the button is there for us now.

What we now need to do, did you guys expect this to be this complicated? Like a little cute little welcome message, just creating these kinds of nightmares. Alright, you wouldn’t expect it, you wouldn’t expect it, but it is the case. Okay, go to code, go to code, and what we need to do is we need to be able to select that button. We’re gonna assign that to a constant, a const, a variable, okay? So we’re gonna say const, and we’re gonna say greeter close, greeter close button.

How about that? Equals document dot query selector, and then what is the equals document.querySelector and then what is the selector? We gave it a class of greeter close, just like that. So we have something called a greeter close button that we can target now. And what we want to do is come down and say close on click, okay?

Close on x click, like that’s the x, like the icon the X icon. We’re gonna say greeter close button okay add event listener. I’m copying essentially what I wrote right here I’m just changing what I’m targeting right and then we’re gonna say we’re gonna look at look for a click we’re gonna do a anonymous function we’re gonna come down here close that and then we can say greeter message. In fact, I can just grab this and hit it. But the difference is I don’t want to toggle the attribute.

I will just want to remove the attribute. The only time you’re ever seeing the close button, the X is when the thing is already open, when the attribute is already there. I just want to remove the attribute when somebody clicks on the X, right? Okay, so let’s just go ahead and save that. Remember to sign the code.

All right, let’s hope this works. Greeter, close, button, okay? I mean, it’s looking right to my dumb eyes, but let’s go ahead and refresh. And now we open, close, open, close. Now, let’s also see the benefit of this is that it should also work by default with the keyboard. So I focus on it, hit enter, and there you go. It closes.

Okay, so that box is checked. We’ve made the pop-up close with a close icon button. Now we need to make the pop-up close with the escape key. For accessibility purposes, they expect that this pop-up will close with the escape key as well. So we’re going to come down and we’re going to say close with escape key, all right? And we’re gonna say, how do we wanna do this? Okay, so we need to add another event listener, all right? We’re gonna add an event listener of a key down, but where are we going to add the event listener?

So escape key, the entire document essentially can listen for the escape key, all right? So all we have to do is say document.addEventListener, addEventListener, and then we’re going to look for key down, and then we’re going to do a function, and then this time our function is going to be the event. I’m going to come down here, I’m trying to do some of this from memory and just

understanding the syntax of everything. So I’m adding an event listener key down to the document. I think what we want to say is if, because it’s not any key. If they press M, that should not close it. We’re looking for the escape key. So if event, and I’m saying event because I used the event in the function right here.

Basically saying we’re looking for an event. What event? Okay, event dot, now I can’t, I’m gonna refer, I’m gonna refer to the notes cause I can’t remember off the top of my head what I’m actually looking for. Event dot key, okay?

So a specific key attached to this event. And then we need to use a triple equal sign. This is how you say, effectively say equals in JavaScript. It needs to be the escape key. Okay, so I’m looking for the escape key. So if the escape key is pressed, what exactly is going to happen? Well, let’s grab this. So take the greeter message and remove the attribute data pop-up open. But there’s one

other thing that we have to do. We have to make sure that nothing else is affected by the escape key. Okay, so we’re going to say event again, calling this right here, event dot prevent event.preventDefault, I believe. Now let me check my notes. It is, that’s correct, okay? So event.preventDefault, basically prevent any default things from happening when the escape key is pressed, given that we’re using it for a very specific purpose here.

At least that’s the way that I understand it and read that happening. Okay, so we are going to sign code. We are gonna save. I hate this work, because I always save, And then I don’t think signing the code actually saves and I’m not sure if you have to save again after signing. So I just, I’m like, save, sign code, save.

It’s kind of annoying. All right, I think, let’s just close with escape. Let’s just figure out, let’s just, is it happening? Is it working? Okay, let’s open our, not our page source. That’s not what we want. We want our console, okay? Let’s make sure there’s no console errors. Excellent. So I open

that and then I hit escape and it closes. Fantastic. Now if I trigger it with the keyboard and then escape it also closes. Also fantastic. Okay really really really good. We need to, so when you trigger this with a keyboard, not with a mouse, but with a keyboard, by default, you need to focus on the first focusable element. Okay. The first focusable element is this button, right? So this is just what keyboard users expect. Assistive technology for accessibility purposes, expect that when you open a pop-up like this,

you’re going to automatically take the focus to the first focusable element. So all this accessibility stuff is really what adds a lot of complication. Okay. So I’m going to say focus on first focusable element. We’re going to come down here. And essentially what we need to do is first of all, just identify focusable elements. Like we need to essentially grab a list of like, what are the focusable elements

available, right, on a given webpage. So what we’re gonna do is we’re gonna say greeter button, first of all, we don’t need to do any of this until somebody clicks a button. Like when they click the button to open the greeter, that’s when we can worry about finding focusable elements and all that stuff, okay?

So we’re gonna say greeter button, add event listener, and we are going to remember this is only only when they trigger this with the keyboard okay so we’re gonna add event listener and we’re gonna use the key down again the function is gonna be an event all right and we’re gonna open this and we are going to close it like that okay perfect now what we’re looking for is the enter key that’s the key that they are going to use to trigger the pop-up.

So we’re gonna say if event.key equals Enter. All right, so if it’s the Enter key that they’re pressing, remember, we’re already looking for any key press, okay? But if it’s this specific key, Enter, then we actually want to go and do something. Now, I realized in my testing of all of this, this is very important. Well, actually, I’ll add it after the way I did

because I didn’t even realize you needed it first. So I’ll do it the way I did, and then I’ll show you what I had to come back and do to correct it, okay? So if event key is the enter key, okay, what we want to do is first assign all the focusable elements to a variable. So we’re going to do const focusable elements, right?

And then we’re going to look for this, if I can type the correct quotes, we’re going to look for a list of things, all right? So the first one is A with an href. That’s obviously a focusable element, right? The next one is button. There’s also could be an input in here if it’s a form. Text area is another kind of input.

Select is another kind of input, if we put a drop down in there or something like that. And then anything with tab index that is not minus one, and actually it has to be tab index again, tab, yeah. I can never remember if there’s a dash between tab and index. The syntax is the hardest part of all this shit, remembering how the syntaxes go.

Tab index equals and then not minus one, like that. So essentially what I just did is I created a list of all focusable elements assigned to this variable focus element. Now what I wanna do is I wanna make another variable called first focusable element because that’s what we really care about. We don’t care about all the focusable elements.

We care about the first focusable element. So what we’re gonna say is, I believe we do focusableElements.querySelector. And let me refer to my notes here. Yes, oh, I’m sorry. It’s not, okay, it’s not focusableElements.querySelector. It is greeter message. So we’re looking for selectors, query selectors,

inside of greeter message. Which ones are we looking for? Okay, and we are looking for focusable elements. All right, and then we’re gonna close that off. I believe that’s all we need. greeterMessage.querySelector, focusableElements. Excellent, that’s all we need. Now, you might be thinking, okay, hold on, Kevin, hold on. You,

you got a list of all focusable elements and assigned it to this variable right here called focusable elements. Then you created a variable called first focusable elements. And essentially you just got the list, but no, I didn’t just get the list query selector. All look at this as query selector. Query selector all would get the list. Query selector by default without the word all

just gets the first item in a list, okay? So it automatically when I say get the list but I only use query selector instead of I’m not saying all of them, I’m just saying query selector, it’s just gonna grab the first one and since the first one’s the only one I care about, this kind of just works out naturally.

Hopefully I explained that right. Okay, now what we have to do is we have to come down here and say, because remember all I’ve done so far is take the first focusable element and assign it to a variable. So what I want to do now, I want to say if first focusable element, okay. Essentially saying if first focusable element exists. That’s what this if statement is doing. Then I want to say first focusable element dot focus and I’m just assigning focus to it. So this is kind of like the way I understand it essentially it’s kind of a shorthand like if if this thing exists but this is all you have to write. It’s very

simple. So if first focusable element exists then give it focus. That’s what this is doing right here, attach focus to it. Okay, and then that’s it for now. There is one more step, cause I think you’re gonna see that this does not work. Okay, all right, so we’re gonna hit save.

We’re gonna go to the front end,

and we are going to, remember, that was only gonna happen on keyboard. Okay, so it opened, but no focus on the first focusable element. And I was debugging this, and I was like, why, why, why, why? And it turns out that it can’t get this list going like in that time span. Like things happen too fast.

So we need to add a delay. We need to add what’s called a timeout, okay? So after enter right here, we are going to set timeout. And the way you do this is open and then two more parentheses, like you would put something in there and then we’re gonna use an arrow function. We’re gonna open that function and then we have to come down here and we have to close that function

and I’m just trying to remember because if we’re gonna put it I think before I think it goes before this because it came right one two one two so it would come right here I believe. So we’re gonna do this, and then you set the timeout, and then you close that off, okay? And so now that it has a timeout, essentially when that thing opens, it’s gonna wait just a split second,

then it’s gonna find the list, then it’s gonna put the focus on the first element. That’s the theory anyway. Let’s see, let’s see if it actually works. Okay, refresh. Trick, there it is, look, look, look, the button has focus. And now if I go to the X, I can close it.

Okay, let’s do that again. There’s focus, no focus, no focus, focus. Okay, I hit enter. Bang! And it focuses on the first focusable element. Now, last thing we’re going to do. There is one more big thing, but I’m struggling with it. I couldn’t get it to work before the video, and I just said you know what we’re gonna have to tackle

it later. You have to trap focus inside of this message okay and that was the part I couldn’t get working. But one thing we are going to be able to add before we finish this up today is and this is another accessibility thing. When somebody closes either with the escape key like that or or with the X like that, it needs to return focus to the thing that triggered it in the first place, okay? To the thing, yeah, I know, I know. But this is actually very, very, very simple to do.

So if they do, if you remember back up here, we did, and let’s change this. This was add event listener, click function, toggle attribute. Okay, so we’re gonna show message on click, okay? And then close message on X click. That’s what these two groups of code are doing right here. All we have to do is append another action to this, okay? And what that’s gonna be is the greeter button.

And then remember down here where we gave something focus with just putting dot focus That’s literally all we have to do here So we’re just gonna say because remember this is a function that when a click happens on greeter button We’re toggling an attribute on greeter message, and then we need to actually I’m sorry. I’m sorry show message on click That’s not where this goes. It’s close message on click it goes here. So when we on the greeter close button when there’s a click, we’re going to remove the attribute data pop-up open and then return focus to greeter button. That’s essentially what’s going to happen here. All right, so we’re going to take that again and then same thing with the escape key. Same concept. We have one thing happening already, we just need

to add another thing to it which is returning focus to greeter button. So I’m gonna sign my code. I’ll save again, just for shits and giggles. Okay, let’s come over, bang, and then escape. And when I escape, you should see focus go back to my head down there. Okay, so escape. There it is, there it is. Now let’s test it with the X.

There it is, it returned. Now see, you’re effectively in a loop, right? Where they can close and then reopen it. Close, reopen it. Close with the escape key, reopen it. So it’s not losing focus. And then essentially they could go to the next thing that’s after this, which was in order

that they were focusing already. So we just added a bunch of accessibility stuff to this. We accomplished a lot. There’s one thing left that we still haven’t accomplished. And look again, I just wanna remind you once again, this cute little, this cute little welcome pop-up thingy that everybody thinks is so cute, and they’re like, oh, can you whip me up one of those?

Just think about this, when a client asks for something like this. If you don’t have this out of the box, which by the way, this is gonna go into frames immediately, okay? But if you don’t have this out of the box, look at all the time we’re spending on this. And to get it really right and dialed in. Okay, it’s a cute little thing, but it’s a house of horrors.

It’s an absolute house of horrors. Okay, I wanted to do this as my first thing and I was like, oh my god, look at all this stuff that we have to be able to do and learn how to do in order to do it. It’s not easy, friends. It’s not easy. So the next time Bev asks for a cute little welcome, oh guys, how could, how hard could it be? Just give me a cute little welcome bubble. Just understand that you are signing up for a House of Horrors and you know there’s a lot of stuff that you’re gonna need to learn how to do or or probably better no you should do both but you know a shortcut would be to to get frames because this will be in frames like a lot of other fantastic

stuff. Okay anyway I digress we’ll be back again I’m gonna figure out how to stuff. Okay anyway I digress we’ll be back again I’m gonna figure out how to trap focus in this little House of Horrors and then I will show you how to do it and then we’re going to move on to something else. Peace.