Video #1: Responsive Menus with TailwindCSS

Show notes and transcription for the video episode: Responsive Menus with TailwindCSS
web
css
video
youtube
Author
Affiliation

miah0x41

Published

June 25, 2024

Modified

June 25, 2024

Video on Responsive Menus with TailwindCSS featuring YouTube logo.

Increasingly Data Explorers and Practitioners are using websites and web applications to communicate their insights and findings.

TailwindCSS is a utility-first Cascading Style Sheet (CSS) framework that allows you to build responsive web pages quickly. In this guide, we will build a responsive menubar with dynamic icons and no Javascript using exclusively TailwindCSS.

This guide has demonstrated how to build a responsive menu with dynamic icons and no Javascript using exclusively TailwindCSS. The key concepts demonstrated were using a checkbox and the peer-* classes to trigger and record the state of the menu. The for attribute of the label tag was used to provide an alternative target to activate the checkbox. When combined with the group-* classes, this provided a dynamic menu system where the icons changed based on the menu state.

It should be noted that the episode is based on the Responsive Menus with TailwindCSS blog post. If you would like help with any of the topics discussed or the methodology use then please contact me through LinkedIn.

This post contains the show notes for the following Curious Data Explorer YouTube video:

Show Notes

The following terms, services, concepts and libraries were mentioned in the episode:

HTML
Hyper Text Markup Language - the semantic structure of a website.
CSS
Cascading Style Sheets - the styling of a website.
CSS Frameworks
A pre-prepared library that is meant to be used as a foundation for a website.

Welcome

Welcome to the Curious Data Explorer channel. My name is Ashraf and I’m an experienced Data Practitioner.

The focus of this video is responsive menus for web pages and applications using Tailwind CSS utility classes. We’ll build a menu that is suitable for both desktop and mobile use including dynamically changing the menu symbol from the classic “hamburger” to a cross all without JavaScript. Furthermore we’ll illustrate the key supporting principles and the right behaviors required for validation.

Introduction

The scope is to build a responsive menu system for a web application or site.

Primarily, we’ll be using the flexbox concept from Cascading Style Sheets (CSS) accessed through the flex Tailwind utility class.

There are three key principles that support this menu system that mean we can avoid the use of JavaScript and keep the overall application snappy. The first combines the checkbox input tag, peer class and its modifier peer-checked. This enables a sibling or peer - which is defined as two elements that have a common parent - to react to a change in state in the target element. We’ll use this to make the navigation links visible when the checkbox is activated.

The second provides a HTML native method to trigger a change in a peer element applicable between an input tag and it’s label. Specifically, we’ll illustrate a design pattern that combines the for attribute of the label.

The third illustrates how the child elements can react to an interaction in their common parent using Tailwind’s group utility class and subsequent modifiers. We’ll also illustrate a lesser known combination of the peer and the group classes that allows the dynamically change to the mobile menu.

Summary

Looking at each of the principles in turn, the first is the use of the peer utility class and its modifier peer-checked. The example code shows two tags, an input of type checkbox and a div that contains the navigation links.

The input tag has a class peer whereas the div by default is hidden using the namesake class and uses the peer-checked modifier to become unhidden using the block class.

The figure on the right shows the effective relationship between the elements. In this instance both the input and div tags have a common parent tag called header. Making them both siblings or peers of each other. The utility class peer is then used to capture actions performed on the target element to which its peer can respond. In this example, when the checkbox is activated, the div becomes unhidden showing the navigation menu.

The second principle is a HTML native mechanism that replicates the behavior of Tailwind’s peer class but applies to specific HTML tags. The example code shows two tags an input of type checkbox and a label that contains the mobile menu button, typically, a hamburger menu icon.

The Input class has a unique ID in this instance, “menu-toggle”, The label tag contains an attribute called for which identifies the input element that the label is applicable for. It contains the ID from the input tag.

The figure on the right shows the effective relationship between the elements. Much like the previous example, both the input and label tags have a have a common parent that makes them siblings or peers. And much like the utility class peer, the HTML native relationship between these elements using the for attribute means that an action on the label is in effect forwarded it to the checkbox.

In practice it means that when the hamburger menu is clicked, it activates the checkbox. To complete the example, note that the checkbox has the class hidden as it has been replaced by its label

