Ways to switch sidebar menu using only CSS?

How do I create a BS4 sidebar menu that toggles on click and replaces an icon? See the code below:

.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 am trying to design a button with a Font Awesome icon that closes the menu, but still displays icons on the side when closed. The close (X) icon should change to a menu icon (three horizontal lines). The Font Awesome 4.7 code for the menu icon is

<i class="fa fa-bars" aria-hidden="true"></i>
. The toggle functionality should be achieved using pure CSS without jQuery. Can someone provide a solution for this? Thank you.

Answer №1

Here's a demonstration using CSS to create a toggle effect with an input checkbox. In this example, I transformed the button into a label linked to an input using the for and id attributes. To make it work smoothly, you may need to adjust some classes or CSS rules.

.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>

Today, Bootstrap 4 (BS4) can be utilized instead of Bootstrap 3 (BS3).

Answer №2

Below is the code snippet that I've utilized in one of my recent projects. Check out 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>

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

How to transform HTML content into plain text format while retaining the HTML tags

transform this into something like this2 I'm attempting to convert text containing html tags (p, ol, b) into plain text format (similar to the outcome of running a code snippet) - I've experimented with the following code in .net core but it only ...

Barba.jS is causing a delay in loading scripts after the page transition

One of my index files includes Gsap and Barba JS, while an inner page includes additional JS files such as locomotive.js and OWLcarousel.js. These two JS files are not necessary for the index page. However, when transitioning from the index page to the inn ...

Is there a way to position a pseudoelement behind its parent yet still in front of its grandparent using absolute positioning?

Imagine the following scenario: <div id="one"/> <div id="two"> <div id="three"/> </div> <div id="four"/> I am trying to apply a pseudoelement to three that appears behind it but in front of two (and any other ancestors if ...

Utilizing distinct JavaScript, JQuery, or CSS for individual Controllers within the Codeigniter framework

Currently, I am involved in a Codeigniter v3 project where we are developing a comprehensive application for a large organization. To optimize the loading speed of each page, I am looking to integrate custom JQuery and CSS files/code specific to each Con ...

"Can you guide me on how to display a React component in a

I have a function that loops through some promises and updates the state like this: }).then((future_data) => { this.setState({future_data: future_data}); console.log(this.state.future_data, 'tsf'); }); This outputs an array o ...

Building a JSON-powered navigation bar with Bootstrap 4

Looking to create a custom navigation bar using Bootstrap 4 and populate it with items from a JSON file. Despite researching various methods, there seems to be limited resources available on this topic. Any assistance or guidance would be greatly appreciat ...

Tips for setting height within a flexbox layout?

Is there a way to specify the height of rows in a flex wrap container so that text containers appear square on both smaller and larger screens? I want the sizing to be dynamic, adjusting as the window is resized. Check out this example on CodeSandbox Loo ...

As the screen size shrinks, two components merge together

One issue I'm facing with my site is the component called NavPanel. This consists of two components - a back button (BackToButton) and a search field (SearchTextField). Everything looks fine on a standard screen size, but when the screen size decrease ...

Adjusting iFrame Height to Fit Content Completely

I am looking to create a website where I can have a banner at the top and display another website below it without needing an additional scroll bar within the page. I have tried using an iframe, but I can't seem to get it to display correctly. I want ...

Utilizing JavaScript to dynamically set a CSS file from an API in AngularJS

I am currently facing an issue with integrating a CSS file returned by an API into my entire website. Since the URL of the CSS file keeps changing, hard coding the URL is not feasible. While I have successfully implemented this on 'view1', my goa ...

Challenge with aligning tables

I need assistance with aligning the TD tag value to the TH tag value as I am currently experiencing alignment issues. Can someone please help me resolve this problem? I have attempted to fix it on jsfiddle Here is the HTML code: <table class=" ...

Tips for breaking out of an infinite loop while loading HTML containing a carousel into a blank <div> within another HTML file using jQuery's $(document).ready() function

Currently, I am studying HTML, CSS, Bootstrap 4, jQuery3, and JavaScript (ES6+), and to enhance my skills, I have devised an exercise for practice and consolidation. I have created 4 HTML files, all featuring responsive design based on Bootstrap 4: inde ...

The Fade In effect in jQuery causes my fixed header to overlap with images on the page

This is the javascript snippet using jquery <script type="text/javascript> $(document).ready(function () { $('#showhidetarget').hide(); $('a#showhidetrigger').click(function () { $('#showhidetarget&apo ...

Display only distinct dates in the ng-repeat list

I'm trying to display an unordered list created using ng-repeat. Each list item includes a month header and a blog post. I'm struggling to find a clean solution to only show one instance of each month name without resorting to complex jQuery hac ...

Detection of numerous Google Analytics tags

To troubleshoot a client's Google Analytics account connected to their website, I decided to utilize the Tag assistant by Google extension. Upon running it, an alert popped up displaying "Multiple Google Analytics tags detected." One tag was the one I ...

Is there a way to use JavaScript to alter the existing URL?

Currently, I am utilizing a select tag to allow users to choose the number of 'rows' displayed on the table. <%=select_tag :per_page, options_for_select([10,20,50,100]....some more code...., onchange => "if (this.value) {windows.location=& ...

Is there a way to reposition a popup window to the center of the page after launching it?

popup = window.open(thelink,'Facebook Share','resizable=1,status=0,location=0, width=500,height=300'); My goal is to perfectly center this popup window both vertically and horizontally. ...

issues with alignment between bootstrap div and canvas

I am currently working on a project with a canvas inside a div using three.js. My goal is to display a purple bar for user settings on the right side of the three.js window. However, I am encountering an issue where Bootstrap is not recognizing that I want ...

Is there a way to customize the navbar layout so that link 1 is aligned to the right side, link 2 is centered, and link 3 is positioned on the right?

I attempted to utilize the flex property and justify content, but unfortunately that did not yield the desired result. I experimented with the code provided below. The goal is to create a website layout with a logo at the top and a navigation bar directly ...

Is there a way to stylize the initial words of a brief text block by blending small caps with italics, all while avoiding the use of a span tag?

I have a series of images with numbered captions like "Fig. 1", "Fig. 2", "Fig. 3", followed by a brief description on the same line. Is there a way to programmatically style these strings (the “Fig. #” only) using CSS or Javascript to make them italic ...