jQuery / Method / .fadeOut() - Gradually Hide Selected Elements

jQuery's .fadeOut() lowers opacity and then sets display to none to hide an element. Disappearing from the screen and layout does not delete the DOM element, so it can be shown again. To remove it, call .remove() in the completion callback after the effect finishes.

Hiding, deletion and duration

The .fadeOut() documentation explains that display: none removes the element's layout space at completion. During the effect, opacity decreases; its height is not gradually collapsing. Deletion from the Document Object Model (DOM) is a separate operation.

Operation Element afterward Example result Meaning of Restore
.fadeOut() only Still in DOM, hidden hidden / nodes=1 Show existing element, retaining edited input
.remove() after completion Deleted from DOM removed / nodes=0 Recreate from initial HTML with initial value

The form .fadeOut(duration, easing, complete) accepts optional arguments. Default duration is 400 ms, "fast" is 200 and "slow" is 600. .fadeOut(800) fades over 800 ms rather than waiting that long before starting. Default easing is swing; specify "linear" after duration for constant progress.

Complete example comparing editable input

Save all the code as UTF-8 in fadeout-demo.html and open it in a browser. No installation is needed, but loading the official full jQuery distribution from its Content Delivery Network (CDN) requires internet. Use the full file because slim excludes the effects module.

The code uses 4.0.0. Hiding, removal, input values, restoration and interrupted reset were executed with 3.7.1 and 4.0.0. Controls stay outside the notice so Restore and Reset remain available after it disappears.

<!doctype html>
<html lang="en">
<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <title>Fade out versus remove</title>
  <style>
    body { font: 16px/1.6 sans-serif; margin: 24px; }
    #notice { padding: 20px; background: #e5f2f0; margin: 16px 0; }
    button, select, input { padding: 8px; margin: 4px; }
  </style>
  <script src="https://code.jquery.com/jquery-4.0.0.min.js"></script>
</head>
<body>
  <h1>Fade out versus remove</h1>
  <label for="duration">Duration:</label>
  <select id="duration"><option value="800">800 ms</option><option value="0">0 ms</option></select>
  <button type="button" id="fade">Fade only</button>
  <button type="button" id="remove">Fade then remove</button>
  <button type="button" id="restore">Restore</button>
  <button type="button" id="reset">Reset</button>
  <div id="host">
    <div id="notice">
      <p>A temporary notice</p>
      <label>Note: <input id="note" value="Keep me"></label>
    </div>
  </div>
  <p id="result" aria-live="polite"></p>
  <script>
    $(function () {
      const initialHtml = $("#host").html();
      function enable() {
        $("#fade, #remove").prop("disabled", false);
      }
      function report(state) {
        $("#result").text(`state=${state} | nodes=${$("#notice").length}`);
      }
      function fade(removeAfter) {
        const $notice = $("#notice");
        if (!$notice.length) {
          report("missing");
          return;
        }
        const reduce = window.matchMedia("(prefers-reduced-motion: reduce)").matches;
        const duration = reduce ? 0 : Number($("#duration").val());
        $notice.stop(true, false);
        $("#fade, #remove").prop("disabled", true);
        report("fading");
        $notice.fadeOut(duration, function () {
          if (removeAfter) $(this).remove();
          enable();
          report(removeAfter ? "removed" : "hidden");
        });
      }
      $("#fade").on("click", () => fade(false));
      $("#remove").on("click", () => fade(true));
      $("#restore").on("click", function () {
        if (!$("#notice").length) $("#host").html(initialHtml);
        $("#notice").stop(true, false).css("opacity", "").show();
        enable();
        report("visible");
      });
      $("#reset").on("click", function () {
        $("#notice").stop(true, false);
        $("#host").html(initialHtml);
        enable();
        report("visible");
      });
      report("visible");
    });
  </script>
</body>
</html>

The notice initially contains Keep me, with this result:

state=visible | nodes=1
  1. Change Note to edited and press Fade only. After an 800 ms fade, the result is state=hidden | nodes=1.
  2. Restore reveals the same notice with edited retained. Hiding preserved the original element.
  3. Fade then remove deletes it after the effect: state=removed | nodes=0. Deferring .remove() lets the fade remain visible.
  4. After deletion, Restore creates a new notice from initial HTML. The input becomes Keep me; edited is not recovered automatically.
  5. During the effect, Restore stops the animation and shows the existing notice. Reset stops it and creates initial HTML again, also resetting edited input.
  6. Choose 0 ms for the same completion logic without gradual motion. A detected reduced-motion preference also uses zero.

To recover user edits after deleting a real editable interface, store those data separately and apply them to the recreated element. This exercise's Restore reveals an existing element or recreates fixed initial content; it does not recover deleted input.

Delete after completion and handle missing targets

.remove() deletes the element, its contents and associated jQuery data and events. Treat it differently from hiding. In the completion callback, this example removes this only when removeAfter is true. In the ordinary function, this is the DOM element whose effect finished.

.fadeOut() does not block subsequent JavaScript. Calling .remove() immediately after it removes the element before the animation finishes. When multiple elements match, completion runs per element; this example intentionally targets one unique ID.

A missing selection has no per-element completion callback. Before starting, the example checks .length and reports state=missing | nodes=0 if deletion already occurred. Controls therefore do not stay disabled waiting for a nonexistent target.

Interrupted restoration and repeated runs

.stop(true, false) clears queued effects and stops the current one without completing it or calling its completion callback. An old callback therefore cannot delete the notice after Restore or Reset. Restore clears intermediate opacity and calls .show(); Reset stops before replacing the initial HTML.

Fade buttons are disabled during animation to prevent accumulating requests, while Restore and Reset stay usable. Distinguish successful completion from cancellation to keep counters and the visual state aligned.

If no effect appears or an error occurs, check full jQuery loading, .fadeOut is not a function in Console, and selection scope. An immediate disappearance may come from 0 ms or reduced motion. An already hidden element has no visible fade to repeat, so Restore before comparing.