Creating a Floating Icon Menu
Tags: html, css, tutorial
Published: 2020-08-02 09:54:13

In today's post, I wanted to demonstrate just how easy it is to create an icon-based, floating navigation menu for your web projects.

### Video Tutorial
If you prefer this tutorial in video form, check it out on my YouTube channel, **dcode**:
{% youtube uHL6aeWUEQQ %}

### Step 1: Choosing an Icon Library
If you're already using an icon library for your project, feel free to skip this step. For those who aren't, I recommend using something like [Google Material Icons](https://material.io/resources/icons/) as they are super easy to set up and use.

You can start using the library by including it in the `<head>`:
```html
<link href="https://fonts.googleapis.com/icon?family=Material+Icons" rel="stylesheet" />
```

### Step 2: Adding the HTML
We're going to be using the `<nav>` element with a class of `.nav` to represent the menu. Within it, we can specify our icon-links:

```html
<nav class="nav">
    <a href="#" class="nav__link">
        <i class="material-icons nav__icon">dashboard</i>
        <span class="nav__text">Dashboard</span>
    </a>
    <!-- ... and more links below -->
</nav>
```

As we can see, for each link we are using `<a class="nav__link">`, and from within those, we have the following elements:
* `<i class="material-icons nav__icon">[icon_name]</i>` - this is to display an icon of your choice. In this case, I chose to use the `dashboard` icon. You can find more icons [here](https://material.io/resources/icons/).
* `<span class="nav__text">` - this one is quite self explanatory, we're simply choosing which text to display under the icon.

After adding the HTML, you should have something like this:
![After-HTML Preview](https://dev-to-uploads.s3.amazonaws.com/i/vq9vlk9rr6m161un6mp8.jpg)

### Step 3: Adding the CSS
Here is where everything is going to fall into place - we're going to be using CSS to position the menu at the bottom of the page, and floating on top of everything else.

#### Styling the menu
Using `position: fixed` will ensure the menu floats above everything else on the page, and a `bottom: 0` will move it to the bottom:

```css
body {
    margin: 0 0 55px 0;
}

.nav {
    position: fixed;
    bottom: 0;
    width: 100%;
    height: 55px;
    box-shadow: 0 0 3px rgba(0, 0, 0, 0.2);
    background-color: #ffffff;
    display: flex;
    overflow-x: auto;
}
```

We're using `display: flex` here so we can easily lay out the individual icon-links in the next step, and an `overflow-x: auto` allows the user to scroll left and right in cases where there are too many icons on a smaller-width device.

You may have also noticed the `margin` on the `<body>` - this is set to be `55px` on the bottom, which is the same height set for the menu, and will ensure none of the existing body content gets hidden under it.

#### Styling the icon-links
This will definitely be the largest ruleset in the tutorial so let's write the CSS and then go through the important ones individually:

```css
.nav__link {
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    flex-grow: 1;
    min-width: 50px;
    overflow: hidden;
    white-space: nowrap;
    font-family: sans-serif;
    font-size: 13px;
    color: #444444;
    text-decoration: none;
}

.nav__link:hover {
    background-color: #eeeeee;
}
```

Let's take a look at the important properties:
* `display: flex` - allows us to align the icon and label in the centre, and works with `align-items: center;` and `justify-content: centre`
* `flex-grow: 1` - ensures each icon will try to take up equal width
* `flex-direction: column` - ensures the icon and label are on top of each other, as opposed to side-by-side
* `white-space: nowrap` - ensures the label will not flow onto a new line

You should now see something like this:

![After Initial CSS](https://dev-to-uploads.s3.amazonaws.com/i/3jj2i4ny65pkjat7l71m.jpg)

#### Final touch - the "active" link
With this solution, we can also represent a link as being the "active view/page" or something of that nature. Let's add a modifier class in the CSS:

```css
.nav__link--active {
    color: #009579;
}
```

Then, we can add it to one of the links in HTML:
```html
<a href="/profile" class="nav__link nav__link--active">
```

This gives us something like this:

![With active link](https://dev-to-uploads.s3.amazonaws.com/i/4hdt6aa40279cjyz2bi7.jpg)

And that's it! If anyone has any questions or suggestions, please leave them below 😁