Create Accessible Tabs with HTML, CSS & JS
Skills:
Prompt Craft90%Advanced Prompting80%Prompt Systems Engineering70%Agent Foundations60%Tool Use & Function Calling50%
Key Takeaways
The video demonstrates how to create accessible tabs using HTML, CSS, and JavaScript, emphasizing the importance of progressive enhancement and accessibility guidelines.
Full Transcript
hi there my friend and Friends Tabs are one of those things that are pretty ubiquitous around the web right we see them all over the place you know whether you're shopping or something they're always in like these types of sites uh big box stores absolutely love tabs and we get these style ones you're on YouTube right now watching this and YouTube has its own tabs along the top here that you can go through uh we have different types of tabs too these you don't always think of tabs but like these vertical ones are our tabs as well that we can use there's even these types of like Carousel slash tabs where it's like a tab system that automatically runs um which you know it already to me if you're cycling through something maybe it's a bad sign um that you're you're trying to get through information and sort of force the user through things it's like I'm totally aware that you often need to build tabs you might be asked to build them or something like that but before we get to actually looking at how to do it I do want to say that like they're not the most user-friendly thing that you can come across on a website so if you're creating a project and you decide to put some tabs in there maybe stop for a second and think do I really need to include tabs here they hide information away from the user you know that's why we have to sort of cycle through them and let those Auto playing ones we're trying to make sure that the user sees that there's more stuff there just like a carousel's hiding information away they can be kind of awkward to use sometimes and not super straightforward you might not even realize that they're an interactive element they hide information from the user which is why those Auto playing ones they're trying to like make sure that we get through all of the content there they can even be awkward to use depending on how you're interacting with them and in general they don't actually add any value to a site and one way I just want to sort of highlight that is this example here we saw this one I was just looking at which is from a big box store Canadian Tire here in Canada where it's this lawnmower and you can sort of you have these tabs to go from the features to the specifications to the resources but then here is another big box store that's selling lawnmowers and it looks like they have a tab system but if I go to overview it brings me to overview I go to specifications it brings me there and if I go to reviews it brings me down to where the reviews are here at the bottom a little bit different but the overview and the specifications is basically the same thing that this one had right features and specifications but this one if I'm just scrolling down the page and I don't stop to look at these I can still get all of that information and that's one wonderful thing about the web is we can scroll through it we're not limited in the amount of space that we have and so I do want you to stop and go do I really need them is there an actual benefit to having this as tabs and the answer is probably not but I'm also going to say that if you're watching this maybe you don't have the choice here you've been tasked with creating tabs you have to do it and you want to build it the right way or at least try and build it the best way possible so that's what we will be looking at in this video but if you do have that power to not have to bother implementing them maybe that would be the better choice just want to really preface that strongly at the beginning but maybe you've been assigned tabs on your latest Sprint or your designers handed you a design and he's won't budge on it you need to make some tabs and that is that so let's dive in and see how we can do it so let's jump into this which is what I'm going to suggest that you start with um and for this video I am going to be doing a little we're going to break down code a lot more and we're going to sort of build it step by step but I'm not going to write it all from scratch just because I think it's going to go a little faster and be a little bit more clear this way um and you'll see here I have my tab I have a div of tab container that I have here at the top that's going down all the way down to here and inside that tab container I have a few different things we're going to break this all down but the first thing is I have my list right here and then I have all my panels after and you'll notice I'm using a list and I'm using links and originally when I was first creating this I was building this with buttons because I'm making an interactive element and so buttons made more sense than links but then after talking with Hayden Pickering who gave me some very great advice for helping me come up with this so I'll link to some of his stuff down below I'd strongly recommend you check it out so what this creates right now is something like this and we don't really have any CSS organizing this I just have some very basic style sheets changing some colors and stuff but what that means is this first advertising one is just a regular link so if I click on Advertising it brings me to there we could even make this a little bit better possibly by highlighting what became targeted if I go to socials we go to the social one and go to marketing it brings me to each one of the paragraphs or the the bit of text that's associated with that we are going to be adding JavaScript to this we're going to be making this a full tab system but the idea here that we're going to be doing is doing it with Progressive enhancement and so if JavaScript doesn't load for whatever reason the user has it turned off who knows what it is this is fully functional and this sort of Harkens back to that one of the Home Depot which I actually think they did a decent job with that making it linked to each section instead of hiding the content behind tabs because the other thing you have to think about is if you do have content in tabs and someone wants to like link to something within the page but it's in a tab how do you even do that and there there's a lot of you know the Deep linking there can be very problematic it's a lot of JavaScript to solve that whereas here the content is all exposed so I'm just throwing a few things out there again just saying do you really want to have tabs but yes you do you're here you're following along so you definitely want tabs so I have all of these set up here and then in this next section I have these tab panels so I have one div tab panels and then inside of my tab panels I'm going and just making an individual one for each I haven't given these like a tab panel class you could definitely do that if you want but I just have my tab tab panels and then inside each one of those I have the div and inside you know that's in this case I just have a paragraph you could put whatever you want in there but the important thing for now is we have the links here and these are just the href that are anchoring and then I have the ID on each one of those right there the other thing I have done on this is this UL is area labeled by the tabs title so how can our company help you is the title for these tabs and then we get that down there as well so just add a little bit of extra context that if somebody gets to this list they know what the list is about but also once this turns into an actual tab system they know the purpose of these tabs it's giving us information about how the company can help us and now I'm not actually going to style this up to look better in this state but you could definitely add a little bit of styling just to make this a little bit nicer if you felt like you wanted to um and we're going to see that we could actually easily have two different styles for all of this because I'm going to be building all of my styles for the tabs assuming that the JavaScript is working even though it's only being done with CSS and we'll see how that's going to work as well so I think the very first thing we should do in this case is actually again the tabs working to like hide the content away get them working so when we click on the links we're going to expose the correct paragraph or the correct tab panel and then once we've done that we'll actually style them up and make it look more like an actual tab system so I'm going to jump on over to my Javascript file here which has nothing in it and we're going to start off with a decent little chunk of code right here and you'll you'll see one of the problems that I had from the beginning but we'll shrink this down just so we can see everything on the screen at once um and here so I'm doing a cons of my tab container my tab list my tab buttons and my tab panels so we have a variables set up for each one of those and we just have my tab container we have the UL uh in this case I'm just doing ul and a a little bit dangerous to actually do that so uh you could come in and either give this UL a class or an ID to actually Target it properly I just have these as the regular links here but again a class on those that you could decide it could be your tab button class or whatever you want um just to make those a little bit safer I'm doing silly demo land you're probably working on a real project so you have to give that a little bit more thought than I had to worry about for my class naming uh and then here on the tab panels This you could definitely do um you know you could give each one of these a class of tab panel like I mentioned earlier but I don't see any problem in doing something like this where we can get our tab panels without having to worry about it too much we have the tab panels then every div in there will just be a panel for me that's straightforward if you like a direct class on each one of them go for it um and then there's this part here and this is the the part that's sort of setting the stage for what we're going to be doing which is uh we're going through our tab buttons so let's go look here we're going through each one of the buttons so we have four buttons that are here or my four links which are my tab buttons in JavaScript land and for each one of those tabs we're going to grab the tab and we're going to grab the index and index here is just it keeps track of the index so we have 0 1 2 3 for each one of them and I'm I've put this here for now because we will have to build some stuff into this but we're saying if the index is zero we're going to do some other stuff later but for index 0 we're not going to worry about it but for all the other ones we're going to do a set attribute hidden and you'll notice that this is actually changed and we have only one paragraph showing up now uh and if I take this off and I hit save we have all four of them so the hidden class is going to hide it visually and it's also going to remove it from the accessibility tree so that's no longer there so if we come and look here we'll see them here but we have the hidden attribute that's been added to all of those uh this is I'm assuming you always want your first tab to be the active tab when the page loads if you wanted a different tab to be your active tab you'd have to find a different approach here but this is just assuming that the first tab I think every site I've ever been on that does use tabs assumes that but it is assuming the first tab is going to be the active one and this is probably the easiest way to do it and we could definitely do this in a little bit of a different way but since I want to be doing other stuff here as well I'm doing the if else here makes sense for me now before we worry about all the other stuff that we might be doing here what we want to do now is we've hidden away content and if I click on one of these links I want to make the content related to those to actually show up here right and the other thing is you'll see when I click advertising it's jumping down and I don't want that to happen and the reason it's doing that is because that behavior is good if JavaScript isn't running or it's disabled for the user but we want to disable that when the JavaScript comes in again we're using JavaScript to progressively enhance everything so it functions if there's no JavaScript but when we have JavaScript we're going to sort of change the behaviors along the way and make it the experience you want it to be so to do that I'm going to bring in this code that we see right here we're going to break all of this down so the first thing we could do is do this where we're going to go through our tabs container we're going to add an event listener for a click and it's going to prevent the default and this is kind of interesting because even though I'm doing this on the tab container and I'm not doing this on the buttons this is still working because any event that happens when I click anywhere in here it's just saying whatever the default event is we're not going to do that and that means I can add an event listener to my entire container instead of having to Loop through and add an event listener to each one of the buttons so it's just a little bit less work for the browser not that I think it would be a performance issue the other way but you can see now when I click these we're not well the advertising one's not jumping down like it was before so that's a nice simple way just to do that again with one event listener and now one thing that is happening here let's just do a console log of e and actually I'm going to do e Target so e is just the event that self and I'm going to look at like what were being clicked on here so if we come and look in my Dev tools let's just put the dev tools on this side so if I come into my console when I click on here you can see what I'm clicking on so if I click on the link we're seeing the link if I click in the middle of nowhere I'm clicking on the LI because the LI stretches all the way across if I probably can manage somewhere along the way here just to click on the tab container itself as well so it's keeping track of what we're clicking on and and ideally we're going to be doing a bunch of different stuff here but we only want it to actually do it if we're clicking directly on one of the links if we're not clicking on a link I don't want the JavaScript to do anything so we can close this down and the way that we can do that is before we even prevent default and you could leave prevent default as the first thing it wouldn't really matter but what we can do is actually let's put this up here I'm going to leave my console log and we're going to look for what we've clicked on so we're going to create a new variable called clicked tab it could be a different name again if you want and it's going to look for the closest link so this is really cool because and let's do that we'll do a console log of clicked tab now uh so if I come and look here and I guess I shouldn't have closed my Dev tools but we can open those back up now if I click out here you're seeing I'm getting null and the reason that we're getting null is because I'm not clicking on a link whereas if I click on the link it's going to come out so normally the clicked The Click tab it's saying there is no click tab that's why it's saying no unless I click on the link and then it's showing me which link I've clicked on and so even though I have this event listener on the entire thing I can know if I'm clicking only on one of the links like this and what that means is we can come in with this I mean say if not clicked tab so if we don't have a clicked tab if it's returning null we can return and that means this entire thing is just gone we're not going to continue with what we're doing in here we're going to escape out and that just means the browser doesn't have to parse any more JavaScript that's not actually going to do anything so now again if I open up my Dev tools and we take a look if I'm clicking anywhere in here nothing is happening but if I click on a link now it's actually firing so good we're only doing something if we clicked on a tab we can now do our prevent default because we know those tabs are actually going to be links and we don't want those links to go anywhere the other Advantage with this too is when I click on these um you'll notice I know my address bar is out but um because those were hashtags I know you can't see my address bar but when I was clicking on those before it would go to the hashtag for that address which is a good behavior because that's what makes those anchor links work but this prevents that completely from happening so none of that's happening we just have no link behaviors happening at all and the one thing that's cool here is that even though we've stopped getting like this the hashtag won't get added to the URL when we click on it we still have access to these and these still can help us with the IDS that we have down here so we're leaning into that original functionality that we had and we can take advantage of that to get the JavaScript to actually show the panels that we want to show and so let's go back to our JavaScript here and so what we can do is we can add this right here and what this is going to do is when we click on a link we're going to get the clicked tab attribute href and we're getting that because when I click on that if I click on this tab I'm getting the advertising or the social media or the content marketing whatever it is I'm getting that right there so the click tabs href is the active panel ID the new panel that I want to activate that's the idea of it and then we can use that to say that the active panel is my tabs so the the panel that I actually want to make the new one that I can see we're going to do the tabs container query selector and we can find that and you could do this without having it as two different variables you could just do it with one and have all of this in there but I just find it a little bit easier to do it this way and now I'm going to do this which so we're going to Loop through all of the panels because if we come back up tab panels is my query selector all of each one of the individual panels that we've created inside of there and so we're going to Loop through all of the panels and for each panel we're going to make them hidden so actually if I take this line off for a second I hit save we see we have that one that's here when I click on socials it disappears and it's Spanish so they've all been set to Hidden and then I can go and I can find my active panel that we've got and then I can remove the attribute if hidden um oh I've hidden false we can just do that I think and it should work as well I don't know I had the pulse in there there we go we can see that it's working so we're setting the attribute here and we're removing the attribute there of the one that we've clicked on and it's a little bit of a lazy way to do it but it works perfectly fine um so there we go we can see that we're switching between and we have that cycling through so that's pretty good the only thing is to really progressively enhance this properly while this is functional right now it doesn't really work the way Tabs are supposed to work um in that if I tab into here and I push tab again we're actually going through it the different links here through my tab which you'd expect is the actual Behavior but the AGP which is the accessibility guidelines actually says that we should have to use the arrow keys to go through our different tabs instead of using tab like this and the reason for this if I go to socials and I select it I should be able to access this information down here so I'm sort of going to the next part with my Tab Key instead of going to the next thing on there and I'm going to talk a little bit about this interaction a little bit more later on but to like actually make this work the way we need it to we have a lot more JavaScript that we're going to have to do and right now it's just from an accessibility point of view we need to bake a lot more things into all of this to get it working properly so what I'm going to do because we will have a lot more behaviors coming in um here when we're clicking on something this is going to get pretty full so I think it actually makes sense to pull this out of here we're just going to do a function called switch Tab and we're going to switch to our clicked tab uh and I just think that it's gonna be a little bit cleaner and a little bit easier to keep track of what's going on and then I just can take everything that I had before and just bring it down into this switch tab right here so it's exactly the same just instead of having the click tab I'm passing new tab here so I'm just using new tab right there the only difference in what I had before if we come back it works exactly the same as it did before where it's just showing what we've clicked on now the next part that we want to do is help with assistive Technologies because right now it was sort of as I was saying with the keyboard navigation of it we need to fix that up but also from an assistive technology standpoint right now this is kind of non-functional and we want to make sure that it works properly so one thing that we do need to do to make that happen is to actually bring in some area rules and I wasn't using those rules before because if we don't have JavaScript enabled we just get the regular list that links down that works as intended and in general the best rule of area is no area is good area which applies most of of the time because we have semantic HTML that we can be using instead but what happens when we're making these types of components it's things that involve interaction that don't have like and that we don't have an HTML tabs interface as nice as that would be to have but we don't have one uh so for things like carousels for tabs for accordions and for other these other things that you have to interact with that can involve different ways of interaction often there's area roles that can help us out when it comes to getting the screen reader experience to function properly and just gives a lot more information to users so they can use our interface properly or at least hopefully use it properly and one thing that can be hard when you're getting into and trying to figure this out is like how do you find out what all these roles are the main thing is if you are trying to build something look up first on the AGP but you could also just do like a11y tabs or accessibility tabs in Google just to get a little bit more information and see how other people have done it and often the AGP will come up as one of the first results and it was I heavily influenced the first draft of what I did here based on their guidelines uh and then sort of after talking with Hayden went to do more of a progressive enhancement version of that instead of just following it exactly how they had it and there's one thing with their guidelines that I'll also talk about regarding area controls that I've recently learned um as well so a few little interesting things that we're going to be able to cover as we go through this but the best place to start is to start by finding some guidelines to help you get there the same way you'd read documentation on the MDM or whatever it is for you know how to a section works or what's this new element or what's that new selector or whatever it is or this new CSS feature right so if you're looking at the documentation for things it's the same thing if you want to make something accessible don't use like a third party tool that tries to force it in try and just learn about it and then at the beginning it will be a bit of a process just like it's a process to learn HTML CSS and JavaScript it's a process to learn these things as well but the more you do it the more second nature it will all become and so what we need to decide now actually is do we want these to be automatic tabs or do we want them to be manual tabs and what I mean by that is do you want it to be a tab that when you're keyboard navigating on it when we switch tabs do we want it to automatically go to that tab or do we want it so we can like cycle through different tabs and then click to select one of them in this case I'm going to go with automatic tabs but it's a very small change if you do want to go with a manual tab so you just a little bit of a change in your JavaScript to be able to do that so what we're going to do and actually I just realized something as I Was preparing for this part but here when I was saying like this could be a little bit dangerous we are query selecting these only within the tabs container and then only within the tab list so you're probably only getting the ones you wanted to anyway so you could probably leave this the way I had it um yeah so yeah just to say it's not as dangerous as I originally thought since I scope my query selectors a little bit which was good um and the reason I mentioned that is because my next one that we're going to be adding in here where we can I'm going to come down here and I'm not going to do it within a function my JavaScript is going to run when the page is loaded because I have a defer on there but that you could definitely make this into like a tabify function if you wanted to you could have an event listener for uh the page load or Dom content loaded I think it is uh because Dawn content loaded is a little bit different than using defer whereas it just waits for it to be loaded before the JavaScript starts to run um instead of right now where I think it has to parse everything as well anyway it shouldn't make a big difference it all goes so quickly anyway but if you wanted to add this into a function or you could even make a Constructor or whatever to like get all of this to work but we're just going to keep it kind of simple and we're going to start with this we're going to do my tab list and we're going to set the attribute role to tab list and so that's it saving for this we're going to spend some time in our our Doc in our devtools here sorry about that um just because it's going to make it a little bit easier because we're adding stuff to the HTML that we're not going to see if we go over in our HTML tab so now if we look here I have my UL which has the area labeled by that we looked at earlier on and then I have this roll of tab list that's coming on that and this is the role that we want to add and again you'd get this from the AGP article I have linked it down below or other ones as well that would explain that this is sort of now telling someone who's using an assistive technology that they're on a tablet they're landing on something that's Tab and when we do that the next thing we want to do is make these into actual tabs so we have our tab list these instead of being list items should now be tabs so there's two different things we need to do to accomplish that so to be able to do that and actually what we should probably do just because I have we have the tab buttons I'm going to move this all the way up um just we're sort of going in a bit of an order uh we have the tab list where here we're setting we're adding that role and actually I misspoke a little bit because um I said that we wanted to make the list items the role we wanted these to be our tabs but we actually want the links to be the tabs because these are what we're interacting with and we want to remove the semantics of the LI because we're no longer in a UL we're now in a tab list which is a little bit different so we want to remove the semantics from the Li and add this tab semantics to the links themselves so to do that we're gonna have two different things we're gonna have to do one of them will actually be able to take advantage of what we have here already which is why I moved this tab list up here but the first thing we'll do is this so we're going to go through our tab list I'm doing the tab list then query selector all of the LI which should be in parentheses there are quotation marks there so we'll get all of our list items and then for each one of those list items we'll set the rule to presentation so if we come and take a look all of those list items now should there we go have the role of presentation on them and so what we can do is down in this part here before what we're doing is we wanted to set the attribute to Hidden on the tab panels right and this Loop through all the tabs and it was getting the index 0 1 2 3 and then we could get that same index for the tab panels and only hide the ones we want for this we don't actually need to go through the index or anything what we want to do is just say Tab and then set attribute of tab index to negative one so now if we come and take a look and we inspect in here we have my tab which is fine but if we come into the next one that's in here we should have a tab index of negative one and so now if I tap onto here we're here if I hit tab again you can see it's jumping down all the way to here because that's the next thing in the tab order now we do have to be really careful when you're changing tab indexes and you have to have a very important or very good reason to do it and here it's just to follow the guidelines of how a tab system should work in that we shouldn't be able to tab through these we need to keyboard navigate or Arrow key navigate through them instead which we can do and we'll be doing that in a second there is one thing though and it's because of the way this interaction is working and talking about tab index we might as well stick with it where when I tab to here if I tab down to here it's a little bit awkward with like say I click into socials and then I want to be able to access this information right away the best way to be able to do that is actually to allow the user they're on the socials then to be able to Tab and actually reach this and this is a behavior you generally is very rare this happens and you only once again I'm finding the guidelines and from just usability testing and all of that that's tends to be the easiest way for users to be able to work um so right because then so they don't have like there's no other real shortcuts in their way to get there and so how we can do that here we have our tab list here we have the list items themselves here we have the buttons themselves and of course the container what I'm also going to come down to here is on the panels themselves and maybe the container would make sense as the first one but for the tab panels what we're going to do is set the tab index to them to zero and the reason we want to do that is we want to be able to go into our tab panel select the tab so say we get onto our marketing one and then I hit Tab and it would actually bring me down to that section and this is for keyboard navigation and people using assistive Technologies it's the easiest way to actually be able to go from like their tab navigation into the content that they've now activated because if you activate that you're assuming that now you want to go and read what is there so definitely a bit of a different Behavior than what you would normally have on most things but this is the suggested way of doing it which does lead to the question of also like testing and having you know making sure that users can actually interact with this properly because you're putting in all this work and people might get there and it might still be a confusing experience for them just because tabs aren't super common there's probably a lot of bad tabs out there so there's different ways of interacting with them so even when you follow best guidelines you might end up finding out that people aren't using it the way that you think they would be so but you start by following what you can and then you start asking people to test it you try it on screen readers get people to use the proper screen readers and all of that and I mentioned earlier that Hayden had helped me and I also had help from Amber from equalized digital link to down Below in the description there for what she's up to as well which deals with like adding accessibility testing for WordPress and stuff like that WordPress sites and she kindly recorded some interactions with screen readers and showing me how it would work on that end of things which was really helpful to like see how that goes because I'm not comfortable using them so just getting some ideas on that uh in how that side of things worked really helped me out so uh thank you for that Amber and the other suggestions you gave me as well to improve things in here um and yeah actually and before I move on I do want to mention that like I wouldn't have been able to build this completely by myself without the help of other people who specialize more in this stuff with Hayden and Amber's help I think this is a million times better than what I would have done on my own and I think when you're building stuff like this and I had a bit of a discussion with Hayden on this where the best way to be able to do this is to actually talk with people that are good with what they do and there's a lot of people on Twitter and Mastodon who who work in this field that are very willing to help out with people and like the discussions that are going on um because one thing that also came up was with these links they should have area controls on them for the tab that they're going to and originally it was buttons with the area controls and through talking with Hayden who's done a lot of testing and other things it turns out that area controls doesn't actually do very much or what we think it does because it used to be announced there was one screen reader that would actually announce what it was doing like this button is controlling this feature and they removed it because it was too verbose it was just like slowing people down it didn't it was open menu they know they're opening the menu they don't need to know what menu they're opening necessarily type of thing because they probably had the context already and there's been quite a bit of discussion within the accessibility Community about area controls and sort of what do we do with it now um but yeah it was sort of enlightening on that front so if you are looking to build things that are accessible first make sure you talk you know look up what the best practices are talk to people test it like crazy through the different interactions you can have ask other people to test it if you do have the resources at hand you're working in a larger company and they want to do this and you're taking the time to build it properly get the audience you're building this for to test it out and see if it works because you might find out that they'd suggest doing things in a different way and the only way to do that is through test actual people using it right so a really important step along the way there and you might not have those resources if you're just a student right now but just try and talk with people in those cases in those cases like I said follow the resources the guidelines you can find if you can find people doing videos like this you can follow along with that and do the best you can and then along the way try and just have discussions and talk with people or follow discussions that are happening or whatever it is to try and learn more about it but with that said let's keep on going here sorry for the little tangent and actually I do want to Circle just really quickly to this where I'm doing a tab index of zero on all my tab panels this could be something that maybe would require a bit more testing because if I go to here and I hit tab it's only highlighting that because that's the only thing that's here because we've hidden away the other ones and we're only doing this through JavaScript so remember if whatever reason the JavaScript doesn't load and we go to that native experience this isn't running the risk of breaking tab ordering and stuff and causing problems outside of like this Progressive enhancement that we're creating right now so that's really important because if all of the tab panels were visible and I would just tab through them that would be kind of weird um so but I think how we've set this up is safe because only one of them is actually visible to us even from the accessibility point of view as well because hidden will take it out of the accessibility tree but while we're here and while we're talking about these panels we should also be we've done the the attribute of rule presentation the rule tab list the role of uh so we can come on this and we can set the role of tab panel on the pan channels themselves as well because if we have the tab list inside the tab list we should have tab panels and on that note we should also have tabs so for all of these what we can do is come through and I'm just going to say tab set rule to Tab and this was before I went to Circle I meant to do this earlier and I forgot but when we stripped away the semantics of the LI we're saying this is no longer a list item because these are my tabs we have to add that in here and we do that with my roll of tab on the individual items that are inside of there so now if we go and we take a look we should see a nicely marked up where we have in here or we have the UL which has the role of tab list and it is being titled by my H2 right there we have the Lis that now have a role of presentation because we don't want the semantics of the LI because our A's here have the roll of tab on them so this is what's giving the semantics to it and we've changed our tab index on those now we're going to do one last thing here and it's gonna have to do with which which one is currently selected because when we have our tabs we need to we've gone this far we we want to also explain to the screen reader which is the selected tab as well and this is a little bit more useful if you're doing a manual uh one just because then you could be going through your tabs but it's not the selected tab but we'll add this in here anyway because I think it's still useful to have so we're only going to we're going to go on this index of zero so we're choosing our first one because that's our active tab when the page loads and we can say is so if the index is zero then that tab we can do a set attribute and that attribute will be area selected and it will go to true so now if we go and take a look there and the reason I'm doing this is because we're going to be starting to style things up soon uh exciting right it took all this time to get to some CSS on one of my videos it's not often we're doing so much JavaScript but now we have an area selected of true on that first one and it will only be on the first one when the page loads and we'll and move things around with some JavaScript after but the reason I'm doing that is let's jump over and do a little bit of CSS so I have my style.css where I just have all the stuff that doesn't really matter uh and let's start so we're going to come to our I'm going to leave it like this assuming the JavaScript doesn't load and you could come up with your own Styles whatever you want but to ensure and this is a little bit I've talked about this before where we can code Things based we like semantic H uh sorry semantic selectors and semantic CSS where we're selecting Things based on the attributes that are on something since we're using a lot of attributes in here so what we could do here is our if you remember we're getting a roll of tab list on the tab list if it's actually going to be a functional tablet list right so what we could do is we could say that if the role is equal to tab list then we can do a list style of none and that will take those away and then we can also come in and say that it's a display flex and they'll go next to one another uh and I guess here too you probably do your margin margin of zero adding of zero and then we can also last thing we'll do here is a gap of like one REM um just to space them out a little bit and now the next thing we can do and we can definitely style these up a lot more than what I'm going to be looking at right now but we're going to come and for now just do an area selected is equal to true and let's do two things let's just for fun do a text decoration uh thickness and we'll make it like 0.5 M to make it really thick maybe that's a bit too much um and then we can also do a text underline offset and do that at like 0.5 M or something just to move it down um it's not perfect but I just want to like maybe we can also we'll do color is yellow uh orange red because just to make it really obvious um how this is working I'm again not super worried about like styling styling right now I'm just worried about more functionality uh but also hooking into the the things we've said here and then if the page loaded just to show you if there was no JavaScript none of those stylings are coming in they're only going to come in if the JavaScript is loaded so we're styling it progressively enhancing it through JavaScript which is also then styling it appropriately so let's jump back into the JavaScript now and let's go to our switch tab function that we've created here because we have a little bit happening right when we click we actually have that switching around now another thing that we'd want to do we want to sort of continue hooking into what we've just created there with our CSS s or vice versa however you want to look at it so active panel we're removing the attribute hidden we could also come in and add this line right here so new tab set attribute of area selected to True right so now when I click that you'll see that that one becomes true and true and true except that's kind of awkward because now they're all true and they're clearly not all selected so to be able to prevent that what we want to do is we can come right here and we can say our tab buttons and so for each one the area selected will go to false every time we click on one of our links because when we do our switch Tab and we'll also switch the Z index to negative one because right now the Z index of zero is staying on this one we don't want that to happen so let's save that and see what happens now so if I click uh the only thing is we've killed our Z indexing so the new tab will also need to do that so let's just grab this paste it here and just switch that to new tab set attribute to zero so now when I go like that it's working and if I Tab and then tab it goes to that one now the only thing is I can't switch to the other tabs and we're going to need to build that functionality in and one thing I was I was saying before with the Aria controls it doesn't quite do what we want it to do if you do want to add in like an extra layer there is a way to do that as well where we can give a bit more context to this this is definitely something where you'd want to test it and obviously there's issues if you have like internationalization going on with different languages and other stuff but I'm not going to include this in the finished version of mine but what you could do and I'm just going to throw it in the HTML here but you'd probably want to have this also as a progressive enhancement where you could do an area described by and then have like a this is looking at an ID so and then in the advertising here we could have a div that is has the ID of focus hint and it would also be hidden so we don't see it um interesting thing a lot of area attributes can access the information of these types of things so this could be like press tab and I don't need it here anyway we'll move this in a second but press tab to move to the tab panel right so and I put it here but we don't want it inside that we and we probably have it right here instead um so we're doing our Focus hint so what this is doing is it's something that's completely hidden from the user and you just have this area described on each one of those and again you could use JavaScript to insert this and the idea with it is that just if you do feel like the people you do some testing they're having trouble understanding how to work with it you could add this in but again you always have to be aware that maybe by adding it in then it ends up being a lot longer you know there's this extra information that's given when they're on these different things every time they go on it so but just as an option for if you feel like you need something like that to give a little bit of an extra hint so people understand how to interact with everything you're building here a little bit better because it from everything I've from all the Talking I've done tapped interfaces for people who use screen readers um it's a struggle and you have to also remember screen readers aren't only for people that are blind there's low site users and other things as well that are using them is it just helps them understand and interact with the websites um so you know it's it's not just this very small Niche you might be dealing with more people than you expect and again they're weird interfaces aren't something that they're used to coming across and always knowing how to interact with them so sometimes that little bit of extra information can be helpful but what's good here is because we made this it's our own like we have a function here called switch Tab and our switch tab is working when we click which is what we want but we also want to be able to switch tab as I said with you know if I'm on this tab and I'm keyboard navigating I want to be able to use my keys to be able to switch between the different tabs and if we built all of this functionality all inside of this uh the event listener here the click event listener then we wouldn't be able to do that so that's another nice reason if you have a sort of a separate function when someone clicks we're doing something take that doing something and make it its own function because then you can reuse it sometimes in good ways and so let's come right here and what we're going to do is we're going to create a new function and we'll do a move left to start with and then we'll come back after and do a move right and of course you got a spell function properly and how this function is going to work is it's going to look at what the currently active tab is and so that means like if we've tabbed onto something you know this is in Focus right now or even if I've clicked on it it is in Focus but um it's not getting the focus ring just because it's not the focus within type of thing that we have on these days which is really nice or not the focus visible I should say so we can get that by saying that our current tab is the current active element um which is is a nice easy way to be able to get which one our active one is here and it is assuming that we're currently interacting with our tab system because it the move left and move right it shouldn't do anything uh um and where we're going to use this function is only going to be if we're inside of this like we're actively interacting with it anyway so this won't have any like if I'm tabbed down to here and I'm using my arrow keys it's not it's never going to get fired so we don't have to worry about that now the thing with the tab is when I go when I push left I want it to move left but if I'm on advertising and I push left again I actually want it to cycle through back to this side so we can cycle all the way through one way or eventually at the right we won't be able to forget the email and they push right I want to go back to the start that way so the simple way without worrying about that is we can do this where we can go switch we can run move left we'll switch tab to the current tab so it's going to look at the current tab it's going to go to the parent element and then it's going to go to the previous element sibling and it's going to find the link that's in there and then that link is what is the new tab that will get activated through our switch tab functionality now this might seem a little bit weird it's just because we're doing some Dom Dom traversal traversal traversal um so right so say I'm on socials and I push left what I need it to do is go to the parent element the parent element so if I'm on my socials and that means I'm on this and then so we're saying thing if we look here we're going to the parent element so the parent element is my presentation then we're going to the previous element sibling so the previous element which is a sibling will be this Li right here and then from there we're doing a query selector of a so we're going and grabbing this right there so we're just moving from here down a level across and then back up so it's not that bad to be able to do it but of course as I said we don't want this to function all the time because if I'm on advertising and I push to the left I do want to be able to get to the email over here and that one's a little bit trickier maybe there's a way we could Traverse to always the first one so what we want to do now is you know if as I said if we're at the end of the list what do we do then and so I'm gonna do this so if the current tab parent element previous sibling we don't have one with the escalation point here so if that doesn't happen then we want to switch tab to our tab buttons and we're going to look at the index so because it's a node list we can pick based on that and then we just look at tab buttons dot length minus one and the reason we do a minus one is we have four items here but we're counting from zero so this last one the index of that one is three right so we just always subtract one and by doing it this way you could have two tabs or ten tabs and it's always going to work and it's always going to choose the last one right there so we can say if that and then else I'll just select everything there and hit save to format it thanks to prettier so we say if there isn't a previous sibling we'll cycle over to here and the rest of the time we'll
Original Description
Creating tabs takes a bit of work, and making sure they’re accessible can be a little tricky. First, you should ask if you even need tabs in the first place, but assuming you do, this video looks at creating some progressively enhanced tabs.
🔗 Links
✅ The finished code: https://codepen.io/kevinpowell/pen/oNQgRKm
✅ Accessibility guidelines for tabs: https://www.w3.org/WAI/ARIA/apg/patterns/tabs/
✅ Heydon Pickering’s site: https://heydonworks.com/
✅ Heydon’s Webbed Briefs (watch these, they’re great): https://briefs.video/
✅ Equalize Digital’s Accessibility Checker for WordPress: https://equalizedigital.com/accessibility-checker/
⌚ Timestamps
00:00 - Introduction
00:50 - Maybe tabs are a bad idea
03:13 - The HTML
06:45 - Showing only the active tab content
09:50 - Showing the correct tab panel when we click on a new tab
17:45 - Assistive technologies, ARIA, and roles
20:38 - Adding roles to the list and list items
26:30 - How to know the expected and best ways for interaction like this
28:30 - aria-controls don’t actually do anything?
29:58 - Making the panels focusable and the tabs and panels the correct roles
32:00 - Adding aria-selected to the active tab
33:10 - Styling it up with semantic CSS
35:14 - Updating the active panel when we select a new tab
36:40 - Giving screen readers more information
39:04 - Adding keyboard navigation to switch between tabs
50:15 - Improvements and changes that you can make to this
#css
--
Come hang out with other dev's in my Discord Community
💬 https://discord.gg/nTYCvrK
Keep up to date with everything I'm up to
✉ https://www.kevinpowell.co/newsletter
Come hang out with me live every Monday on Twitch!
📺 https://www.twitch.tv/kevinpowellcss
---
Help support my channel
👨🎓 Get a course: https://www.kevinpowell.co/courses
👕 Buy a shirt: https://teespring.com/stores/making-the-internet-awesome
💖 Support me on Patreon: https://www.patreon.com/kevinpowell
---
My editor: VS Code - https://code.visualstudio.com/
---
I'm
Watch on YouTube ↗
(saves to browser)
Sign in to unlock AI tutor explanation · ⚡30
Playlist
Uploads from Kevin Powell · Kevin Powell · 0 of 60
← Previous
Next →
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
How to create an awesome navigation bar with HTML & CSS
Kevin Powell
Improve your CSS by Keepin' it DRY
Kevin Powell
HTML & CSS for Beginners Part 6: Images
Kevin Powell
HTML & CSS for Beginners Part 7: File Structure
Kevin Powell
HTML & CSS for Beginners Part 4: Bold and Italic text and HTML comments
Kevin Powell
HTML & CSS for Beginners Part 5: Links
Kevin Powell
HTML & CSS for Beginners Part 3: Paragraphs and Headings
Kevin Powell
HTML and CSS for Beginners Part 1: Introduction to HTML
Kevin Powell
HTML and CSS for Beginners Part 2: Building your first web page!
Kevin Powell
HTML & CSS for Beginner Part 8: Introduction to CSS
Kevin Powell
HTML & CSS for Beginners Part 9: External CSS
Kevin Powell
HTML & CSS for Beginners Part 10: Divs & Spans
Kevin Powell
HTML & CSS for Beginners Part 11: Classes & IDs
Kevin Powell
HTML & CSS for Beginners Part 12: The CSS Box Model - Margin, Borders & Padding explained
Kevin Powell
HTML & CSS for Beginners Part 13: Background Images
Kevin Powell
HTML & CSS for Beginners Part 14: Style Text with CSS
Kevin Powell
HTML & CSS for Beginners Part 15: How to style links
Kevin Powell
HTML & CSS for Beginners Part 16: CSS selectors and Specificity
Kevin Powell
HTML & CSS for Beginners Part 17: How to Create and Style HTML Lists
Kevin Powell
HTML & CSS for Beginners Part 18: How Floats and Clears work
Kevin Powell
HTML & CSS for Beginners Part 19: Colors with CSS - hex, rgba, and hsla
Kevin Powell
HTML & CSS for Beginners Part 20: How to center a div
Kevin Powell
HTML & CSS for Beginners Part 21: How to create a basic website layout - the HTML
Kevin Powell
HTML & CSS for Beginners Part 22: How to create a basic layout - the CSS
Kevin Powell
How to Create a Responsive Website from Scratch - Part 1: The HTML #Responsive #HTML5
Kevin Powell
How to Create a Responsive Website from Scratch - Part 2: The Header and Hero area #Responsive #CSS3
Kevin Powell
How to Create a Responsive Website from Scratch - Part 3: The About Section #Responsive #CSS
Kevin Powell
How to Create a Responsive Website from Scratch - Part 4: Building a Responsive Portfolio Section
Kevin Powell
How to Create a Responsive Website from Scratch - Part 5: Call To Action and Footer #CSS #Responsive
Kevin Powell
Tutorial: Learn how to use CSS Media Queries in less than 5 minutes
Kevin Powell
End of the year upate and what's coming to my channel to start the new year
Kevin Powell
Create a CSS only Mega Dropdown Menu
Kevin Powell
CSS Tutorial: Outline and Outline Offset
Kevin Powell
CSS Blending Modes
Kevin Powell
Parallax effect | 2 different ways to add it with jQuery
Kevin Powell
CSS Units: vh, vw, vmin, vmax #css #responsive #design
Kevin Powell
How to Create a Website - Complete workflow | Part 01: Intro + Setting things up
Kevin Powell
100 Subscribers speed coding bonus video
Kevin Powell
How to Create a Website - Complete workflow | Part 02: The Markup #HTML
Kevin Powell
How to Create a Website - Complete workflow | Part 03: Sass Variables and a Mixin #Sass
Kevin Powell
How to Create a Website - Complete workflow | Part 04: Setting up the hero and header
Kevin Powell
How to Create a Website - Complete workflow | Part 05: Typography & Buttons
Kevin Powell
How to Create a Website - Complete workflow | Part 06.1: Building the navigation with Flexbox
Kevin Powell
How to Create a Website - Complete workflow | Part 06.2: Making the nav work with jQuery
Kevin Powell
Redesigning & Coding My Website #CreateICG
Kevin Powell
How to Create a Website - Complete workflow | Part 07: Starting the flexbox grid
Kevin Powell
How to Create a Website - Complete workflow | Part 08: Promo & Problem shooting!
Kevin Powell
How to Create a Website - Complete workflow | Part 09: The CTA and Footer
Kevin Powell
How to Create a Website - Complete workflow | Part 10: Making it responsive
Kevin Powell
How to Create a Website - Complete workflow | Part 11: Making it responsive con't
Kevin Powell
How to Create a Website - Complete workflow | Part 12: Putting the site online
Kevin Powell
Create a Custom Grid System with CSS Calc() and Sass
Kevin Powell
CSS em and rem explained #CSS #responsive
Kevin Powell
Should you use Bootstrap?
Kevin Powell
How to add Smooth Scrolling to your one page website with jQuery
Kevin Powell
Let's learn Bootstrap 4
Kevin Powell
How I approach designing a website - my thought process
Kevin Powell
Build a website with Bootstrap 4 - Part 1: The setup
Kevin Powell
Build a website with Bootstrap 4 - Introduction
Kevin Powell
Build a website with Bootstrap 4 - Part 2: Customizing Variables
Kevin Powell
More on: Prompt Craft
View skill →Related Reads
📰
📰
📰
📰
Building a Browser-Based Tiled Poster PDF Generator
Dev.to · Gaven
3 Next.js Micro-Interactions to Make Your App Feel Premium
Dev.to · jackke88
Test your vanilla JS app in the real browser, with no build step
Dev.to · Kevin Julián Martínez Escobar
Modern Frontends Don’t Have One “Ready” State
Dev.to · Markus Gasser
Chapters (16)
Introduction
0:50
Maybe tabs are a bad idea
3:13
The HTML
6:45
Showing only the active tab content
9:50
Showing the correct tab panel when we click on a new tab
17:45
Assistive technologies, ARIA, and roles
20:38
Adding roles to the list and list items
26:30
How to know the expected and best ways for interaction like this
28:30
aria-controls don’t actually do anything?
29:58
Making the panels focusable and the tabs and panels the correct roles
32:00
Adding aria-selected to the active tab
33:10
Styling it up with semantic CSS
35:14
Updating the active panel when we select a new tab
36:40
Giving screen readers more information
39:04
Adding keyboard navigation to switch between tabs
50:15
Improvements and changes that you can make to this
🎓
Tutor Explanation
DeepCamp AI