2

I am trying to use .slideToggle() to toggle a div with display: none to display: grid. However this animation seems to add display: block inline to the html and overwrite any other css class

CSS

.grid {
    display: grid;
}

jQuery

$('#nav-toggle').click(function() {
    $('.nav-menu').slideToggle(500, function() {
        $(this).toggleClass('grid')
    });
});

I had somewhat brief success using

$('#nav-toggle').click(function() {
    $('.nav-menu').slideToggle(500, function() {
         if ($(this).is(':visible')) {
             $(this).css('display','grid');
         }
    });
});
.nav-menu {
    display: none;
    grid-template-columns: repeat(3, 1fr);
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id=nav-toggle>
    Toggle
</div>

<div class=nav-menu>
    <div>Item 1</div>
    <div>Item 2</div>
    <div>Item 3</div>
</div>

but the initial animation seems to play using display: block and once the animation is finished I guess jQuery then sees the element as visible and the HTML snaps from display: block (items stacked) to display: grid (items spaced).

All following animations seem to play nicely with display: grid.

How can I get the initial animation to display correctly too?

2 Answers 2

1

The solution is to set nav-menu to display:grid; and to hide and show it with JQuery. By the way if you have a user who disabled JavaScript, he will still be able to read your page.

Try the following code:

$('.nav-menu').hide(); // clearer than display none
$('#nav-toggle').click(function() {
  $('.nav-menu').slideToggle(500, function() {
    if ($(this).is(':visible')) {
      $(this).show(); // clearer than display previous (here grid)
    }
  });
});
.nav-menu {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="nav-toggle">
  Toggle
</div>

<div class="nav-menu">
  <div>Item 1</div>
  <div>Item 2</div>
  <div>Item 3</div>
</div>

Related to: https://stackoverflow.com/a/8144998/1248177

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

3 Comments

Thanks. Hmm this really makes responsive webpages a pain to implement, I guess I will look into other ways to display my menu.
@myol you may want to use a framework like bootstrap to help you. Beside, did this fix you problem? If so, upvote and accept it. :)
It didn't fix my problem per-se but I've upvoted anyway since you took the time to answer.
0

So in order to make responsive CSS media queries much cleaner and easier, I ended up wrapping the nav element in a div and simply having the div toggle between display: none and display: block.

I am still able to align the menu items within since the child of the block is the nav which kept the grid property. Also in my case this block was a child of a more complex display: grid layout, but since it is still a child, I could still use the CSS grid properties on it, I just had to use older CSS methods to expand and center the block.

Its not perfectly clean but I guess its the best I can do until jQuery is updated to support more than just display: block for its animations.

$('#nav-toggle').click(function() {
    $('.nav-menu-container').slideToggle(500, function() {
        if ($(this).css('display') == 'none') {
            $(this).css('display', '');
        }
    });
});
.nav-menu-container {
    display: none;
}

.nav-menu {
    display: grid;
    grid-template-columns: repeat(3, 1fr);
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id=nav-toggle>
    Toggle
</div>
<div class=nav-menu-container>
    <div class=nav-menu>
        <div>Item 1</div>
        <div>Item 2</div>
        <div>Item 3</div>
    </div>
</div>

Comments

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.