The final code principle combines tailwinds peer and group utility classes in transmitting the change in state of the checkbox to change the hamburger menu symbol to that one of a cross. When the menu is open.

The example code shows the same two tags as before but includes one of the two icons in this instance an SVG. The input tag utilizes the peer utility class and normally would enable its sibling or peer elements to respond to the activation of the checkbox using the peer-checked modifier.

As illustrated previously, the modifiers are only applicable to peer elements only. To transmit the change of state to the child elements of the label we can couple it with the group class. The end result is a little bit counter intuitive in terms of the class definition on the SVG.

The outcome is to hide the Hamburger symbol when the checkbox is clicked. Using the hidden class. And when the mobile menu is open, whilst displaying the cross SVG instead. The trigger is using the group class to receive all actions from the parent label using the empty square brackets and then respond to the parent’s peer checkbox activation

If you found that confusing, the figure on the right shows the effective relationship between the elements. The input and label tags are peers and the SVG is a child of a label. The SVG cannot respond to peer-modifier such as peer-checked from the input. To overcome this applying group to its parent and using the universal group modifier the SVG can now respond to peer signals received by its parent.

Blog

This video is based on a blog post called “Responsive Menus with TailwindCSS” at the home of the Curious Data Explorer channel. You can access this from the URL provided or using the QR code. We tailor our content for a variety of mediums from blog posts to podcasts to this very video. So it’s worth reading the blog post in addition to this video for more of the finer details. If you find this guide or any of our content useful then please engage with us with a comment, like or by subscribing.

Most of all tell a friend!

My name is Ashraf I’m a Curious Data Explorer.

Let’s now begin the guide!

Guide

The starting point is a HTML or HyperText Markup Language document. Which consists of a document type declaration at the top. A HTML tag with a language attribute specifying the English language. Within a pair of head tags, we have two meta tags.

The first sets the character encoding of the document in this particular case UTF or Unicode. The second resets the behavior of mobile web browsers. Which automatically scale desktop sites. This ensures no scaling occurs as we will managing the site experience directly using a responsive menu system.

On line seven we have the title of the web page and on line ten, We use the content delivery network or CDN installation method for the TailwindCSS Library. On line thirteen we have a pair of empty body tags.

The output of all of this is in effect a blank page. Let’s begin with some dummy content. Within the body tab, we include a set of header tags semantic clear, the menu sits as part the header of the document, and that will be the focus of this tutorial.

The second part is some example content. Which consists of a level one header and a paragraph with an example text. If we save the document It produces an output And this will provide some context for the menu that we’ll be developing.

For the header we set a background color of dark blue, and a default text of text-gray-300. The header consists of three parts The first is the logo. An outer div followed by a link which consists of an image file and some text. If we save this we can start to see the beginnings of our desktop menu.

The second part is the menu. This again contains an outer div semantically, we’re gonna provide a navigation so we use the nav tag which consists of unordered lists using the UL tag. There are three list items specified by the LI tag consisting of links targeting home our team and about us. If we save we can start to see that all of the text is left aligned and stacks on top of each other.

The final element is a Call-To-Action or CTA button consisting of a link and a button tag. With the words contact us. If we save all of those elements we can see on the right hand side that each item is stacked on top of each other.

The key to our desktop menu is the use of the Flexbox. Cascading Style Sheets or CSS.

To begin with we’ll focus on the header tag. First of all we specify flex. Now by default the flex box is row orientated. And in my view it’s helpful to make that explicit. So we’ll add flex-row.

Secondly we’d liked all the items to be vertically centered. So we use the term item-center And finally, add some padding This aligns the three elements horizontally in the row direction. But as you can see they’re in close contact don’t quite look at the desktop menu.

The intention is to have the logo and associated text on the left hand side and the remaining elements push the right hand side side side. . There’s a number of ways to achieve this. But one of the methods is to use the flex-1 utility class. This class means that the logo element will consume all available free space In effect pushing the other items to the right hand side.

The next step is to put the logo next to the logo text Again we use flexbox. We specify flex By default the orientation is row. So we we specify the term flex-row We want to vertically center the item so we use item-center followed by a gap of two and vertical padding of two as well.

We reduce the size of the symbol using the h10 class The next step is to modify the menu again we use flexbox plus specified flex by default it’s row orientated We want to center the items vertically for these items-center We want to separate the two items out so we use the term justifiy-between with a gap of four and a padding of four. The result looks closer to a menu which is vertically aligned.

