1

As you can see in the below code snippet I have a vertical sidebar that can become wider when a TOGGLE button is clicked. The Sidebar eases in with an animation and additionally displays the description text when the sidebar is wide. I think I achieved all of this properly.

My concern is more about my code. It doesn't feel right. Is there anyway I can do this all with simply adding and removing css classes?

Additionally, I would like advice on the way I am using delay to make sure when the extra description text appears it doesn't look horrible.

var menuSize = 'Small';

$(".js-menu-toggle").click(function(e) {
  e.preventDefault();

  if (menuSize == 'Small') {
    $('#sidebar').css('width', '180px');
    $('#content-wrapper').css('margin-left', '180px');

    $('#sidebar').css('-webkit-transition', 'all 0.3s ease');
    $('#sidebar').css('-moz-transition', 'all 0.3s ease');
    $('#sidebar').css('-ms-transition', 'all 0.3s ease');
    $('#sidebar').css('-o-transition', 'all 0.3s ease');
    $('#sidebar').css('transition', 'all 0.3s ease');
    $('#app-wrapper').css('-webkit-transition', 'all 0.3s ease');
    $('#app-wrapper').css('-moz-transition', 'all 0.3s ease');
    $('#app-wrapper').css('-ms-transition', 'all 0.3s ease');
    $('#app-wrapper').css('-o-transition', 'all 0.3s ease');
    $('#app-wrapper').css('transition', 'all 0.3s ease');

    $('.menu-item-desc').delay(120).show(0);

    menuSize = 'Large'
  } else {
    $('#sidebar').css('width', '50px');
    $('#content-wrapper').css('margin-left', '50px');

    $('#sidebar').css('-webkit-transition', 'all 0.3s ease');
    $('#sidebar').css('-moz-transition', 'all 0.3s ease');
    $('#sidebar').css('-ms-transition', 'all 0.3s ease');
    $('#sidebar').css('-o-transition', 'all 0.3s ease');
    $('#sidebar').css('transition', 'all 0.3s ease');
    $('#content-wrapper').css('-webkit-transition', 'all 0.3s ease');
    $('#content-wrapper').css('-moz-transition', 'all 0.3s ease');
    $('#content-wrapper').css('-ms-transition', 'all 0.3s ease');
    $('#content-wrapper').css('-o-transition', 'all 0.3s ease');
    $('#content-wrapper').css('transition', 'all 0.3s ease');

    $('.menu-item-desc').hide();

    menuSize = 'Small'
  }
});
html,
body {
  height: 100vh;
}

#sidebar {
  position: fixed;
  top: 0;
  left: 0;
  width: 50px;
  height: 100%;
  z-index: 2;
  background-color: #102027;
  color: #fff;
}

#sidebar ul {
  list-style: none;
  padding: 0;
  margin: 0;
}

#sidebar a {
  color: #fff;
}

#content-wrapper {
  position: relative;
  top: 0;
  left: 0;
  overflow: hidden;
  height: 100%;
  margin-left: 50px;
  padding-top: 100px;
  padding-bottom: 30px;
}

#header-wrapper {
  position: absolute;
  top: 0;
  left: 0;
  z-index: 2;
  overflow: hidden;
  width: 100%;
  height: 100px;
}

#header {
  width: 100%;
  height: 50px;
  background-color: #fff;
}

#subheader {
  width: 100%;
  height: 50px;
  background-color: #37474f;
  color: #fff;
  clear: right;
}

#content {
  position: relative;
  top: 0;
  left: 0;
  overflow: auto;
  z-index: 1;
  width: 100%;
  height: 100%;
  padding-top: 15px;
  padding-bottom: 15px;
}

#footer {
  position: absolute;
  bottom: 0;
  left: 0;
  z-index: 2;
  overflow: hidden;
  width: 100%;
  height: 30px;
  line-height: 30px;
  border-top: solid 1px #cfcfcf;
  background: #fff;
}

