Himanshu SharmaSoftware engineer
Let’s talk

jQuery · Lesson 29 of 45

Show, hide and toggle

Show and hide elements with jQuery .show(), .hide() and .toggle(), with or without animation, run code when they finish, and keep hidden content accessible.

10 minEffects and animationUpdated 23 October 2026

By the end of this lessonShow, hide and toggle elements instantly or with animation, run code afterwards, and choose between hiding with jQuery and with a class.

Instant show and hide

The simplest effects are instant:

html
<p id="note">This note can be hidden.</p>
<button id="hide">Hide</button> <button id="show">Show</button>

<script src="https://code.jquery.com/jquery-4.0.0.min.js"></script>
<script>
  $("#hide").on("click", function () {
    $("#note").hide();
    console.log("hidden, display =", $("#note").css("display"));
  });
  $("#show").on("click", function () {
    $("#note").show();
    console.log("shown, display =", $("#note").css("display"));
  });
</script>
result
hidden, display = none
shown, display = block

.hide() sets display: none, so the element takes up no space and is not read by screen readers. It remembers the previous display value, so .show() puts back block, flex, inline or whatever the element used before.

Toggle

.toggle() flips the state: visible elements hide and hidden ones show.

html
<button id="more" aria-expanded="false" aria-controls="details">Show details</button>
<div id="details" hidden>Ships in 2 days. Free returns within 30 days.</div>

<script src="https://code.jquery.com/jquery-4.0.0.min.js"></script>
<script>
  $("#details").removeAttr("hidden").hide();   // let jQuery manage it from here

  $("#more").on("click", function () {
    $("#details").toggle();
    const open = $("#details").is(":visible");
    $(this).text(open ? "Hide details" : "Show details").attr("aria-expanded", open);
    console.log("open:", open);
  });
</script>
result
open: true
open: false
open: true

The button's text and its aria-expanded attribute are updated every time, so everyone knows the current state. Notice the first line: the details start with the HTML hidden attribute, so they are hidden even before JavaScript runs, then jQuery takes over.

Pass a boolean to force the state, which is safer when the code may run more than once:

javascript
$("#admin-tools").toggle(user.isAdmin);
$("#empty-message").toggle(items.length === 0);

Animated show and hide

Give .show(), .hide() or .toggle() a duration, and the element animates its width, height and opacity together:

html
<button id="box-btn">Toggle with animation</button>
<div id="box" style="width: 160px; height: 80px; background: #a5b4fc; margin-top: 8px"></div>

<script src="https://code.jquery.com/jquery-4.0.0.min.js"></script>
<script>
  $("#box-btn").on("click", function () {
    $("#box").toggle(400, function () {
      console.log("finished, visible:", $(this).is(":visible"));
    });
  });
</script>
result
finished, visible: false

The duration can be:

  • a number of milliseconds, such as 300;
  • "fast" (200ms) or "slow" (600ms);
  • left out of animated calls such as .fadeIn(), which use the default 400ms.

Callbacks

The function passed after the duration is a callback: it runs when the animation finishes, once per element. Code after the call runs straight away, before the animation is done:

html
<button id="go">Hide</button>
<p id="msg">Goodbye</p>

<script src="https://code.jquery.com/jquery-4.0.0.min.js"></script>
<script>
  $("#go").on("click", function () {
    $("#msg").hide("fast", function () {
      console.log("2. callback: animation finished");
    });
    console.log("1. this line runs first");
  });
</script>
result
1. this line runs first
2. callback: animation finished

This ordering is the most important thing to understand about jQuery animations. If you want something to happen after an effect, put it in the callback (or use the promise technique in the queue lesson).

Hiding with jQuery or with a class?

There are three common ways to hide something:

Method Good for
.hide() / .show() quick scripts, and animated showing and hiding
.toggleClass("is-hidden") with CSS when CSS should decide how hiding looks (for example a CSS transition), or different screen sizes behave differently
the hidden attribute, .prop("hidden", bool) plain markup that is hidden before any script runs

.show() sets an inline display style, which beats your stylesheet. If you later try to hide the element with a CSS class, the inline style wins. Mixing approaches on the same element causes confusing bugs, so pick one per element.

Respecting reduced motion

Some people get dizzy or distracted from movement on screen and ask their system to reduce motion. You can turn off all jQuery animations for them with one line; effects then jump straight to their end state, and callbacks still run:

javascript
if (window.matchMedia("(prefers-reduced-motion: reduce)").matches) {
  $.fx.off = true;
}

Common mistakes

  • Putting follow-up code after an animated call instead of in its callback.
  • Forgetting to update aria-expanded on the button that shows or hides content.
  • Mixing .show() with CSS classes that also set display.
  • Animating many large elements at once, which can make a page stutter; animate the container instead.

Exercise

Make a "Read more" button that toggles a hidden paragraph with the "fast" speed. When the animation finishes, change the button text to "Read less" or "Read more" depending on whether the paragraph is visible.

Show one possible answer
html
<button id="rm">Read more</button>
<p id="more" style="display: none">The rest of the story...</p>

<script src="https://code.jquery.com/jquery-4.0.0.min.js"></script>
<script>
  $("#rm").on("click", function () {
    const $btn = $(this);
    $("#more").toggle("fast", function () {
      $btn.text($(this).is(":visible") ? "Read less" : "Read more");
      console.log($btn.text());
    });
  });
</script>
result
Read less

Key points

  • .hide() sets display: none and remembers the old display value; .show() restores it.
  • .toggle() shows hidden elements and hides visible ones; .toggle(condition) forces a state.
  • Pass a duration ("fast", "slow" or milliseconds) to animate, and a callback to run code when it finishes.
  • Hidden elements are removed from the accessibility tree too; keep aria-expanded in step on the button that controls them.

Check yourself

1. What does .hide() do with no arguments?
2. How long is the "slow" duration?
3. What does .toggle(isLoggedIn) do?
4. When does the callback in .hide(400, fn) run?