The third element is to make the button - the Call To Action button - look like a button. Let’s start off with a bit of background so we can see the changes that we’re making To give the item its button shape we’ll add some horizontal padding some vertical padding, change the font weight to medium. Change the color to text-gray-200 and add rounded corners.

For interactivity let’s add a hover effect We change the text to white. We change the background color for something lighter: bg-sky-500. Which we can see changes as we hover over the button. At this stage we have a realistic looking desktop menu.

The desktop menu requires a tiny bit of polish. First of all let’s add a hover effect to the symbol using hover and scale-105 which increases the scale by five percent For the text itself, let’s make a number of modifications.

We’ve converted the text to uppercase. We’ve increased its size We increased its font weight. On hover the text turns to white. There’s an underline effect. And the underline offset is four pixels To see that in effect , let’s move our mouse over the logo. We can see it increases by a small margin. Likewise let’s hover over the text and we can see the underline effect What we want however, is that when we hover over one feature we want both features to be interactive.

This can be achieved using Tailwind’s group class. There are three changes that have been made The first is on line 18 we’ve added the group class This is the parent element to both the image and the span tag containing the Root Insights text For the image We’ve changed from hover to group-hover for the scale-105 percent.

Likewise for the text we’ve gone from hover for the the text color change, the underline and the underline offset to group-hover The impact of that is that now if we hover over the text the symbol increases in size or if we hover over the symbol, the text has an underline. This is the principle of the group CSS class.

Mobile Menu

The next task is to look at the same webpage using a mobile browser In this particular case we use an iPhone 12 or 13 viewport. As you can see The text has overlapped. We have a menu items overlapping and text wrapping occurring for each menu link as well as for the button itself. To help us focus on the key issues let’s first of all hide the navigation

Having hidden the navigation we can see that the logo and the symbol are a little bit large as is the button itself. So we can make some minor modifications for the medium breakpoint using the md: keyword. To make the header more mobile friendly we’ve made two key changes The first is - as Tailwind is a mobile first utility framework, we specified a height of h-8. At the medium break point we go back to the original h-10 which we use for the desktop For the text. For mobile use, the size is text-xl and for medium breakpoint text-2xl.

And finally for the Call To Action button, the default text size is text-sm for small at the medium break point it reverts to text-base as using the desktop menu. If we unhide the menu again, we can see the challenge before us. The three menu links are cramped between the logo on the left and the Call To Action button on the right.

To start to address the challenge with the menu we can start by using the flex-wrap class. Applying on the header pushes the final element to a new line. Which is similar to what we want because we want the menu items to sit below the logo and the Call To Action.

But to do so we need to change the order of things. We really want the Call To Action button to in effect be in the middle of the three sets of elements. To do that we need to move the button physically on the DOM, the document object model

The Call To Action button has now been moved to line 33 and we can see that the menu the mobile menu is starting to take shape. The next step is to change the orientation of the navigation menu from being row-wise to column-wise.

One mechanism to implement this is in effect only enable flexbox at the medium break point This has the effect of stacking the three menu links together. The second change we wish to make is to make each item, menu item full width This would force it to sit below the remaining text We can do that on the div. But that means for the medium break point we just set the width to be automatic Now it’s starting look more and more like the mobile menu.

There are two issues with the current layout The first is the logo and the menu links no longer align, and the links are lacking some basic effects. The first step is to disable the padding The second step is to modify each link. Each link now has a hover effect in the desktop menu including white text , underline effect and underline offset of four pixels As this is a mobile first utility library, We enable block We add some by default vertical padding or py-3 but the medium break point we remove that The effect of that is to provide a bit of spacing and some uniform width.

Now that the mobile menu looks appropriate we need to trigger the menu. And to begin with we’ll use a checkbox To trigger the menu on the checkbox was applied the class peer which means correspondingly on the div for the menu, we can respond with peer-checked In this instance when the checkbox is clicked, we’d like the element to have a block layout Otherwise by default to be hidden but the medium break point to also be block. This makes the menu disappear such that when we now check the the checkbox it comes up. If you click on it it deactivates.