.menu-item-desc {
  display: none;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

<div id="sidebar">
  <a class="js-menu-toggle" href="#">TOGL</a>
  <ul>
    <li>Item 1<span class="menu-item-desc"> - Item 1 Desc</span></li>
    <li>Item 2<span class="menu-item-desc"> - Item 2 Desc</span></li>
    <li>Item 3<span class="menu-item-desc"> - Item 3 Desc</span></li>
  </ul>
</div>
<div id="content-wrapper">
  <div id="header-wrapper">
    <div id="header" class="container-fluid">Header</div>
  </div>
  <div id="content" class="container-fluid">PRIMARY CONTENT</div>
</div>

5
  • 2
    Yes, you can. What's the trouble? Commented Aug 2, 2017 at 14:45
  • Why not try it before coming here to confirm? Commented Aug 2, 2017 at 14:46
  • @ControlAltDel I did try it using jQuery addClass and nothing works... Commented Aug 2, 2017 at 14:46
  • @DanielBeck Alright, will post it now. Commented Aug 2, 2017 at 14:47
  • Have you explored declaring transition rules on the elements that will change, like #sidebar? Commented Aug 2, 2017 at 14:47

5 Answers 5

2

Yes you can! Use addClass, removeClass and toggleClass accordingly.

For example, the #sidebar element can have a class assigned to it:

.toggle-slidein {
  -webkit-transition: all 0.3s ease;
  -moz-transition: all 0.3s ease;
  -ms-transition: all 0.3s ease;
  -o-transition: all 0.3s ease;
}

In your jQuery you can apply it like so:

$('#sidebar').addClass('toggle-slidein');

That takes care of these lines of code:

$('#sidebar').css('-webkit-transition', 'all 0.3s ease');
$('#sidebar').css('-moz-transition', 'all 0.3s ease');
$('#sidebar').css('-ms-transition', 'all 0.3s ease');
$('#sidebar').css('-o-transition', 'all 0.3s ease');
$('#sidebar').css('transition', 'all 0.3s ease');

You can extend this to the rest of your code as you see fit.

Edit: providing toggleClass example for sidebar and content-wrapper:

First add some CSS classes that will represent the changes to the elements you want to dynamically change.

.sidebar--large {
  width: 180px;
}
.content-wrapper--pushleft {
  margin-left: 180px;
}

Then in your jQuery:

$(".js-menu-toggle").click(function(e) {
  e.preventDefault();

  if (menuSize == 'Small') {
    $('#sidebar').toggleClass('sidebar--large');
    $('#content-wrapper').toggleClass('content-wrapper--pushLeft');
    //... other code
    menuSize = 'Large';

  } else {
    $('#sidebar').toggleClass('sidebar--large');
    $('#content-wrapper').toggleClass('content-wrapper--pushLeft');
    //... other code
    menuSize = 'Small';
  }
}

The jQuery code using toggleClass creates a toggle effect by checking for the specified class name; so the class names are added if missing, and removed if already set on the element.

Sign up to request clarification or add additional context in comments.

6 Comments

You wouldn't toggle the transition styles, only the width style
I changed it to addClass to provide a more concrete example
@Age this is exactly what I needed. Is there anyway I can improve the changing of the width and margin-left of the sidebar and content-wrapper?
@BlakeRivell certainly, using toggleClass. I can provide an example by editing my answer
@AGE if you can do that it would be awesome. So far your answer has helped me the most because it is most descriptive.
|
1

As mentioned in some other answers (I noticed after writing my code), you could use jQuery's toggleClass function to achieve this.

$(".js-menu-toggle").click(function(e) {
  e.preventDefault();
  $("#sidebar").toggleClass("expanded");
  $("#content-wrapper").toggleClass("expanded");
});
html,
body 

{
  height: 100vh;
}

#sidebar {
  position: fixed;
  top: 0;
  left: 0;
  width: 50px;
  height: 100%;
  z-index: 2;
  background-color: #102027;
  color: #fff;
  transition: all 0.3s ease;
  overflow: hidden;
   white-space: nowrap;
}
#sidebar.expanded {
   width: 180px;
}
#sidebar .menu-item-desc {
   display: inline-block;
   white-space: nowrap;
  transition: all 0.3s ease;
    opacity: 0;
   visibility: hidden;
}
#sidebar .menu-item-desc:hover{
   display: block;
}
#sidebar.expanded .menu-item-desc {
   opacity: 1;
    visibility: visible;
}
#sidebar ul {
  list-style: none;
  padding: 0;
  margin: 0;
}

