DEV Community

Takane Ichinose
Takane Ichinose

Posted on


#CodepenChallenge Navigation: Responsive Glassy Navbar

Mobile-first responsive navigation menu design concept.

The structure of the links is just exactly the same as how I forked it. It is like, I just added some classes, and some elements, example for icons, or the text itself.

The menu and sub-menu was created with recursive function.

How I did it


First, using the default layout in HTML, I tried to style the navigation menu. There is no crucial part in styling, it is just how you want the navigation to look.


Honestly, because I really want to use the GSAP, I brute-forced this one. So if there is anyone who has better code for this, please comment down below.

// This is the recursive function that will create the elements
createMenuJSX(menu = {
  // The array that will be rendered
  let link = [];

  for (let i in menu) {
    let m  = menu[i];
    let ic = <i className="cpc-icon cpc-hidden fas fa-caret-down"></i>;

    if (typeof m.icon !== 'undefined') {
      ic = <i className={'cpc-icon ' + m.icon}></i>;

    // if 'menu' object is undefined (if it doesn't have a sub menu),
    // just show content.
    if (typeof === 'undefined') {
      // Note the useless elements here, this is to maintain balance
      // between the texts and icons. I think there is a better way
      // here, but I ran out of ideas, so I kept it like this.
          <a href={}>
            <i className="cpc-caret cpc-hidden fas fa-caret-down"></i>
    } else if (typeof === 'object') {
      let tmpSubmenu = this.state.submenu;
      let tmpLength  = tmpSubmenu.length;

      // Create a temporary array. This will be used later for
      // rendering, as well as the 'ref' for GSAP animation.
        'active': false,
        'caret': React.createRef(),
        'sub': React.createRef()

      // The click event handler is here.
      // The caret and sub menu ref is set here. As mentioned earlier
      // I need this to use the GSAP as animation. If I would not use
      // it, I can easily set the class, and will not use brute force
      // in rendering these elements. I can directly put this method
      // as rendering method in render() method.
            onClick={this.menuClickEvent.bind(this, tmpLength)}
              className="cpc-caret fas fa-caret-down"
          <ul className="cpc-sub" ref={tmpSubmenu[tmpLength].sub}>

      this.setState({submenu: tmpSubmenu});

  return link;

// I used the created jsxData state to display the elements.
render() {
  return (
    <nav className="cpc-menu">
      <ul className="cpc-main">
Enter fullscreen mode Exit fullscreen mode

Changing the state

Now, we already rendered the elements, let's go to the click events, to show the sub menu of the menu with a caret.

menuClickEvent(i) {
  let submenu = this.state.submenu;
  let tmpmenu = submenu[i];
  // This is how you get the element that was set as a 'ref'
  let sub     = tmpmenu.sub.current;
  let caret   = tmpmenu.caret.current;

  if ( === false) { = true;

    // GSAP animation for caret. Notice that I used the ref
    // for this one., 1, {
      transform: 'rotate(180deg)',
      ease: Elastic.easeOut.config(1, 0.3)

    // GSAP animation for sub menu. Notice that I used the ref
    // for this one., 1, {
      height: sub.scrollHeight,
      visibility: 'visible',
      ease: Elastic.easeOut.config(1, 0.3)
  } else { = false;

    // GSAP animation for caret. Notice that I used the ref
    // for this one., 1, {
      transform: 'rotate(0deg)',
      ease: Elastic.easeOut.config(1, 0.3)

    // GSAP animation for sub menu. Notice that I used the ref
    // for this one., 0.5, {
      height: 0,
      ease: Bounce.easeOut
    }).eventCallback('onComplete', () => {
      // 'eventCallback' will be called after some events was called,
      // like, start, stop, complete, etc. In my case, I used complete., 0, {
        visibility: 'hidden'

  submenu[i] = tmpmenu;

  this.setState({submenu: submenu});
Enter fullscreen mode Exit fullscreen mode

So, this is how this menu and sub-menu is working. If you have better suggestion for this one, please comment down below.

You'll notice that I coded it crappy. It is because I am not yet good in ReactJS. I'm still practicing it.


To conclude this challenge, it was fun, that I learned many things about react. While I'm coding, of course, I am reading the documentation. This is my first time to do the recursion in ReactJS. Well, it is just the same as usual recursion actually. I also want to know more about GSAP animation, because I've been coding the animation at CSS only.


Google Fonts: Montserrat
Font Awesome: Icons
ReactJS: Functionality and rendering
GSAP: Animation

Top comments (0)

Timeless DEV post...

Git Concepts I Wish I Knew Years Ago

The most used technology by developers is not Javascript.

It's not Python or HTML.

It hardly even gets mentioned in interviews or listed as a pre-requisite for jobs.

I'm talking about Git and version control of course.

One does not simply learn git