 Welcome to another episode of GUI Challenges, where I build interfaces my way and then I challenge you to do it your way. Because with our creative minds combined, we're going to find multiple ways to solve these interfaces and expand the diversity of our skills. And in today's GUI Challenge, we're building a tooltip. I'd like to start our exploration and conversation about tooltips today with what isn't a tooltip and what is a tooltip. So in this case, this should look like a tooltip. You should be like, Oh yeah, that's a tooltip. But what about something like this? Is that a tooltip? Especially if it has interactive content inside of it. Is that a tooltip? No, you should be thinking to yourself, those are pretty different. This one here that we're looking at is called a toggle tip. So notice that I have focus on this little plaque right here. I'm also hovering on this little plaque right here. Nothing is showing. Why not? Well, it's because it is a toggle tip. I'll hit spacebar, and I'll get to see the content that's behind that tooltip. This is a pop up. It features light dismiss. I can hit escape as well. So here I'm going to just light dismiss this. I'm going to tab over to this one, hit spacebar. Notice focus is given to the tooltip, to this toggle tip. And then I can tab again to go inside of there and navigate with my keyboard inside of this persistent overlay and hit escape to close it. Now that's very different from a tooltip where I can hit tab to go inside of it. I can hit tab again. And hitting escape doesn't really do anything. I also can't hit tab again to go inside of this and interact with anything inside of here. So to me, the biggest difference between tooltips and toggle tips is twofold. First off, whether or not you have interactive elements inside of it, you're automatically going to be in toggle tip territory. You're going to have to be for the user experiencing accessibility of this element. Another thing is the interaction of what you want to show and hide this content. So a tooltip here is going to be hover or focus, something that's a little bit more light than a click, right? So if I click any of these, they're not going to do anything. The click is sort of dispatched separately from this just presentation of this element. So anyway, we are building tooltips today and that becomes very critical in the way that we're going to form our HTML and form our CSS. And it also means that we can do the majority of this with CSS. So let's head on over to the debugging corner and we'll check out a couple of things, you know, like features about these tooltips that I built and we'll get into some of the technical details. Oh yeah, the debugging corner, I love it over here. So we've got light themes all across the top, dark themes along the bottom. So this tooltip definitely should be able to do light and dark themes. So here's our light and our dark theme here. Excellent. Notice down here we have prefers reduced motion. So we just see a gentle crossfade. And up here, we're not preferring reduced motion. So we do see a slight amount of motion in the way that it's presenting. It's sort of directionality, like it's kind of coming from the element that owns this tooltip. Over here, we have right to left in the document mode. So see how our labels are over here. And if we go to top, look at even our like exclamation point is on the other side, go to block start, right and inline end. So these are logical property, contextually relevant tooltips. So they'll move with the document. And I thought that was kind of a nice touch to not just make them have a physical side, but give them a logical property as well. So we have hover working, we saw that tabbing through works as well. And notice when I tab, oh, here, let's tab through, let's, let's undo reduced motion, right? So now we see the slide a little bit now. And if I tab, notice that there isn't any motion. And I thought that was an interesting touch too, because if there was motion, the outline stroke and other things kind of tried to struggle to stay with that element while it animated. And by only having a crossfade with the keyboard interaction, I'm able to have this much more soft feel, I think. So anyway, that was just a little design touch that I put in there. Another one is that notice if I mouse quickly over these, you know, well, relatively quickly, I don't see the tool tip unless I stay there for 200 milliseconds. And I thought that was also interesting that someone should be able to sort of like mouse over stuff like this and not see a whole bunch of tooltips. But if they do sit there for at least a little bit, we'll show them the tool tip, right? So lots of little things adding up into this. I like this little do don't example here. So we have an input with some placeholder text and a label, which might feel like plenty to describe to someone how to interact with this input. But there's a temptation to always do this, which is remove the label and put everything inside of your tool tip. And that's not a good idea. You don't want to hide this. These tool tips are all about supplemental information that's not required. It's not interactive. This is going to be something they're just going to casually find. It's extra, which also means that you should treat all these tool tips as progressively enhanced. If they don't work or something doesn't happen right with these tool tips, the user shouldn't be in a scenario where they don't know what to do. So anyway, we've got prefers reduce motion, we have right to left handling, we have touch. So here I can tap on these, look at the error style version. So you can customize them, which is kind of nice. Here's the try me one down here. And these are kind of cool uses for it. So I found that these tool tips are really nice for, I mean, you can put them on a link if you want, but really it doesn't matter. It's kind of can be nice for buttons if you want to add some supplemental information there. Like here's what's nice is a labeled button. It's really tempting to not label icon buttons, but you should always label them and you can give them a tool tip to provide even more information about what's behind the destination of this icon button. This one I really liked here. This is the abridge element. In fact, it's kind of weird. Safari doesn't underline that here. Let me come down here to Chrome's. The abridge element has this underline style, which is nice because this is letting a user know that this is an abbreviation of the actual full on word. So here we have HTML in an ABR with a tool tip. And now I can say that it's hypertext markup language on hover. And we get this really nice tool tip that just enhances some supplemental information about this particular item. And then down here, this last example, you should already have alt text on your images, but this one allows you to put a tool tip inside of the picture and surface that nice alt text to your mouse and keyboard users as well. So sided users can get that extra information about a picture if you like. I thought it was kind of a cool use case, right? That's extra information about the picture that you can provide supplementally. So if that's our overview, we've gone over, you know, the sort of directionality of the document and how that works. We've got reduced motion. We have light and dark text themes. What else is inside of here to talk about? Well, let's dive into the screen reader experience next and then we'll dive into some of the technical styles that got us there, like the use of has the use of inert, which we'll see in just a second. Roll equals tool tip and more on to the screen reader user experience. So I'm going to hit command F5 to initialize voiceover on my Mac voiceover. Now it's worth noting that I did test this across Android screen reader iOS screen reader and some other screen readers to make sure that this solution was well rounded because it was easy to settle with pacifying one screen reader and not all of them. But okay, let's go over this experience. First, I want to show you or really I want you to hear the experience before we dive into how I accomplished it. So close your eyes and I'm going to hit tab and we're going to move on to the next link inside of this document that we don't know much about. Link block start has tool tip use logical size two thumbs up with light skin tone. So we focused on to a link and it said link block start that's normal that's what a screen reader is always going to say when you focus on to a link but then it took a breath and said has tool tip use logical sides too and then it described the emoji listen to another one link right has tool tip can animate them you interesting right so if you can't see we're almost getting a story told to us as the same as if we were seeing so we see a link we hover on it and then it says can animate them to a screen reader user they focus the link it says the link text right and then it says has a tool tip can animate them so to a screen reader user they're not relying on the screen reader technology itself to call this thing a tool tip even though we've given it a roll tool tip many screen reader users didn't have any affordances for that so what i've done is i've added a pause so that it says link inline end has tool tip the lot you know it said inline end has tool tip there's breaths between there without any of this work it would have just said inline end the logical sides are more closely tied to the implementation because to it it's just a chunk of text but by splitting it up i'm able to distinguish to a screen reader user what's the text to the link and what's the tool tip text or even just like we'll go down the link try me has tool tip high button it's a button the text just try me and it has a tool tip that says hi i think that's really interesting so let's break down a little bit what's happening here and it's also worth noting that not every user is going to navigate with the tab key they might use the screen reader uh motions which is going to be customized me has tool tip high but there are some elements that aren't necessarily uh focusable like this see this is just text so it's kind of it's important to note that tab isn't the only way that's just a keyboard user navigating your side a screen reader user will navigate with um alternative ways to go they can jump between text and headings i mean i'm sure you've heard this but it's important to test both keyboard and screen reader all right i'm going to turn off the screen reader and then we're going to go kind of inspect how some of this is accomplished and we're going to use dev tools voice over off so i'm going to hit command option i to bring open dev tools let me pull this open a little bit larger here and i'm going to hit the accessibility tree tool and that's going to give us a view of these elements from the accessibility context so here is our link our link has text top with a semicolon has tool tip hey a tool tip and that's exactly what we were read and if we look down here all we see is static text and that's it and the way that that worked is a couple of fun things that we did with our html so i'm going to get rid of the accessibility view here i'm going to look at our actual tool tip element so here's our tool tip custom element notice it's not a web component this is just a custom element any element with a dash and it can be a custom element and the browser is just going to treat it like a div i thought it was fun in this case to give a tool dash tip the role equals tool tip and well we'll talk about inert here in a second but that's just a hook for me to do my styling you could have used a class name it doesn't matter i thought it was nice to see it as a tool tip it reads well as an author in my markup to see that these are clearly tool tips and then we'll make sure screen reader users of course get that same experience so we also add inert onto here and roll tool tip so roll tool tip if an screen reader can it will treat this particular element as a tool tip and it will show it in the dev tools as a tool tip but since we've also given an inert we've essentially said this element has no interactivity kind of ignore any mouse events touch events focus events so don't let this thing be focusable at all right which is essentially how a tool tip works we never should be able to go into it that's the role of a toggle tip a toggle tip would be one that we can focus into so we wouldn't put inert on a toggle tip but we are on a tool tip so all of that to say we're making this inaccessible from a sort of interactivity point of view but we do want the content of it to surface so if we open up the tool tip here and in fact let's just show hover so let's simulate being hovered on this tool tip so we can kind of investigate the elements that are being put in here we have the actual tool tip text so this is what gets read aloud or that gets shown in and hover also gets read aloud after this before text so this before text is kind of a clever little user experience enhancement that i added at least i think it is we'll see how well it tests across other screen reader users as you all try it out but it has this content semi colon has tool tips so that's how i i'm giving the screen reader user some special text to give it a pause and then to say has tool tip and to read the tool tip text the rest of these styles are all making it invisible to sighted users so this is screen reader only text notice we don't see it in the tool tip here it doesn't show up anywhere and that's because it's being very effectively hidden from sighted users but the content is still there the text is still there and the screen reader user knows that i thought that was kind of neat another thing that's really interesting here is if we look at the after element the after element is actually what's doing the whole bubble shape and this little arrow tool tip down but the shadows are on the tool tip itself and that's just a special little thing in here so that we could get a special shape and we get the special shape shadow which is uh it was important to me that the little tick that popped down was actually part of the element and not a triangle pseudo element i've had so many issues with little triangle pseudo elements that you could see a little line right here it was just so annoying and maybe that line since it was a pseudo element wasn't changing the shadow i don't know it was all very obnoxious to me and so this uses a mask and so here's our mask down here being set to tip and in each particular tip direction selector like this is for top and block start we're giving it the bottom tip so if we were to go look at one of the other tips we would see a top tip or left tip or right tip and these particular tips are gradients written in a conic gradient syntax that essentially creates a little slice of pizza and we position that piece of pizza non-repeating in the very center bottom in this case and that's why we get that little thing and so it's changing the shape of the border so if we look here see there's a border size that's the orange the border is being cropped by the mask and that's giving us our effect so these are actually shaped like the shape uh there's no tricks and no seams and i i think that's a really nice solution here so back to screen reader support we've got the screen reader only text here we have inert and if we look at the accessibility tree it's well represented that way although look it looks like it's a little upset at our current scenario but oh they're just all ignored okay so i guess it's just being honest about its representation right now it's saying that that tool tip element is being ignored as all all of its descendants so any text and interactive elements which you shouldn't have inside of there are also inert and so that's kind of interesting we've got screen readers tabbing into this getting presented with an element that is inert but its content is being attached to the parent element and being read allowed to it so i thought this was really cool i thought the experience was really meaningful as the tool tip was announced to a screen reader user as a tool tip and wasn't just some surprise text that showed up and yeah that's how i was able to get that user experience in there all of these things to say i'm using inert and i'm using has to well here let's go look at how has is being used right so i'm here on the anchor element we can scroll down into our layer demo here which says has tool tip so we're using the has selector to find all the elements that have direct ascended tool tips and giving them position relative and that's allowing the tool tip element itself to position absolute right position absolute and find its way and its particular see this one's top position to find where it needs to be positioned at so it's using a combination of insets and with transforms to get itself into that particular position and that essentially gives you all of the technical details but let's dive into a little bit of the styles before we go here we are my trusty editor and just to preview really quick this is what it looks like to author once we have that anchor element here's the anchor text and our tool tip inside of there with inert enroll equals tool tip and our text inside and that's all it takes and notice this one doesn't even have a tip position so this one is using the attribute tip position to change the tip position and look down here to position right to position in line and bottom etc so that's how you change what side the tool tip should be on and then our styles looks like this we've got a couple of custom properties to stash our padding our triangle size our background our shadow strength because we manage the shadow strength between light and dark we need to have some good shadows there is right to left as a custom property to help us manage our transforms transforms are they don't have a logical value or a logical option so we have to sort of create that with calc and so if something is right to left or not we can use that negative one or one and a calculation against an x position and sort of change the way that that works here's each of our masks so our conic gradients for our bottom tip our top tip our right tips and stuff our opacity and our transforms and our transitions on those our positioning some font styles so this is saying you can be as wide as your max content but never go longer than 25 characters so that's why short tips look short and longer tips start to wrap and multi-line we've got our padding set here our border radius these are all on the parent element this also has a background of bg our color called canvas text is a system color that that will be dynamically the color of the document so in a light theme it's black text in a dark theme it's white text and we're saying we'll change on filter that's to make sure that our nice shadows don't get messed up during transitioning here's our light theme so we just flip the background to white we make our shadows much less strong here we're using the durseudo selector to know if the document is in right to left if it is we flip our custom property so that we can uh that's going to be what you know flip syncs right or left in our styles here i'm using the at nest per the the draft spec that we have here to create a new selector that says has tooltip so this you can think of as our tooltip selector context that we were in before it says has a tooltip give that element that does have a tooltip position relative so that was a really fun way for us to create stacking contexts only for elements with tooltips and then we can also extend that and say and is hover focus visible or active find the child tooltip and opacity one and transition delay so we're looking at parent interactivity and then selecting a child inside of there which is kind of cool so if a parent has a tooltip and is being hovered focus and active then find that tooltip and just some cool nesting selectors that that worked out really well here's our screen reader only text excellent here's our tooltip shape so can cast a shadow we talked about that earlier here's the mask being set to tip and then all the different positions are going to change the tip there this is some text alignment and then here's like an example of how top is being positioned well actually the top isn't as interesting as right let's look at how right is being positioned so we have an inset inline start so that's like our left position this is using an absolute position we're calculating its own size plus the padding that's on the inline and the triangle size so that's how we're getting perfect centering our inline block and is at 50% and our y position that's going to be using our transform is also 50% if the user is okay with motion we're going to go look to see if they're hovering or active and we're going to find that tooltip and give it an out position so this is going to make it so that this is negative three pixels and when you hover it's going to move to the right three pixels as is our after this sets our our tooltip so it says left tip we're setting the inline in our inset inline start this is another position absolute this is our border inline start notice these triangle sizes match so we're offsetting it based on the size of the triangle and then we're creating the triangle and the border and last we flip to a different tip if we're in a different direction mode and that's essentially how the rest of them are all positioned so they all find their way between a combination of inset and transform translate positions as well as a custom mask tooltip that shows which side that tooltip should be on and that is it for the styles the last thing here is um if you don't have has so if the brow like firefox for example doesn't have has and this demo still works because i'm wrote a little tiny polyfill the tiny polyfill says hey if this browser does not support the selector has go find all the tooltips find their parent elements and give them a class called has tooltip then we'll inject a style tag that says has tooltip class position relative has tooltip is hover focus visible active and we'll give them opacity one transition delay of 200 milliseconds and then we'll pin those styles to the document and essentially we have polyfilled the features so that browsers without has still get interactive tooltips whew that is all to say that while i've built a mostly css only tooltip i mean we have this little polyfill for has here i do look forward to the anchor positioning api and the pop up apis that are coming out soon from open ui and they're being prototyped right now inside of chromium as these are going to give you much easier ability to do toggle tips where the toggle tip can be a it's almost like a little mini dialogue it'll come with light dismiss it'll come with some inert management for you as well as it will be positioned in the top layer so one of the things that's a bummer about these tooltips is their children of an element which means they aren't in the global positioning space they don't have awareness of the window and they don't have awareness of other tooltips and so they might show up underneath other elements which is kind of a bummer so i look forward to this future where we could build toggle tips as easy as we build a tooltip and then maybe we'll get the best of the both worlds at that point we'll still need to do some accessibility testing i look forward to those changes that are coming thanks for watching this kuii challenge on tool tips and i'll see you around take it easy y'all