espresso_coffee
espresso_coffee

Reputation: 6110

How to toggle sidebar menu with pure CSS?

I have BS4 sidebar menu that should toggle on click and replace an icon. Here is the code:

.toggle {
  display: none;
}
.menu-head label {
  color: black;
  cursor: pointer;
}
.container {
    overflow: hidden;
    display: inline-block;
}
.side-bar {
    background:#3e4140;
    position: absolute;
    height: 100%;
    width: 200px;
    color:#fff;
    transition: margin-left 0.5s;
}
.side-bar ul {
    list-style: none;
    padding: 0px;
}
.side-bar ul li.menu-head {
    padding: 20px;
    background-color: #ECECEA;
}
.side-bar ul .menu li a {
    color:#fff;
    text-decoration: none;
    display: inline-table;
    width: 100%;
    padding-left: 20px;
    padding-right: 20px;
    padding-top: 10px;
    padding-bottom: 10px;
}
.side-bar ul .menu li a:hover {
    border-left:3px solid #ECECEA;    
    padding-left:17px;
}
.content {
    padding-left: 200px;
    transition: padding-left 0.5s;
}
<!doctype html>
<html lang="en">

<head>
  <meta charset="utf-8">
  <title>Home Page</title>
  <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/css/bootstrap.min.css" integrity="sha384-Gn5384xqQ1aoWXA+058RXPxPg6fy4IWvTNh0E263XmFcJlSAwiGgFAW/dAiS6JXm" crossorigin="anonymous">
  <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/font-awesome/4.7.0/css/font-awesome.min.css">
</head>

<body>
  <div class="container">
    <div class="row">
      <div class="wrapper">
        <div class="side-bar">
          <ul>
            <li class="menu-head">
              <div class="row">
                <div class="col-9">
                  <img class="img-responsive" height="60px" width="60px" src="https://www.w3schools.com/w3css/img_avatar3.png" alt="Logo">
                </div>
                <div class="col-3">
                  <button class="btn btn-sm btn-dark"><i class="fa fa-times" aria-hidden="true"></i></button>
                </div>
              </div>
            </li>
            <div class="menu">
              <li>
                <a href="#">Home <i class="fa fa-home" aria-hidden="true"></i></a>
              </li>
              <li>
                <a href="#">Calendar <i class="fa fa-calendar" aria-hidden="true"></i></a>
              </li>
              <li>
                <a href="#">Education <i class="fa fa-university" aria-hidden="true"></i></a>
              </li>
              <li>
                <a href="#">Settings <i class="fa fa-cog" aria-hidden="true"></i></a>
              </li>
            </div>
          </ul>
        </div>
        <div class="content">
          <div class="card m-5">
            <div class="card-header">Featured</div>
            <div class="card-body">
              <h5 class="card-title">Special title treatment</h5>
              <p class="card-text">With supporting text below as a natural lead-in to additional content.</p>
              <a href="#" class="btn btn-primary">Go somewhere</a>
            </div>
          </div>
        </div>
      </div>
    </div>
  </div>
  <script src="https://code.jquery.com/jquery-3.2.1.slim.min.js" integrity="sha384-KJ3o2DKtIkvYIK3UENzmM7KCkRr/rE9/Qpg6aAZGJwFDMVNA/GpGFF93hXpG5KkN" crossorigin="anonymous"></script>
  <script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.12.9/umd/popper.min.js" integrity="sha384-ApNbgh9B+Y1QKtv3Rn7W3mgPxhU9K/ScQsAP7hUibX39j7fakFPskvXusvfa0b4Q" crossorigin="anonymous"></script>
  <script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/js/bootstrap.min.js" integrity="sha384-JZR6Spejh4U02d8jOt6vLEHfe/JQGiRRSQQxSfFWpi1MquVdAyjUar5+76PVCmYl" crossorigin="anonymous"></script>
</body>

</html>

I created the button with font awesome icon that should close the menu. Once the menu is closed the ideal scenario will be to still display the icons on the side. The close (X) icon button should change to menu icon (three horizontal lines). In font-awesome 4.7 the code for that icon is here: <i class="fa fa-bars" aria-hidden="true"></i>. The toggle functionality should use pure css. I already know that this can be done with jQuery but that is not the solution that I'm looking for. Thank you.

