Sidenav using pure css

20 Apr 2019

30 Jan 2020

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

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

Latest Posts

WordPress lazy load images with blur up technique

WordPress lazy load images with blur up technique

18 Mar 2020

Lazy loading images in WordPress with blur up technique.

Markdown comments in WordPress

Markdown comments in WordPress

18 Feb 2020

Implement markdown supported comments in WordPress using Parsedown.

Create options page in WordPress using free ACF

Create options page in WordPress using free ACF

17 Feb 2020

Create a custom settings page for your WordPress site using ACF free version.

Sliced text in CSS

Sliced text in CSS

20 Mar 2019

Create sliced/glitch text effect using CSS

Pure CSS modal

Pure CSS modal

19 Mar 2019

Pure CSS Modal with close/open buttons as well as click outside to close ability.

Create animated donut chart using SVG and javascript

Create animated donut chart using SVG and javascript

05 Feb 2019

Animated donut chart using SVG, javascript, and CSS.