#sidebar a {
  color: #fff;
}

#content-wrapper {
  position: relative;
  top: 0;
  left: 0;
  overflow: hidden;
  height: 100%;
  margin-left: 50px;
  padding-top: 100px;
  padding-bottom: 30px;
  transition: all 0.3s ease;
}
#content-wrapper.expanded {
    margin-left: 180px;
}
#header-wrapper {
  position: absolute;
  top: 0;
  left: 0;
  z-index: 2;
  overflow: hidden;
  width: 100%;
  height: 100px;
}

#header {
  width: 100%;
  height: 50px;
  background-color: #fff;
}

#subheader {
  width: 100%;
  height: 50px;
  background-color: #37474f;
  color: #fff;
  clear: right;
}

#content {
  position: relative;
  top: 0;
  left: 0;
  overflow: auto;
  z-index: 1;
  width: 100%;
  height: 100%;
  padding-top: 15px;
  padding-bottom: 15px;
}

#footer {
  position: absolute;
  bottom: 0;
  left: 0;
  z-index: 2;
  overflow: hidden;
  width: 100%;
  height: 30px;
  line-height: 30px;
  border-top: solid 1px #cfcfcf;
  background: #fff;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

<div id="sidebar">
  <a class="js-menu-toggle" href="#">TOGL</a>
  <ul>
    <li>Item 1<span class="menu-item-desc"> - Item 1 Desc</span></li>
    <li>Item 2<span class="menu-item-desc"> - Item 2 Desc</span></li>
    <li>Item 3<span class="menu-item-desc"> - Item 3 Desc</span></li>
  </ul>
</div>
<div id="content-wrapper">
  <div id="header-wrapper">
    <div id="header" class="container-fluid">Header</div>
  </div>
  <div id="content" class="container-fluid">PRIMARY CONTENT</div>
</div>

4 Comments

Hey I love this example, however the opacity 0 technique is messing up my UI since the menu-item-desc is actually taking up space on the page. If the user puts their cursor to the right side of the small version of the menu it will cause a hover on the li because their cursor is technically over top of the menu-item-desc. Is there anyway I can get the best of both worlds? The opacity effect without the menu-item-desc taking up space when opacity=0?
You could use an animation to set it to display: none after the opacity reaches 0.
would I do this by creating another class that does the animation or sets the display none?
thank you. So it was a matter of using Visibility: visible and hidden on the .menu-item-disc classes correct?
0

Woo buddy! That's a lot of CSS you have in your Javascript! Yes, you can simply put all of that into a CSS class and then add/remove said class dynamically in your Javascript. Check out this question that should answer what you're looking for :)

Here!

Comments

0

Yes you can.

If you create classes with your required css styles, you can then toggle them with jquery:

$('#sidebar').toggleClass('class-name', true) adds the class $('#sidebar').toggleClass('class-name', false) removes the class

Simply add classes for each menu size and add/remove them as required inside the event.

5 Comments

do the transitions go on the classes or on the divs?
The transitions should be included with classes. I would suggest creating classes for each element, depending on the menu size. For instance, create a .sidebar-large class which you can then toggle on if the sidebar is large. Add the transitions to this .sidebar-large class.
The transition should be a standard rule of the element in question, in any state that it is in, the classes you add and remove should have the position/size changes declared.
@UncaughtTypeError If I do this and .sidebar-large class has a width of 180px and I create a content-wrapper large class with a margin-left of 180px will this override the original div styles? That is my concern.
@BlakeRivell Sure, it should just be a simple matter of specificity, so make sure that you have the right selectors declared to over-qualify default styles.
0

Nice question I think what you are looking for is .toggleClass method in jquery or you can use .addClass and .removeClass I have supplied links for it here:

2 Comments

what class would I be toggling. A class that changes the width and margin of my elements or a class that has the transitions?
Firstly you need to have the code of your transition/change of margin etc. and then use the .toggleClass function. I am not quit sure if what I told you helps you. Let me know though! Hope I helped you.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.