Upvotes: 1

Views: 5240

Answers (2)

Vimalraj Chinnaiyan
Vimalraj Chinnaiyan

Reputation: 31

Here the below code I have used for one of my projects. find the demo below

@import url(https://fonts.googleapis.com/css?family=Roboto:400,700);

@keyframes checked-anim {
    50% {
        width: 3000px;
        height: 3000px;
    }
    100% {
        width: 100%;
        height: 100%;
        border-radius: 0;
    }
}
@keyframes not-checked-anim {
    0% {
        width: 3000px;
        height: 3000px;
    }
}
li, a {
    margin: 75px 0 -55px 0;
    color: #03A9F4;
    font: 14pt "Roboto", sans-serif;
    font-weight: 700;
    line-height: 1.8;
    text-decoration: none;
    text-transform: none;
    list-style: none;
    outline: 0;
    display: none;
}
li {
    width: 230px;
    text-indent: 56px;}
a:focus {
    display: block;
    color: #333;
    background-color: #eee;
    transition: all .5s;
}
aside {
    position: absolute;
    color: white;
    top: 35%;
    right: 10%;
    text-align: right;
}
h1 {
    line-height: 0;
    font-size: 4vw;
    font-weight: 700;
}
h3 {
    float: right;
    line-height: .3;
    font-size: 2.5vw;
    font-weight: lighter;
}
h4 {
    float: left;
    margin-left: -2%;
    font-size: 1.5vw;
    font-weight: lighter;
}

html, body {
    margin: 0;
    padding: 0;
    background-color: #03A9F4;
    font-family: 'Roboto', sans-serif;
    overflow: hidden;
}

#trigger, #burger, #burger:before, #burger:after {
    position: absolute;
    top: 25px;
    left: 25px;
    background: #03A9F4;
    width: 30px;
    height: 5px;
    transition: .2s ease;
    cursor: pointer;
    z-index: 1;
}
#trigger {
    height: 25px;
    background: none;
}
#burger:before {
    content: " ";
    top: 10px;
    left: 0;
}
#burger:after {
    content: " ";
    top: 20px;
    left: 0;
}
#menu-toggle:checked + #trigger + #burger {
    top: 35px;
    transform: rotate(180deg);
    transition: transform .2s ease;
}

#menu-toggle:checked + #trigger + #burger:before {
    width: 20px;
    top: -2px;
    left: 18px;
    transform: rotate(45deg) translateX(-5px);
    transition: transform .2s ease;
}
#menu-toggle:checked + #trigger + #burger:after {
    width: 20px;
    top: 2px;
    left: 18px;
    transform: rotate(-45deg) translateX(-5px);
    transition: transform .2s ease;
}
#menu {
    position: absolute;
    margin: 0; padding: 0;
    width: 110px;
    height: 110px;
    background-color: #fff;
    border-bottom-right-radius: 100%;
    box-shadow: 0 2px 5px rgba(0,0,0,0.26);
    animation: not-checked-anim .2s both;
    transition: .2s;
}
#menu-toggle:checked + #trigger + #burger + #menu {
    animation: checked-anim 1s ease both;
}
#menu-toggle:checked + #trigger ~ #menu > li, a {
    display: block;
}
[type="checkbox"]:not(:checked), [type="checkbox"]:checked {
    display: none;
}
HTML CSS JSResult Skip Results Iframe
EDIT ON
<aside>
  <h1>#1 Burger Menu</h1>
  <h4>inspired by</h4><h3>Google Material Design</h3>
</aside>
<input type="checkbox" id="menu-toggle"/>
  <label id="trigger" for="menu-toggle"></label>
  <label id="burger" for="menu-toggle"></label>
  <ul id="menu">
    <li><a href="#">Home</a></li>
    <li><a href="#">About</a></li>
    <li><a href="#">Portfolio</a></li>
    <li><a href="#">Contact</a></li>
  </ul>

Upvotes: 3

G-Cyrillus
G-Cyrillus

Reputation: 106008

