Sidenav using pure css

Created on

20 Apr 2019

Updated on

20 Jan 2021

Creating new stuff using CSS is always fun. Although javascript can create a side nav pretty easily, you can do almost the same thing using CSS.

For the CSS modal, I used radio buttons to create the effect. However, for the side nav, I will use the anchor element and :target selector.

Why :target selector?

  • The button that opens the sidebar needs not be placed adjacent to the sidebar.
  • Any number of close button/elements can be created
  • Back button can be used to close the sidebar after it is opened

Are there any disadvantages?

Yes, if a user opens and closes the side nav n times, then the back button also has to pressed n times to go back. But besides that its just like javascript.

Steps

  • Create a button that activates the side nav
  • Create the side nav
  • Open/close the side nav

Creating the button

By button, I mean an anchor element with a href attribute pointing to the side nav.

<a href="#sidenav" class="btn open">≡</a>
.btn {
    display: inline-block;
    height: 40px;
    width: 40px;
    line-height: 40px;
    text-align: center;
    background: #fff;
    color: #333;
    border-radius: 50%;
    text-decoration: none;
    font-size: 1.2em;
    box-shadow: 0 2px 10px -2px rgba(0, 0, 0, .1);
    margin: 20px;
}

I’ve styled it to look like a round hamburger button.

Creating the Sidenav

The side nav can be created in any way that suits you, but remember to add the id sidenav to it.

Here is the code that I used to create it.

<div id="sidenav">
    <ul>
        <li class="center user">
            <img src="https://placeimg.com/300/300/people" alt="User" />
            <p>John Doe</p>
        </li>
        <li class="divider"></li>
        <li class="title">Links</li>
        <li class="item active"><a href="#">Home</a></li>
        <li class="item"><a href="#">About</a></li>
        <li class="item"><a href="#">Portfolio</a></li>
        <li class="item"><a href="#">Testimonials</a></li>
        <li class="item"><a href="#">Contact</a></li>
        <li class="divider"></li>
        <li class="title">Projects</li>
        <li class="item"><a href="#">Project 1</a></li>
        <li class="item"><a href="#">Project 2</a></li>
        <li class="item"><a href="#">Project 3</a></li>
    </ul>
</div>
#sidenav {
    width: 80%;
    max-width: 300px;
    height: 100%;
    position: fixed;
    left: 0;
    top: 0;
    background: linear-gradient(to right, #673AB7, #5E35B1);
    left: -300px;
    transition: left .35s;
}

ul {
    list-style: none;
    height: 100%;
    overflow: auto;
}

.center {
    text-align: center;
}

.user {
    padding: 20px;
    position: relative;
}

.user img {
    width: 150px;
    border-radius: 50%;
}

.user p {
    color: #eee;
    padding: 10px 0;
}

.divider {
    padding: 0;
    height: 1px;
    background: #7e57c2;
}

.title {
    color: #b39ddb;
    text-transform: uppercase;
    font-size: 0.8em;
    letter-spacing: 1px;
    padding: 20px;
    padding-bottom: 10px;
}

.item {
    background: transparent;
    transition: background .35s;
}

.item a {
    text-decoration: none;
    color: #eee;
    display: inline-block;
    padding: 20px;
    padding-left: 30px;
    width: 100%;
}

.item.active,
.item:hover {
    background: rgba(0, 0, 0, .1);
}

Which results in the below side nav

Preview of sidenav

Now all that’s left is to animate open/close.

Opening/Closing the side nav

We need to first make the button that we created in step 1 to work.

For that simply add the below CSS

#sidenav:target {
    left: 0;
}

Now whenever the #sidenav becomes a target, it is animated to appear from the left side.

Now we need to close the side nav. For that, I am using an overlay such that whenever a user clicks outside the side nav, it closes.

Any anchor element that has a href attribute of anything other than #sidenav will close the side nav.

So to create the overlay, I am using an anchor element.

Place the below element right next to #sidenav

<a href="#!" class="close sidenav-overlay"></a>

And add the following CSS

.sidenav-overlay {
    position: fixed;
    width: 100%;
    height: 100%;
    background: rgba(0, 0, 0, 0.3);
    left: 100%;
    top: 0;
    z-index: -1;
    cursor: default;
}

#sidenav:target+.sidenav-overlay {
    left: 0;
}

That’s it we have a working side nav.

Result

Here are the entire code and live result.

<a href="#sidenav" class="btn open">≡</a>
<div id="sidenav">
    <ul>
        <li class="center user">
            <img src="https://placeimg.com/300/300/people" alt="User" />
            <p>John Doe</p>
        </li>
        <li class="divider"></li>
        <li class="title">Links</li>
        <li class="item active"><a href="#">Home</a></li>
        <li class="item"><a href="#">About</a></li>
        <li class="item"><a href="#">Portfolio</a></li>
        <li class="item"><a href="#">Testimonials</a></li>
        <li class="item"><a href="#">Contact</a></li>
        <li class="divider"></li>
        <li class="title">Projects</li>
        <li class="item"><a href="#">Project 1</a></li>
        <li class="item"><a href="#">Project 2</a></li>
        <li class="item"><a href="#">Project 3</a></li>
    </ul>
</div>
<a href="#!" class="close sidenav-overlay"></a>
* {
    margin: 0;
    padding: 0;
    box-sizing: border-box;
}

body {
    background: #f1f1ff;
}

.btn {
    display: inline-block;
    height: 40px;
    width: 40px;
    line-height: 40px;
    text-align: center;
    background: #fff;
    color: #333;
    border-radius: 50%;
    text-decoration: none;
    font-size: 1.2em;
    box-shadow: 0 2px 10px -2px rgba(0, 0, 0, .1);
    margin: 20px;
}

#sidenav {
    width: 80%;
    max-width: 300px;
    height: 100%;
    position: fixed;
    left: 0;
    top: 0;
    background: linear-gradient(to right, #673AB7, #5E35B1);
    left: -300px;
    transition: left .35s;
}

.sidenav-overlay {
    position: fixed;
    width: 100%;
    height: 100%;
    background: rgba(0, 0, 0, 0.3);
    left: 100%;
    top: 0;
    z-index: -1;
    cursor: default;
}

#sidenav:target {
    left: 0;
}

#sidenav:target+.sidenav-overlay {
    left: 0;
}

ul {
    list-style: none;
    height: 100%;
    overflow: auto;
}

.center {
    text-align: center;
}

.user {
    padding: 20px;
    position: relative;
}

.user img {
    width: 150px;
    border-radius: 50%;
}

.user p {
    color: #eee;
    padding: 10px 0;
}

.divider {
    padding: 0;
    height: 1px;
    background: #7e57c2;
}

.title {
    color: #b39ddb;
    text-transform: uppercase;
    font-size: 0.8em;
    letter-spacing: 1px;
    padding: 20px;
    padding-bottom: 10px;
}

.item {
    background: transparent;
    transition: background .35s;
}

.item a {
    text-decoration: none;
    color: #eee;
    display: inline-block;
    padding: 20px;
    padding-left: 30px;
    width: 100%;
}

.item.active,
.item:hover {
    background: rgba(0, 0, 0, .1);
}

Fiddle

If you have any doubts, suggestions or improvements feel free to comment.

Comments

Post a comment

This site is protected by reCAPTCHA and the Google Privacy Policy and Terms of Service apply.