I’ve got a coding challenge a few weeks ago about how to make a navbar out of pure JS/CSS, no library.
I won’t spoil it, especially for the next people doing it, but I thought the idea interesting so I decided to show how one could do one in ReactJS.
So, this is a guide about how to make a simple dropdown navbar from some backend data and simple React/CSS.
and the data we get from our backend to populate this navbar. To do so I’ll format them like this :
12345678910111213141516
[{"text":"THE TEXT OF YOUR LINK","url":"http://THE.URL"},{"text":"THE TEXT OF YOUR LINK","url":"http://THE.URL","submenu":[{"text":"THE TEXT OF YOUR LINK","url":"http://THE.URL"}]}]
The submenu is not needed and we’ll build the navbar accordingly.
Our React components
We have : a Navbar container, Navbar items containing a link and a submenu if possible, and Navbar links.
/** @jsx React.DOM */varNavBarItem=React.createClass({generateLink:function(){//Right now we don't need our class but what if we wanted to change the text, add an arrow or something? //Single responsibility principles tell us that it our "Item" should not handle this.return<NavBarLinkurl={this.props.url}text={this.props.text}/>;},generateSubmenu:function(){//We generate a simple Navbar (the parent). //Spoilers: it takes items as its argument. return<NavBaritems={this.props.submenu}/>},generateContent:function(){varcontent=[this.generateLink()];if(this.props.submenu){//If there is a submenu in our data for this item//We add a generated Submenu to our contentcontent.push(this.generateSubmenu());}returncontent;},render:function(){varcontent=this.generateContent();return(<li>{content}</li>);}})
To sum it up, our Navbar generates NavbarItems from the array of items we gave it.
Each NavbarItem contains a NavbarLink + an optional NavBar, which would simply be the submenu we want.
All in all, it generates an html that looks like this :
Now, we need to style that because it honestly looks like… bad things (PG-rated tutorials FTW).
Nothing fancy in here, you’re the one styling it, but let me show you what you’ll need :
.menu{list-style:none;/* Important for sizing problems when you add/remove the submenus Make it use 100% of the size of your container */width:100%;/* This prevents a lot of problems with the submenus. UL have basic padding, keep that in mind */padding:0;}.menuli{/* I wanted mine horizontal. Feel free to change it to what you want */display:inline-block;/* Float the items to the left, to make sure the disposition does not change when it shows the subitems */float:left;/* The -1px on top and right make it so that our borders end up above one another Not needed it you don't have borders... */margin:-1px-1px00;}.menulia{display:block;/* My basic styling. I'm just giving them a black text, with a black border, and center the text in the box. */text-decoration:none;border:1pxsolidblack;vertical-align:middle;text-align:center;/* Fixed size is also just me. Not fixing it just make huge boxes when you have submenus */width:100px;height:50px;line-height:50px;}.menuli>ul{/****** THE INTERESTING PART ******//* We hide the submenus by putting them somewhere on the left, with no opacity. */left:-9999px;opacity:0;/* We make transitions on opacity */-webkit-transiton:opacity0.3s;-moz-transition:opacity0.3s;-ms-transition:opacity0.3s;-o-transition:opacity0.3s;transition:opacity0.3s;}.menuli:hover>ul{/* On hover, we get it back to its basic spot left:0;/* And change the opacity to a fully visible one */opacity:1;};
The result on a beautiful gist
Here is the link on Github. Feel free to download/tweak and comment it.
Next parts
I plan on giving you the version with the dropdowns triggered by a click instead of a hover. This is coming in a few days, the code is almost ready already ;)
Feel free to let me know if I missed/misexplained anything here or by mail at quentin@devauchelle.eu