here is an example via CSS with an input checkbox to mimic a toggle effect from your code where i turned button into a label linked to an input via for and id. from there you will need to tune a few class or some of your CSS rules so it behaves nicely .

.toggle {
  display: none;
}
.menu-head label {
  color: black;
  cursor: pointer;
}
.container {
    overflow: hidden;
    display: inline-block;
}
.side-bar {
    background:#3e4140;
    float:left;
    height: 100%;
    width: 200px;
    color:#fff;
    transition: margin-left 0.5s;
}
.side-bar ul {
    list-style: none;
    padding: 0px;
}
.side-bar ul li.menu-head {
    padding: 20px;
    background-color: #ECECEA;
}
.side-bar ul .menu li a {
    color:#fff;
    text-decoration: none;
    display: inline-table;
    width: 100%;
    padding-left: 20px;
    padding-right: 20px;
    padding-top: 10px;
    padding-bottom: 10px;
}
.side-bar ul .menu li a:hover {
    border-left:3px solid #ECECEA;    
    padding-left:17px;
}
.content {
    overflow:hidden;
    transition: padding-left 0.5s;
}
#toggle {
position:absolute;right:100vw;/* off sight*/}

#toggle:checked ~ div    .hide {
display:none!important;
}
#toggle:checked ~ div .side-bar {
max-width:0;
margin-right:-30vw!important}
<!doctype html>
<html lang="en">

<head>
  <meta charset="utf-8">
  <title>Home Page</title>
  <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/css/bootstrap.min.css" integrity="sha384-Gn5384xqQ1aoWXA+058RXPxPg6fy4IWvTNh0E263XmFcJlSAwiGgFAW/dAiS6JXm" crossorigin="anonymous">
  <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/font-awesome/4.7.0/css/font-awesome.min.css">
</head>

<body>
 <input type="checkbox" id="toggle">
  <div class="container">
    <div class="row">
      <div class="wrapper">
        <div class="side-bar">
          <ul>
            <li class="menu-head">
              <div class="row">
             
                <div class="col-9">
                  <img class="img-responsive hide" height="60px" width="60px" src="https://www.w3schools.com/w3css/img_avatar3.png" alt="Logo">
                </div>
                <div class="col-3">
                  <label for="toggle" class="fa fa-times btn btn-sm btn-dark text-white" aria-hidden="true"></label>
                </div>
              </div>
            </li>
            <div class="menu hide">
              <li>
                <a href="#">Home <i class="fa fa-home" aria-hidden="true"></i></a>
              </li>
              <li>
                <a href="#">Calendar <i class="fa fa-calendar" aria-hidden="true"></i></a>
              </li>
              <li>
                <a href="#">Education <i class="fa fa-university" aria-hidden="true"></i></a>
              </li>
              <li>
                <a href="#">Settings <i class="fa fa-cog" aria-hidden="true"></i></a>
              </li>
            </div>
          </ul>
        </div>
        <div class="content">
          <div class="card m-5">
            <div class="card-header">Featured</div>
            <div class="card-body">
              <h5 class="card-title">Special title treatment</h5>
              <p class="card-text">With supporting text below as a natural lead-in to additional content.</p>
              <a href="#" class="btn btn-primary">Go somewhere</a>
            </div>
          </div>
        </div>
      </div>
    </div>
  </div>
  <script src="https://code.jquery.com/jquery-3.2.1.slim.min.js" integrity="sha384-KJ3o2DKtIkvYIK3UENzmM7KCkRr/rE9/Qpg6aAZGJwFDMVNA/GpGFF93hXpG5KkN" crossorigin="anonymous"></script>
  <script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.12.9/umd/popper.min.js" integrity="sha384-ApNbgh9B+Y1QKtv3Rn7W3mgPxhU9K/ScQsAP7hUibX39j7fakFPskvXusvfa0b4Q" crossorigin="anonymous"></script>
  <script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/js/bootstrap.min.js" integrity="sha384-JZR6Spejh4U02d8jOt6vLEHfe/JQGiRRSQQxSfFWpi1MquVdAyjUar5+76PVCmYl" crossorigin="anonymous"></script>
</body>

</html>

Nowdays, you can use BS4 instead BS3.

Upvotes: 3

Related Questions