So we now have a dynamic menu. There are multiple methods to remove the checkbox. One method is to hide it which is what we intend to do. The second is people tend to put a menu icon on top of the checkbox So by clicking on the menu icon, they inadvertently click on the checkbox as well. As we’re going do the former. We’ll add a mobile menu button. To do so we’ll use the label and for attribute to selectively choose the same ID. So on line 45 that’s what we have We also add a cursor pointer and some left margin.

Within that we have a hamburger menu taken from open source. When we say we can see the menu appear on the right hand side. If we now click on this It checks the checkbox and it opens the menu. We can now hide the checkbox using the hidden class leaving just the menu icon

Next we add the close icon. This is a cross SVG. Please note that by default on line 70 we have hidden the cross icon. If we save, this has zero impact on the output. We can’t see it. This is where Tailwind Utility classes, both the peer and the group are combined to allow us to dynamically change the icon based on the state of the checkbox.

The first thing to do is to add the group class to the label Secondly we want the Hamburger menu to disappear once the checkbox is clicked and it’s affected by the group So on line 53 , we add a peer-checked pseudo class which is group to match any any response And the results of that is then the hidden class. So in effect If the group itself is toggled, the hamburger menu is hidden For the close icon we have the reverse the close icon goes from hidden to block.

If we now open the menu we can see that the symbol has dynamically changed to a cross It’s not possible to animate an element that goes from hidden to block. What we can animate is the height. So rather than having rather than having these utility classes we can change them for a default height of zero and then when the checkbox is checked a height of 36.

If we now click on the menu, we get exactly the same effect. But the fact that the height is changing means we can now start to animate it. The second observation is you can see here the links are visible We need to curtail this using overflow-hidden. But at the same time also add a transition. To clip the text let’s add overflow-hidden. Followed by some transitions transition-all and duration of 300 milliseconds with a delay of 150ms a very smooth animated effect.

Desktop Menu Fixes

We now have a complete mobile menu With the functioning setup But having made some structural changes what does it look like in terms of the desktop menu? The desktop menu now no longer seems appropriate. We still have the hamburger menu visible We have the Call To Action button but in the wrong place. The navigation bar is missing So to rectify those we need to modify the menu at the medium break point.

The first step is to hide the hamburger of the menu. At the meeting break point with md:hidden. The second is to have a default height at the medium break point of h-auto. So medium break point The remaining issue is but the the Call To Action and the menu items are in the wrong order we want the call to action in the desktop menu view to be on the right hand side.

We can do this using the order classes. So in this case we want the menu to come first So at the medium break point we can add order-1 That alone would have no changes without corresponding change to the Call To Action button On the Call To Action button, we add them at the medium break point add order-2. And that changes the default order for the medium breakpoint.

And now we’ve gone back to our original desktop menu. And to confirm that nothing has broken we can reactivate the mobile view to ensure that no adverse effects have occurred. In this case we’ve got a fully working menu with the Call To Action button next to the hamburger menu If we go back to desktop menu view , we’ve got the links in the order that we wish them to be to be.

We demonstrated in this video how to create a responsive mobile menu for a web page or application, using TailwindCSS. Beyond the code we showed you three key principles that enable a menu system that can dynamically change the mobile menu icon from a hamburger symbol to a cross all without JavaScript.

In addition to demonstrating the utility of the Flexbox CSS concept, we illustrated the effect of using the peer class to show the navigation links when the checkbox was activated. We use a native HTML peer type relationship between an input tag using its ID and a label tag and its “for” attribute. This enabled us to hide the checkbox and instead trigger a response using custom SVG icons within the label tag.

Finally we combined Tailwind’s peer and group class together to dynamically change the state of a child element when its parent received a response from a peer. All that remains is for me to thank you for watching.

If you found this video useful please engage with us with a comment, like or by subscribing. Most of all tell a friend! Thank you again for watching.

My name is Ashraf, and I’m a Curious Data Explorer.

Attribution

Music and audio clips from:

Back to top

Citation

BibTeX citation:
@online{2024,
  author = {, miah0x41},
  title = {Video \#1: {Responsive} {Menus} with {TailwindCSS}},
  date = {2024-06-25},
  url = {https://blog.curiodata.pro/posts/06-video-1},
  langid = {en}
}
For attribution, please cite this work as:
miah0x41., “Video #1: Responsive Menus with TailwindCSS,” Jun. 25, 2024. Available: https://blog.curiodata.pro/posts/06-video-1