How to Animate Width to Auto Using jQuery

Animating an element’s width from 0 to 'auto' cannot be achieved natively with jQuery’s .animate() method because it requires numeric values to calculate frame-by-frame interpolation. The safest and most robust solution is to temporarily calculate the element's rendered pixel width at 'auto', instantly restore it to 0, animate to the measured pixel value, and finally set the CSS width back to 'auto' upon completion to preserve responsive behavior.

The Core Problem

Passing { width: 'auto' } directly into jQuery's .animate() fails silently or causes an abrupt jump:

// This does NOT work
$('#target').animate({ width: 'auto' }, 400);

Because 'auto' is a keyword rather than a fixed scalar value, jQuery cannot compute intermediate states.

The Solution: Measure, Animate, and Reset

Browsers do not repaint the screen between synchronous JavaScript execution lines. This allows you to set the element to width: 'auto', measure its computed width, revert it back to 0, and start the animation without any visual glitching.

Here is the standard implementation:

function animateWidthToAuto(selector, duration) {
    var $el = $(selector);

    // 1. Temporarily apply 'auto' and read the computed width
    var targetWidth = $el.css('width', 'auto').width();

    // 2. Revert instantly back to 0
    $el.css('width', 0);

    // 3. Animate to the measured numerical value
    $el.stop().animate({ width: targetWidth }, duration, function () {
        // 4. Reset to 'auto' so content remains responsive
        $(this).css('width', 'auto');
    });
}

Handling Invisible or Hidden Elements

If the element starts with display: none, .width() returns 0. To accurately measure its width, temporarily force layout visibility without causing a visual flash:

function animateHiddenWidthToAuto(selector, duration) {
    var $el = $(selector);

    // Measure while element is invisibly rendered
    $el.css({
        position: 'absolute',
        visibility: 'hidden',
        display: 'block',
        width: 'auto'
    });

    var targetWidth = $el.width();

    // Restore original positioning and initialize starting width
    $el.css({
        position: '',
        visibility: '',
        display: 'block',
        width: 0
    });

    // Run the animation
    $el.stop().animate({ width: targetWidth }, duration, function () {
        $(this).css('width', 'auto');
    });
}

Essential Considerations

  • overflow: hidden: Always apply overflow: hidden via CSS to the animating container to prevent its internal text or children from wrapping unexpectedly or spilling outside during the transition.
  • box-sizing: Ensure the element uses box-sizing: border-box to avoid width recalculation errors if padding or borders are present.
  • Responsive Cleanup: Step 4 (setting width: 'auto' in the complete callback) is critical. Leaving a fixed pixel width will prevent the element from adapting to future layout changes, font size updates, or window resizes.